2010-09-07 93 views
4

我知道我可以用得到由编译器生成汇编源代码如何在gcc中获得完整的汇编程序输出?

gcc -S ... 

即使是烦人不给我一个目标文件作为过程的一部分。

但是我怎么能得到编译代码的一切?我的意思是地址,生成的字节等等。

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

+0

[使用GCC生成可读的程序集?](https://stackoverflow.com/questions/1289881/using-gcc-to-produce-readable-assembly) – 2018-02-27 19:49:29

回答

7

我喜欢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,它将尝试使用相应的源代码行对输出进行注释。

0

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

1

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

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

gcc xx.c xx.o -o xx 

产生一个“清单”文件x.lst后者只适用于xx.asm

为xx.c与xx.asm你可以编译他们两个,然后用“gdb”一起 - GNU调试

3

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