pax*_*blo 6 assembly gcc opcode
我知道我可以使用以下命令获取编译器生成的汇编源代码:
gcc -S ...
Run Code Online (Sandbox Code Playgroud)
即使这令人烦恼也没有给我一个目标文件作为过程的一部分.
但是,如何获得编译代码的所有内容?我的意思是地址,生成的字节等等.
输出的指令gcc -S不告诉我有关指令长度或编码的任何信息,这是我想要看到的.
Mat*_*ery 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
...
Run Code Online (Sandbox Code Playgroud)
该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
...
Run Code Online (Sandbox Code Playgroud)
然后,我发现看到每行注释为有用<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
...
Run Code Online (Sandbox Code Playgroud)
但事实证明,你可以通过提供另一个晦涩的选项来解除这个,最终达到我最喜欢的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
...
Run Code Online (Sandbox Code Playgroud)
如果你使用调试符号构建(即编译-g),并且替换了-drwith -Srl,它将尝试使用相应的源代码行注释输出.