首页 > 解决方案 > 函数调用是否与 %rax 以外的其他寄存器混淆?

问题描述

这是我的编译器生成的 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 的代码,然后打印它工作正常。

这个函数调用是否会以某种方式与其他寄存器混淆?

标签: cgccassemblyx86

解决方案


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


推荐阅读