检查生成的汇编代码

Examine generated assembly code?

本文关键字:汇编 代码 检查      更新时间:2023-10-16

我有以下测试程序来检查GCC生成的代码。rotlFixed在头文件misc.h中提供,并声明为内联。它还使用模板专门化来调用GCC内联汇编:

int main(int argc, char* argv[])
{
  byte r1 = rotlFixed(1, 1);
  byte r2 = rotlFixed(1, 255);
  word16 r3 = rotlFixed(1, 1);
  word16 r4 = rotlFixed(1, 255);
  word16 r5 = rotlFixed(1, 256);
  word16 r6 = rotlFixed(1, 65535);
  cout << r1 << "," << r2 << "," << r3 << "," << r4 << ",";
  cout << r5 << "," << r6 << endl;
  return 0;
}

根据如何让GCC生成汇编代码,我编译了源文件:

g++ -O1 -S -c cryptopp-test.cxx

但是当我执行命令时,我没有看到对rotate的调用:

$ cat cryptopp-test.s
    .file   "cryptopp-test.cxx"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "misc.h"
.LC1:
    .string "y < THIS_SIZE"
    .text
    .globl  main
    .type   main, @function
main:
.LFB2196:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $_ZZN8CryptoPP9rotlFixedIiEET_S1_jE19__PRETTY_FUNCTION__, %ecx
    movl    $692, %edx
    movl    $.LC0, %esi
    movl    $.LC1, %edi
    call    __assert_fail
    .cfi_endproc
.LFE2196:
    .size   main, .-main
    .type   _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB2311:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $_ZStL8__ioinit, %edi
    call    _ZNSt8ios_base4InitC1Ev
    movl    $__dso_handle, %edx
    movl    $_ZStL8__ioinit, %esi
    movl    $_ZNSt8ios_base4InitD1Ev, %edi
    call    __cxa_atexit
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE2311:
    .size   _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
    .section    .init_array,"aw"
    .align 8
    .quad   _GLOBAL__sub_I_main
    .section    .rodata
    .align 32
    .type   _ZZN8CryptoPP9rotlFixedIiEET_S1_jE19__PRETTY_FUNCTION__, @object
    .size   _ZZN8CryptoPP9rotlFixedIiEET_S1_jE19__PRETTY_FUNCTION__, 54
_ZZN8CryptoPP9rotlFixedIiEET_S1_jE19__PRETTY_FUNCTION__:
    .string "T CryptoPP::rotlFixed(T, unsigned int) [with T = int]"
    .local  _ZStL8__ioinit
    .comm   _ZStL8__ioinit,1,1
    .hidden __dso_handle
    .ident  "GCC: (GNU) 5.1.1 20150618 (Red Hat 5.1.1-4)"
    .section    .note.GNU-stack,"",@progbits

我显然做错了什么,因为我想检查的调用丢失了。

如何生成清单?或者,如果我正在生成它,我如何显示所有相关的部分?

提前感谢。


如果重要的话,系统是Fedora 22 x86_64,和GCC 5.1.1:

$ uname -a
Linux localhost.localdomain 4.0.4-301.fc22.x86_64 #1 SMP Thu May 21 13:10:33 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ gcc --version
gcc (GCC) 5.1.1 20150618 (Red Hat 5.1.1-4)
...

相关的,这是一个潜在的问题,导致我想看看生成的代码如何通过内联函数强制const传播?

看起来g++已经优化了您的main()以失败的断言"y < THIS_SIZE"

如果你想要更多的信息,你应该给我们看rotlFixed()的实现。

标志-O1正在优化您的函数调用rotlFixed(...)。用-O0来做。

同样,如果你使用的是-S,你也不需要-c

如果您希望看到编译器优化后的机器码,请将其放入不带main()的文件中并进行编译。那么编译器会认为它正在构建一个可以从其他地方调用的函数。

在main()中,编译器看到你从不使用结果,并丢弃未使用的函数。

您真的希望将-fverbose-asm-S-O一起传递给g++gcc

您可能还想获得代码的预处理形式(使用gcc -C -E)。

-fverbose-asm要求GCC编译器在生成的汇编代码中发出注释。

你显然需要一些优化-O1;否则生成的汇编程序将包含大量无用的代码(使其可读性降低)。

您可能希望传递-fdump-tree-all(或其他-fdump标志)来获得描述GCC内部各种内部表示的数百个转储文件。

您可以使用MELT来定制GCC