c++ - 从 g++ 输出中删除不需要的汇编程序语句

标签 c++ assembly compiler-construction g++

我正在调查本地二进制文件的一些问题。我注意到 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/

相关文章:

c++ - 为什么类中方法的顺序在 C++ 中无关紧要?

c++ - 跟踪简单的递归函数

c++ - 如何对陀螺仪数据进行离散积分?

C++ 到 MIPS 汇编

c - PIC芯片16F690

java - Java、C++、Python 和 ObjC 的在线编译器/运行时?

unordered_map 上的 C++ 未定义行为作为基于范围的 for 循环中的右值

c++ - 将缓冲区与另一个缓冲区连接

assembly - MOV r/m8,r8 和 MOV r8,r/m8 的区别

c - C中的汇编代码是什么?