如何在gcc中获得完整的汇编程序输出?
我知道我可以通过以下方式获得编译器生成的汇编程序源代码:如何在gcc中获得完整的汇编程序输出?,gcc,assembly,opcode,Gcc,Assembly,Opcode,我知道我可以通过以下方式获得编译器生成的汇编程序源代码: gcc -S ... 尽管令人恼火的是,在这个过程中没有给我一个对象文件 但是我怎样才能获得关于编译代码的所有信息呢?我指的是地址,生成的字节等等 gcc-S所输出的指令没有告诉我任何关于指令长度或编码的信息,这正是我想看到的。我觉得你需要一个反汇编程序objdump几乎是标准(otool在Mac OS X上);与链接器提供的任何映射文件信息相一致,对象文件的反汇编应该提供您想要的一切。gcc将生成一个汇编语言源文件。然后可以使用as-
gcc -S ...
尽管令人恼火的是,在这个过程中没有给我一个对象文件
但是我怎样才能获得关于编译代码的所有信息呢?我指的是地址,生成的字节等等
gcc-S所输出的指令没有告诉我任何关于指令长度或编码的信息,这正是我想看到的。我觉得你需要一个反汇编程序
objdump
几乎是标准(otool
在Mac OS X上);与链接器提供的任何映射文件信息相一致,对象文件的反汇编应该提供您想要的一切。gcc将生成一个汇编语言源文件。然后可以使用as-a yourfile.S
生成一个列表,其中包含每条指令的偏移量和编码字节-a
还有一些子选项来控制列表文件中显示的内容(as--help
将提供它们的列表以及其他可用选项)
生成仅适用于xx.asm的“列表”文件x.lst
对于xx.c和xx.asm,您可以同时编译它们,然后使用'gdb'-gnu调试器我喜欢
objdump
,但最有用的选项并不明显,尤其是在包含重定位的对象文件上使用它,而不是在最终二进制文件上
objdump-d一些二进制文件
做了合理的工作
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
...
然后,我发现将每一行注释为
非常有用objdump
有一个方便的选项,但是它有一个恼人的副作用,就是关闭实际字节的转储-objdump——前缀地址-drsome_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
...
...
00000005 <foo> push %ebp
00000006 <foo+0x1> mov %esp,%ebp
00000008 <foo+0x3> push %ebx
...
如果您使用调试符号构建(即使用
-g
编译),并将-dr
替换为-Srl
,它将尝试用相应的源代码行注释输出。获取快速列表的最简单方法是使用汇编程序的-a
选项,您可以将-Wa,-a
放在gcc
命令行上。您可以对a选项使用各种修饰符,以精确地影响输出的内容——请参见as(1)手册页。的可能重复项
...
00000005 <foo> push %ebp
00000006 <foo+0x1> mov %esp,%ebp
00000008 <foo+0x3> push %ebx
...
...
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
...