检查生成的汇编代码?

时间:2015-07-19 03:21:36

标签: c++ assembly g++

我有以下测试程序来检查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;
}

根据How to get GCC to generate assembly code,我编译了源文件:

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

但是,当我捕捉时,我看不到对旋转的调用:

$ 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)
...

相关,这是导致我想要查看生成的代码的基本问题How to force const propagation through an inline function?

4 个答案:

答案 0 :(得分:2)

看起来g ++已将main()优化为"y < THIS_SIZE"

的断言失败

如果您想了解更多信息,请告诉我们rotlFixed()的实施情况。

答案 1 :(得分:1)

标记-O1正在优化您的函数调用rotlFixed(...)。使用-O0执行此操作。

此外,如果您使用-c,则不需要-S

答案 2 :(得分:1)

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

通过在main()中拥有它的方式,编译器会发现你从不使用结果并丢弃未使用的函数。

答案 3 :(得分:1)

您真的想将-fverbose-asm传递给g++gcc -S-O

您可能还希望获得代码的预处理表单(gcc -C -E)。

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

你显然至少需要一些优化-O1;否则生成的汇编程序将包含许多无用的代码(使其不太可读)。

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

您可以使用MELT自定义GCC。