该函数采用 (x,y) 坐标数组,每个数字都是一个字节 unsigned int,但大小只能在 0-32767 之间。该函数将这些数字转换为 ascii 并将其存储在另一个缓冲区中。格式为“xy ”。该函数从坐标数组的末尾开始,向后工作到开头。**该函数一直工作到最后一个数字。**
测试输入(以 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)
的确切更改位置。
谢谢@Jester。 “主”文件中存在一个错误,导致缓冲区重叠一个字节。缓冲区位于内存中的每个缓冲区之后,另一个函数通过向其添加 1 来更改描述第一个缓冲区长度的值。这导致缓冲区重叠一个字节。