我正在 pg251 上的 CSAPP(第三版)学习被调用者和调用者保存的寄存器,我知道对于被调用者保存的寄存器:
此外,我从过程 Q(被调用者)可以通过根本不更改寄存器值或通过将原始值压入堆栈,更改它,然后在返回之前从堆栈中弹出旧值来保留寄存器值.
this帖子中了解到:
但是,当我尝试理解 pg252 上的 CSAPP(第三版)中的示例时,我仍然感到困惑。该示例部分说明如下:被调用者保存的寄存器(又名非易失性寄存器,或调用保留的)用于保存应在调用之间保留的长期值。
long P(long x, long y) {
long u = Q(y); // The detail of Q is irrelevant here
long v = Q(x);
return u + v;
}
通过gcc-11
生成对应的程序集如下:
_P:
LFB2:
pushq %rbp
LCFI2:
pushq %rbx
LCFI3:
subq $8, %rsp
LCFI4:
movq %rdi, %rbp
movq %rsi, %rdi
call _Q
movq %rax, %rbx
movq %rbp, %rdi
call _Q
addq %rbx, %rax
addq $8, %rsp
LCFI5:
popq %rbx
LCFI6:
popq %rbp
LCFI7:
ret
很明显,%rbp 和 %rbx 被调用者保存的寄存器,我们可以看到 过程 P(调用者) 将 %rbp 和 %rbx 压入堆栈。
P
不仅是调用者,而且还是被调用者。
_P:
LFB2:
pushq %rbp
LCFI2:
pushq %rbx
在这里我们可以看到 P
保存
rbp
和
rbx
保存its callers 值。
call _Q
addq %rbx, %rax
我们可以看到 P
调用
Q
,然后将
rbx
添加到其结果(存储在
rax
中)。这意味着
rbx
未被
Q
修改,这意味着
Q
必须保留其值,即保存其被调用者。