如何解决“ sub $ 16,%rsp”指令的作用是什么?
让我们采用以下基本C函数以及它产生的有意未优化的程序集:
int main() {
int i = 4;
return 3;
}
它产生以下(未优化的)程序集,这对我来说都是有意义的:
main:
pushq %rbp
movq %rsp,%rbp
movl $4,-4(%rbp)
movl $3,%eax
popq %rbp
ret
但是,一旦添加函数调用,就会有两条我不太了解的指令:
void call() {};
int main() {
int i = 4;
call();
return 3;
}
main:
pushq %rbp
movq %rsp,%rbp
subq $16,%rsp <-- why is it subtracting 16?
movl $4,-4(%rbp)
movl $0,%eax <-- why is it first clearing the %eax register?
call call
movl $3,%eax
leave
ret
如果堆栈帧需要对齐16字节,subq $16,%rsp
对此有何帮助?最初的pushq %rbp
指令是否已经将其偏移8,而现在为+24?还是上面有问题的这两行的要点是什么?
解决方法
第一个变体将局部变量存储在红色区域中,该区域位于堆栈指针下方的128个字节区域中,signal处理程序不会更改该区域。第二种变体不能使用红色区域,因为callq
指令写入(原始)红色区域,从而破坏了存储在其中的局部变量。 (当然,被调用的函数也可以写入原始的红色区域。)
%eax
设置为零,因为函数定义未声明任何原型,因此编译器必须假定它是可变参数函数。 %eax
(实际上是%al
)用于optimize the implementation of variadic functions。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。