Memory 内存传输英特尔汇编AT&;T

Memory 内存传输英特尔汇编AT&;T,memory,assembly,x86,intel,Memory,Assembly,X86,Intel,我在将字符串从一个内存地址按字节移动到另一个内存地址时遇到问题。在这方面已经做了几个小时,并尝试了一些不同的策略。我是Intel assemby的新手,所以我需要一些提示和见解来帮助我解决这个问题 getText例程应该将n(在%rsi中找到)字节从ibuf传输到%rdi中的地址。计数器i是用于指示从何处开始传输的偏移量,在例程结束后,它应指向未传输的下一个字节。如果没有n个字节,则应取消传输并返回在%rax中传输的实际字节数 getText: movq $ibuf, %r

我在将字符串从一个内存地址按字节移动到另一个内存地址时遇到问题。在这方面已经做了几个小时,并尝试了一些不同的策略。我是Intel assemby的新手,所以我需要一些提示和见解来帮助我解决这个问题

getText例程应该将n(在%rsi中找到)字节从ibuf传输到%rdi中的地址。计数器i是用于指示从何处开始传输的偏移量,在例程结束后,它应指向未传输的下一个字节。如果没有n个字节,则应取消传输并返回在%rax中传输的实际字节数

getText:
        movq    $ibuf, %r10
        #in rsi is the number of bytes to be transfered
        #rdi contains the memory adress for the memory space to transfer to
        movq    $0, %r8     #start with offset 0
        movq    $0, %rax    #zero return register
        movq    (counterI), %r11
        cmpb    $0, (%r10, %r11, 1) #check if ibuf+counterI=NULL
        jne MOVE            #if so call and read to ibuf
        call    inImage
    MOVE:       
        cmpq    $0,%rsi         #if number of bytes to read is 0
        je  EXIT            #exit
        movq    counterI, %r9       
        movq    $0, %r9         #used for debugging only shold not be 0
        movb  (%r10, %r9, 1), %bl   #loads one byte to rdi from ibuf
        movb  %bl, (%rdi, %r8, 1)
        incq    counterI        #increase pointer offset
        decq    %rsi            #dec number of bytes to read
        incq    %r8         #inc offset in write buffert
        movq    %r8, %rax       #returns number of bytes wrote to buf 
        movq    (counterI), %r9 
        cmpb    $0, (%r10, %r9,1)   #check if ibuf+offset is NULL
        je  EXIT            #if so exit
        cmpq    $0, %rsi        #can be cleaned up later
        jne MOVE
    EXIT:
        movb    $0, (%rdi, %r8, 1)  #move NULL to buf+%r8?          
        ret
第二个指令使第一个指令无效,但鉴于这句话,我理解您将删除它。更好的是,如果要将每次出现的%R9都更改为%R11,则可以同时删除这两个选项

movzbq  (%r10, %r9, 1), %r10    #loads one byte+zeroes to rdi from ibuf
movq    %r10, (%rdi, %r8, 1)    #HERE IS THE PROBLEM I THINK
这是一个危险的构造。您首先使用%R10作为地址,然后在其中删除一个零扩展数据字节。稍后在代码中,您将再次使用%R10作为地址,但遗憾的是,该地址不在其中!解决方案是移动到另一个寄存器,而不必担心零扩展

movb  (%r10, %r9, 1), %bl   #loads one byte to rdi from ibuf
movb  %bl, (%rdi, %r8, 1)
以下代码可以缩短

 cmpb    $0, (%r10, %r9,1)   #check if ibuf+offset is NULL
 je  EXIT            #if so exit
 cmpq    $0, %rsi        #can be cleaned up later
 jne MOVE
EXIT:
作为


这个函数的语义应该是什么?
counterI
扮演什么角色?图像中的
是什么?为什么要对读取的字节进行零扩展,然后写入整个qword?(这将在末尾写入7个额外的零,通常不需要这样做)此外,如果要复制字符串,不必在终止符之前停止,然后添加一个额外的终止符,只需复制它,然后检测它是否是终止符。您还可以在没有按下某个内容/更改rsp的情况下弹出某个内容,因此它会弹出返回地址,然后返回到遗忘状态。getText最多应将n个字节传输到寄存器%rdi中的地址。计数器i是以ibuf为单位的当前偏移量。inImage是一个函数,它将stdin写入字符串,在本例中为ibuf。问题是,我尝试使用movb,但当我尝试将其放入%r#寄存器时,它会抱怨。我更改了推送%r12,但没有注意到弹出:D我更关注从一个内存地址移动到另一个内存地址的问题。
 cmpb    $0, (%r10, %r9,1)   #check if ibuf+offset is NULL
 je  EXIT            #if so exit
 cmpq    $0, %rsi        #can be cleaned up later
 jne MOVE
EXIT:
 cmpb    $0, (%r10, %r9, 1)   #check if ibuf+offset is NULL
 jne MOVE
EXIT: