assembly GAS(AT&T)ASM -一个地址的值在改变另一个地址的值后改变,为什么?

vcirk6k6  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(98)

这个函数取一个数组的(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)的确切更改位置。

mtb9vblg

mtb9vblg1#

谢谢@Jester。在“main”文件中有一个bug,它使缓冲区重叠了一个字节。缓冲区位于内存中的每一个缓冲区之后,另一个函数通过将第一个缓冲区的长度加1来改变描述第一个缓冲区长度的值。这导致了一个字节的to缓冲区的重叠。

相关问题