内存传输英特尔组装 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:
我在将字符串按字节从一个内存地址移动到另一个内存地址时遇到问题。已经这样做了几个小时,并尝试了一些不同的策略。我是 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: