函数调用是否与%rax以外的其他寄存器混淆?

时间:2018-09-22 20:06:24

标签: c gcc assembly x86

这是我的编译器生成的gcc汇编代码。注释描述了应该发生的事情(我认为),我输入的是零。程序的输出为4(或4 +我在提示中输入的值)。

.globl main
main:
    pushq %rbp 
    movq %rsp, %rbp 
    subq $0, %rsp 
    movq $1, %rbx           ; rbx = 1
    movq $46, %rdx          ; rbx = 1  rdx = 46 
    movq %rbx, %rcx         ; rbx = 1  rdx = 46  rcx = 1
    addq $7, %rcx           ; rbx = 1  rdx = 46  rcx = 8
    movq $4, %rbx           ; rbx = 4  rdx = 46  rcx = 8
    addq %rcx, %rbx         ; rbx = 12 rdx = 46  rcx = 8
    addq %rdx, %rcx         ; rbx = 12 rdx = 46  rcx = 54      
    callq read_int          ; rbx = 12 rdx = 46  rcx = 54      
    movq %rax, %rdx         ; rbx = 12 rdx = R  rcx = 54      
    negq %rbx               ; rbx = -12 rdx = R   rcx = 54      
    addq %rbx, %rcx         ; rbx = -12 rdx = R   rcx = 42      
    movq %rdx, %rbx         ; rbx = R  rdx = R   rcx = 42      
    addq %rcx, %rbx         ; rbx = R  rdx = R   rcx = 42 + R      
    movq %rbx, %rax         ; rax = 42 + R      
    movq %rax, %rdi
    callq print_int
    addq $0, %rsp
    movq $0, %rax
    popq %rbp
    retq

真的不明白为什么会这样。如果我尝试在没有读取指令的情况下进行编译,则可以正常工作。代码唯一的区别是

movq $0, %rdx

代替

callq read_int
movq %rax, %rdx

但是以前没有使用%rax寄存器。而且没有寄存器保存4。read_int的代码是

int64_t read_int() {
  int64_t i;
  scanf("%" SCNd64, &i);
  return i;

它本身可以正常工作,例如仅调用read int并将rax移入rdi,然后将其打印正常的代码。

此函数调用是否与其他寄存器混淆?

1 个答案:

答案 0 :(得分:1)

对于任何想知道的人:rdx rcx是调用者保存寄存器。在调用函数之前,它们需要保存(例如,在堆栈上)