内存传输英特尔组装 AT&T

Memory transfer intel assembly AT&T

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

getText 例程应该将 n(在 %rsi 中找到)字节从 ibuf 传输到 %rdi 中的地址。 counterI 是用于指示传输开始位置的偏移量,例程结束后它应该指向下一个未传输的字节。如果没有 n 个字节,它应该取消传输并且 return %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    [=10=], %r8     #start with offset 0
        movq    [=10=], %rax    #zero return register
        movq    (counterI), %r11
        cmpb    [=10=], (%r10, %r11, 1) #check if ibuf+counterI=NULL
        jne MOVE            #if so call and read to ibuf
        call    inImage
    MOVE:       
        cmpq    [=10=],%rsi         #if number of bytes to read is 0
        je  EXIT            #exit
        movq    counterI, %r9       
        movq    [=10=], %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    [=10=], (%r10, %r9,1)   #check if ibuf+offset is NULL
        je  EXIT            #if so exit
        cmpq    [=10=], %rsi        #can be cleaned up later
        jne MOVE
    EXIT:
        movb    [=10=], (%rdi, %r8, 1)  #move NULL to buf+%r8?          
        ret
movq    counterI, %r9       
movq    [=10=], %r9         #used for debugging only shold not be 0

第二条指令使第一条指令无用,但鉴于我的理解,您会将其删除。更好的是,如果您将每次出现的 %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    [=13=], (%r10, %r9,1)   #check if ibuf+offset is NULL
 je  EXIT            #if so exit
 cmpq    [=13=], %rsi        #can be cleaned up later
 jne MOVE
EXIT:

作为

 cmpb    [=14=], (%r10, %r9, 1)   #check if ibuf+offset is NULL
 jne MOVE
EXIT: