这个函数取一个数组的(x,y)坐标,每个数字都是一个字节的无符号整数,但大小只能在0-32767之间。该函数将这些数字转换为整数,并将其存储在另一个缓冲区中。格式为“x \t y \n”。该函数从坐标数组的末尾开始,并向后工作到开始。该函数一直工作到最后一个数字。
测试输入(以10为基数)2084、3146、30093、9127
当加载4,8字节的无符号int时,其中第一个数字存储在%rdi,(%rdi)的值是2084(从基数16转换而来),这可以通过使用GDB在行中确认:movq (%rdi), %r12 # test to see what is stored at (%rdi)
但是在movb $10, (%rcx) # insert newline
之后,(%rdi)处的值发生了变化,我不明白为什么。
功能:
.section .text
.globl ints_to_ascii # void ints_to_ascii()
# %rdi = Array start address
# %rsi = Data length
# %rdx = print buffer address
# %rcx = print buffer length
ints_to_ascii:
push %rbp
movq %rsp, %rbp
addq %rdi, %rsi # make rsi point at end of coordinate array, used to get 8 byte numbers
addq %rdx, %rcx # make rcx point at end of buffer
movq $10, %r10 # Divisor (10 for decimal)
.LparseData_coordinateLoop:
cmpq %rdi, %rsi
jle .LparseData_coordinateLoop_end
dec %rcx # Move the pointer one position to the left
movq (%rdi), %r12 # test to see what is stored at (%rdi)
movb $10, (%rcx) # insert newline
movq (%rdi), %r12 # test to see what is stored at (%rdi)
subq $8, %rsi # point to the next place for a number
movq (%rsi), %rax
convert_y_loop:
xorq %rdx, %rdx # Clear the remainder
divq %r10 # Divide RAX by 10, result in RAX, remainder in RDX
dec %rcx # Move the pointer one position to the left
mov %dl, (%rcx) # Store the ASCII digit in the buffer
addq $48, (%rcx) #add 48 to convert to ascii
cmpq $0, %rax # Check if quotient is zero
jne convert_y_loop # If not zero, continue the loop
convert_y_loop_end:
dec %rcx # Move the pointer one position to the left
movb $9, (%rcx) # insert tab
subq $8, %rsi # point to the next place for a number
movq (%rsi), %rax
convert_x_loop:
xorq %rdx, %rdx # Clear the remainder
divq %r10 # Divide RAX by 10, result in RAX, remainder in RDX
dec %rcx # Move the pointer one position to the left
mov %dl, (%rcx) # Store the ASCII character
addq $48, (%rcx) #add 48 to convert to ascii
cmpq $0, %rax # Check if quotient is zero
jne convert_x_loop # If not zero, continue the loop
convert_x_loop_end:
jmp .LparseData_coordinateLoop
.LparseData_coordinateLoop_end:
movq %rbp, %rsp
pop %rbp
ret
我尝试使用GDB,并多次插入movq (%rdi), %r12 # test to see what is stored at (%rdi)
,以查看(%rdi)
的确切更改位置。
1条答案
按热度按时间mtb9vblg1#
谢谢@Jester。在“main”文件中有一个bug,它使缓冲区重叠了一个字节。缓冲区位于内存中的每一个缓冲区之后,另一个函数通过将第一个缓冲区的长度加1来改变描述第一个缓冲区长度的值。这导致了一个字节的to缓冲区的重叠。