当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《你如何在gcc中从C/C++源获得汇编程序输出?》经验,为你挑选了11个好方法。

怎么做到这一点?

如果我想分析如何编译某些内容,我将如何获得发出的汇编代码?



1> Andrew Edgec..:

使用-Sgcc(或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获得的详细程度的一些指示.


虽然这是正确的,但我发现Cr McDonough的答案结果更有用.
另外一个用途:objdump -M intel -S --disassemble helloworld> helloworld.dump来获取与linux上的nasm兼容的intel语法中的对象转储.
如果你有一个功能来优化/检查,那么你可以尝试在线交互式C++编译器,即[godbolt](http://gcc.godbolt.org/)
最好使用`gcc -O -fverbose-asm -S`

2> PhirePhly..:

这将生成asm代码,其中C代码+行号交织在一起,以便更容易地看到哪些行生成了什么代码.

# 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

在程序员的算法中找到,第3页(这是PDF的整体第15页).


`g ++ -g -O0 -c -fverbose-asm -Wa,-adhln test.cpp> test.lst`将是这个的简写版本.
您也可以使用`gcc -c -g -Wa,-ahl = test.s test.c`或`gcc -c -g -Wa,-a,-ad test.c> test.txt`
(实际上是在页面上(编号)3(这是PDF的第15页))

3> 小智..:

以下命令行来自Christian Garbin的博客

g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt

我在Win-XP的DOS窗口中运行G ++,对着包含隐式转换的例程

c:\gpp_code>g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt
horton_ex2_05.cpp: In function `int main()':
horton_ex2_05.cpp:92: warning: assignment to `int' from `double'

输出是用原始C++代码分配的生成代码(C++代码在生成的asm流中显示为注释)

  16:horton_ex2_05.cpp **** using std::setw;
  17:horton_ex2_05.cpp ****
  18:horton_ex2_05.cpp **** void disp_Time_Line (void);
  19:horton_ex2_05.cpp ****
  20:horton_ex2_05.cpp **** int main(void)
  21:horton_ex2_05.cpp **** {
 164                    %ebp
 165                            subl $128,%esp
?GAS LISTING C:\DOCUME~1\CRAIGM~1\LOCALS~1\Temp\ccx52rCc.s
166 0128 55                    call ___main
167 0129 89E5          .stabn 68,0,21,LM2-_main
168 012b 81EC8000      LM2:
168      0000
169 0131 E8000000      LBB2:
169      00
170                    .stabn 68,0,25,LM3-_main
171                    LM3:
172                            movl $0,-16(%ebp)



4> Doug T...:

使用-S开关

g++ -S main.cpp

或者与gcc

gcc -S main.c

也看到这个


查看常见问题解答:"询问和回答您自己的编程问题也很完美".关键是现在StackOverflow包含Q&A作为其他人的资源.

5> Dark Shikari..:

如果你想看到的东西取决于输出的链接,那么除了前面提到的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(){
    if(/$ptr/o) {
        s/$ptr(\[[^\[\]]+\],$reg)/$2/o or
        s/($reg,)$ptr(\[[^\[\]]+\])/$1$3/o or
        s/$ptr/lc $1/oe;
    }
    if($prev =~ /\t(repz )?ret / and
       $_ =~ /\tnop |\txchg *ax,ax$/) {
       # drop this line
    } else {
       print $prev;
       $prev = $_;
    }
}
print $prev;
close FH;

我怀疑这也可以用在gcc -S的输出上.



6> 小智..:

好吧,正如大家所说,使用-S选项.如果使用-save-temps选项,还可以获得预处理文件(.i),汇编文件( .s)和目标文件(*.o).(使用-E,-S和-c获取每个.)



7> Dan Lenski..:

正如大家所指出的,使用-SGCC选项.我还想补充一点,结果可能会有所不同(非常!),具体取决于您是否添加优化选项(-O0对于没有优化选项-O2).

特别是在RISC体系结构中,编译器通常会在进行优化时将代码转换为几乎无法识别.看结果令人印象深刻,令人着迷!



8> Chris Jeffer..:

如前所述,请查看-S标志.

它还值得查看'-fdump-tree'标志系列,特别是'-fdump-tree-all',它可以让你看到一些gcc的中间形式.这些通常比汇编程序更具可读性(至少对我而言),并让您了解优化通过的执行方式.



9> mcandre..:

如果您正在寻找LLVM组装:

llvm-gcc -emit-llvm -S hello.c



10> Jeremy Ruten..:

使用-S选项:

gcc -S program.c



11> Antonin GAVR..:

我没有在答案中看到这种可能性,可能是因为问题是从2008年开始,但在2018年你可以使用Matt Goldbolt的在线网站https://godbolt.org

你也可以在本地git克隆并运行他的项目https://github.com/mattgodbolt/compiler-explorer

推荐阅读
低调pasta_730
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有