如何在gcc中从C / C ++源获取汇编程序输出?

时间:2020-03-06 14:45:30  来源:igfitidea点击:

如何做到这一点?

如果我想分析某些东西是如何编译的,我将如何获取发出的汇编代码?

解决方案

使用-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"作为选项。它在终端中显示装配体输出。