如何在gcc中从C / C ++源获取汇编程序输出?
如何做到这一点?
如果我想分析某些东西是如何编译的,我将如何获取发出的汇编代码?
解决方案
使用-S开关
g++ -S main.cpp
或者也与gcc
gcc -S main.c
也看到这个
使用-S选项:
gcc -S program.c
如果要查看的内容取决于输出的链接,则除了上述gcc -S之外,输出目标文件/可执行文件上的objdump也可能有用。这是Loren Merritt编写的非常有用的脚本,它将默认的objdump语法转换为可读性更高的nasm语法:
#!/usr/bin/perl -w $ptr='(BYTE|WORD|DWORD|QWORD|XMMWORD) PTR '; $reg='(?:[er]?(?:[abcd]x|[sd]i|[sb]p)|[abcd][hl]|r1?[0-589][dwb]?|mm[0-7]|xmm1?[0-9])'; open FH, '-|', '/usr/bin/objdump', '-w', '-M', 'intel', @ARGV or die; $prev = ""; while(<FH>){ if(/$ptr/o) { s/$ptr(\[[^\[\]]+\],$reg)//o or s/($reg,)$ptr(\[[^\[\]]+\])//o or s/$ptr/lc /oe; } if($prev =~ /\t(repz )?ret / and $_ =~ /\tnop |\txchg *ax,ax$/) { # drop this line } else { print $prev; $prev = $_; } } print $prev; close FH;
我怀疑这也可以在gcc -S的输出上使用。
使用-S选项来gcc(或者g ++)。
gcc -S helloworld.c
这将在helloworld.c上运行预处理器(cpp),执行初始编译,然后在运行汇编器之前停止。
默认情况下,这将输出文件" helloworld.s"。仍然可以使用-o选项设置输出文件。
gcc -S -o my_asm_output.s helloworld.c
当然,这只有在我们拥有原始来源的情况下才有效。
如果只具有生成的目标文件,则另一种方法是使用objdump,方法是设置--disassemble选项(或者缩写形式为-d)。
objdump -S --disassemble helloworld > helloworld.dump
如果为目标文件(在编译时为-g)启用了调试选项,并且尚未剥离该文件,则此选项最有效。
运行file helloworld
将给我们一些有关使用objdump获得的详细程度的指示。
就像每个人都指出的那样,在GCC中使用-S
选项。我还想补充一点,结果可能会(疯狂!)取决于我们是否添加优化选项(" -O0"表示无,"-O2"表示进行性优化)。
特别是在RISC体系结构上,编译器通常会在进行优化时转换几乎无法识别的代码。查看结果令人印象深刻,令人着迷!
这将生成带有C代码+行号交织在一起的asm,以便更轻松地查看哪些行生成了什么代码。
# create assembler code: c++ -S -fverbose-asm -g -O2 test.cc -o test.s # create asm interlaced with source lines: as -alhnd test.s > test.lst
在《面向程序员的算法》(第4页)中找到。
如前所述,请查看-S标志。
还值得研究" -fdump-tree"标志系列,尤其是" -fdump-tree-all"标志,它使我们可以看到gcc的某些中间形式。这些通常比汇编器更具可读性(至少对我而言),并让我们了解优化过程的执行方式。
使用" -S"作为选项。它在终端中显示装配体输出。