在unix上打印x86_64后,寄存器值不同,

在unix上打印x86_64后,寄存器值不同,,unix,assembly,x86,x86-64,Unix,Assembly,X86,X86 64,Unix上的x86_64 当我打印%rdi 3次时,第一次打印的值是正确的,然后第二次和第三次打印的值彼此相等,但与第一次打印的值不同(设定值) 为什么价值在变化?如何正确设置/获取/打印%rdi寄存器中的值而不进行此更改?另外,关于如何将%rdi传递给函数并在返回时维护该值的示例也非常有用 我广泛地寻找解决方案,但找不到任何解决方案。我正在构建一个编译器,我的教授给了我们几乎零关于x86_64的文档,他不告诉我在哪里可以找到合适的文档,我正在努力理解这里发生了什么 使用gcc-o test.s

Unix上的x86_64

当我打印%rdi 3次时,第一次打印的值是正确的,然后第二次和第三次打印的值彼此相等,但与第一次打印的值不同(设定值)

为什么价值在变化?如何正确设置/获取/打印%rdi寄存器中的值而不进行此更改?另外,关于如何将%rdi传递给函数并在返回时维护该值的示例也非常有用

我广泛地寻找解决方案,但找不到任何解决方案。我正在构建一个编译器,我的教授给了我们几乎零关于x86_64的文档,他不告诉我在哪里可以找到合适的文档,我正在努力理解这里发生了什么

使用gcc-o test.s编译

    .section    .rodata
    .int_wformat: .string "%d\n"
    .int_rformat: .string "%d"
    .str_wformat: .string "%s"
    .nl_const: .string "\n"
    .initial_prompt_const: .string "\n\n\tAssembly X86 Test Program:\n----------------------------------------------------\n"
    .ext_const: .string "\n----------------------------------------------------\n\t\tProgram Complete\n\n"
    .sec_div_const: .string "\n------------------\n"
    /* Set and Scan */
    .calla_readb_const0: .string "\ta = 10\n\tEnter b = "
    /* Arithmetic prints */
    .aplusb_const0: .string "\ta + b = "
    .aminusb_const0: .string "\ta - b = "
    .atimesb_const0: .string "\ta * b = "
    .agtb_const0: .string "\tWrite(a>b) : "
    .agtb_const1: .string "\ta = 10\n\tb = "
    .comm _gp, 16, 4
    .text
    .globl main
    .type main,@function

main:   nop
    /* Push high address (saved registers) */
    pushq %rbp
    /* Set the top of the stack ( low address ) to the top of the stack (high address) */
    movq %rsp, %rbp
    movl  $.initial_prompt_const, %ebx

    movl $4, (%rdi)

    movl (%rdi), %esi
    movl $0, %eax
    movl $.int_wformat, %edi
    call printf

    movl (%rdi), %esi
    movl $0, %eax
    movl $.int_wformat, %edi
    call printf


    movl (%rdi), %esi
    movl $0, %eax
    movl $.int_wformat, %edi
    call printf
    /* Sets %rsp to %rbp, pops top of stack into %rbp */
    leave
    ret

printf
允许更改
rdi
和一组其他寄存器。了解.code>movl$.int格式,%edi将更改
rdi
,因为
edi
rdi
的较低32b部分,所以不是
printf
首先更改它。你需要调试器。再加上要详细研究ABI/调用约定,不幸的是x86_64比旧的16/32b复杂一级,人类不太容易使用。要存储您的
rdi
,请使用必须保留的寄存器(先保留),或者将值存储在某个位置。我甚至不确定在x86_64中使用堆栈的正确方法是什么,简单的push/pop-around-printf可能会破坏对齐,因此,子rsp,。