【发布时间】:2020-11-19 17:10:11
【问题描述】:
我们知道,按照 x86-64 约定,寄存器%rbx、%rbp 和%r12–%r15 被归类为被调用者保存的寄存器。而%r10 和%r111 是调用者保存的寄存器。
但是当我在大多数情况下编译 C 代码时,例如函数P 调用Q,我看到函数Q 的以下汇编代码:
Q:
push %rbx
movq %rdx, %rbx
...
popq %rbx
ret
我们知道,由于%rbx是一个被调用者保存的寄存器,我们必须将它存储在堆栈中,并在稍后为调用者P恢复它。
但是通过使用调用方保存的寄存器%r10 来保存堆栈操作会不会更简洁:
Q:
movq %rdx, %r10
...
ret
所以被调用者不需要为调用者保存和恢复寄存器,因为调用者在调用被调用者之前已经将它压入堆栈?
【问题讨论】:
-
不是架构决定了谁和哪些寄存器被保存。这是调用约定。
-
请提供一个完整的例子,包括高级语言和编译输出,因为生成的代码与整个函数有关。
标签: c assembly x86-64 compiler-optimization calling-convention