我正在调查本地二进制文件的一些问题。我注意到 g++ 创建了很多对我来说似乎没有必要的 ASM 输出。 -O0
示例:
Derived::Derived():
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp <--- just need 8 bytes for the movq to -8(%rbp), why -16?
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rdi <--- now we have moved rdi onto itself.
call Base::Base()
leaq 16+vtable for Derived(%rip), %rdx
movq -8(%rbp), %rax <--- effectively %edi, does not point into this area of the stack
movq %rdx, (%rax) <--- thus this wont change -8(%rbp)
movq -8(%rbp), %rax <--- so this statement is unnecessary
movl $4712, 12(%rax)
nop
leave
ret
选项 -O1 -fno-inline -fno-elide-constructors -fno-omit-frame-pointer
:
Derived::Derived():
pushq %rbp
movq %rsp, %rbp
pushq %rbx
subq $8, %rsp <--- reserve some stack space and never use it.
movq %rdi, %rbx
call Base::Base()
leaq 16+vtable for Derived(%rip), %rax
movq %rax, (%rbx)
movl $4712, 12(%rbx)
addq $8, %rsp <--- release unused stack space.
popq %rbx
popq %rbp
ret
此代码用于Derived
的构造函数调用Base
基础构造函数,然后覆盖位置0 处的vtable 指针并将常量值设置为int 成员除了 Base
包含的内容之外。
问题:
- 我能否通过尽可能少的优化来翻译我的程序并摆脱这些东西?我必须设置哪些选项?还是编译器无法使用
-O0
或-O1
检测到这些情况并且没有办法绕过它们? - 为什么会生成
subq $8, %rsp
语句?您不能优化输入或输出一开始就没有意义的语句。为什么编译器会生成它呢?即使使用 O0,寄存器分配算法也不应该为不存在的东西生成代码。那为什么要这样做呢?
最佳答案
is there a reason the compiler cannot detect these cases with
-O0
or-O1
正是因为您告诉编译器不要这样做。这些是优化级别,需要关闭或关闭以进行正确调试。您还在为运行时牺牲编译时间。
您正在用错误的方式观察望远镜,看看当您启动up 优化时编译器会为您做的很棒的优化。
关于c++ - 从 g++ 输出中删除不需要的汇编程序语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58131883/