从g ++输出中删除不必要的汇编器语句

问题描述 投票:-2回答:1

我正在研究本地二进制文件的一些问题。我注意到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,寄存器分配算法也不应为不存在的内容生成代码。那么为什么要这样做呢?
c++ assembly compiler-construction g++
1个回答
1
投票

是否有原因导致编译器无法通过-O0-O1检测到这些情况>

正是因为您要告诉编译器不要这样做。这些是optimisation

级别,需要关闭或关闭这些级别才能进行正确的调试。您还需要在编译时间与运行时间之间进行权衡。

您看错望远镜的方式,请检查当您启动up

优化时编译器将为您做的令人敬畏的优化。
© www.soinside.com 2019 - 2024. All rights reserved.