如何在gcc中获得完整的汇编程序输出?

时间:2010-09-07 03:39:44

标签: gcc assembly opcode

我知道我可以使用以下命令获取编译器生成的汇编程序 source 代码:

gcc -S ...

即使这令人讨厌,也没有给我一个目标文件作为整个过程的一部分。

但是如何获得编译代码的所有内容?我指的是地址,生成的字节等等。

gcc -S输出的指令不会告诉我有关指令长度或编码的任何信息,这就是我想要看到的内容。

5 个答案:

答案 0 :(得分:10)

我喜欢objdump,但最有用的选项并不明显 - 特别是如果你在包含重定位的目标文件上使用它,而不是最终的二进制文件。

objdump -d some_binary做得很合理。

objdump -d some_object.o不太有用,因为对外部函数的调用不会被有效地反汇编:

...
00000005 <foo>:
   5:   55                      push   %ebp
   6:   89 e5                   mov    %esp,%ebp
   8:   53                      push   %ebx
...
  29:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  30:   e8 fc ff ff ff          call   31 <foo+0x2c>
  35:   89 d8                   mov    %ebx,%eax
...

call实际上是printf() ...添加-r标志有助于此;它标志着重新安置。 objdump -dr some_object.o给出:

...
  29:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
                        2c: R_386_32    .rodata.str1.1
  30:   e8 fc ff ff ff          call   31 <foo+0x2c>
                        31: R_386_PC32  printf
...

然后,我发现将每行注释为<symbol+offset>很有用。 objdump有一个方便的选项,但它有关闭实际字节转储的烦人副作用 - objdump --prefix-addresses -dr some_object.o给出:

...
00000005 <foo> push   %ebp
00000006 <foo+0x1> mov    %esp,%ebp
00000008 <foo+0x3> push   %ebx
...

但事实证明你可以通过提供另一个模糊选项来撤消它,最后到达我最喜欢的objdump咒语:

objdump --prefix-addresses --show-raw-insn -dr file.o

给出如下输出:

...
00000005 <foo> 55                       push   %ebp
00000006 <foo+0x1> 89 e5                        mov    %esp,%ebp
00000008 <foo+0x3> 53                           push   %ebx
...
00000029 <foo+0x24> c7 04 24 00 00 00 00        movl   $0x0,(%esp)
                        2c: R_386_32    .rodata.str1.1
00000030 <foo+0x2b> e8 fc ff ff ff              call   00000031 <foo+0x2c>
                        31: R_386_PC32  printf
00000035 <foo+0x30> 89 d8                       mov    %ebx,%eax
...

如果您使用调试符号构建(即使用-g编译),并将-dr替换为-Srl,它将尝试使用相应的源注释输出线。

答案 1 :(得分:3)

获得快速列表的最简单方法是使用汇编程序的-a选项,您可以通过将-Wa,-a放在gcc命令行上来执行此操作。您可以对选项使用各种修饰符来确切地影响出来的内容 - 请参阅as(1)手册页。

答案 2 :(得分:1)

gcc将生成汇编语言源文件。然后,您可以使用as -a yourfile.S生成包含每条指令的偏移量和编码字节的列表。 -a还有一些子选项来控制列表文件中显示的内容(as --help会列出它们以及其他可用选项。)

答案 3 :(得分:0)

听起来像你想要一个反汇编程序。 objdump几乎是标准版(Mac OS X上的otool);与链接器为您提供的任何映射文件信息一致,对象文件的反汇编应该为您提供所需的一切。

答案 4 :(得分:0)

nasm -f elf xx.asm -l x.lst

gcc xx.c xx.o -o xx

生成一个'list'文件x.lst,仅适用于xx.asm

对于xx.c​​以及xx.asm你可以编译它们然后使用'gdb' - gnu debugger