我正在研究本地二进制文件的一些问题。我注意到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
问题:
-O0
或-O1
检测到这些情况,并且无法解决?subq $8, %rsp
语句?您不能优化没有开头的语句。为什么编译器会生成它?即使使用O0,寄存器分配算法也不应为不存在的内容生成代码。那么为什么要这样做呢?级别,需要关闭或关闭这些级别才能进行正确的调试。您还需要在编译时间与运行时间之间进行权衡。是否有原因导致编译器无法通过
-O0
或-O1
检测到这些情况>正是因为您要告诉编译器不要这样做。这些是optimisation
您看错望远镜的方式,请检查当您启动up
优化时编译器将为您做的令人敬畏的优化。