我想知道如何在我的 C 源文件上使用GCC来转储机器代码的助记符版本,以便我可以看到我的代码被编译成什么。你可以用 Java 做到这一点,但我无法找到 GCC 的方法。
我正在尝试在汇编中重写一个 C 方法,看看 GCC 是如何做到的,这将是一个很大的帮助。
如果您使用调试符号进行编译(添加-g到您的 GCC 命令行,即使您也在使用-O31),您可以使用objdump -S生成与 C 源代码交错的更具可读性的反汇编。
-g
-O3
objdump -S
>objdump --help [...] -S, --source Intermix source code with disassembly -l, --line-numbers Include line numbers and filenames in output
objdump -drwC -Mintel很好:
objdump -drwC -Mintel
-r
puts
call
-R
-C
-w
-Mintel
.intel_syntax noprefix
-S
你可以alias disas="objdump -drwCS -Mintel"在你的~/.bashrc. 如果不在 x86 上,或者如果您喜欢 AT&T 语法,请省略-Mintel.
alias disas="objdump -drwCS -Mintel"
~/.bashrc
例子:
> gcc -g -c test.c > objdump -d -M intel -S test.o test.o: file format elf32-i386 Disassembly of section .text: 00000000 <main>: #include <stdio.h> int main(void) { 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: 83 e4 f0 and esp,0xfffffff0 6: 83 ec 10 sub esp,0x10 puts("test"); 9: c7 04 24 00 00 00 00 mov DWORD PTR [esp],0x0 10: e8 fc ff ff ff call 11 <main+0x11> return 0; 15: b8 00 00 00 00 mov eax,0x0 } 1a: c9 leave 1b: c3 ret
请注意,这 未 使用-r,因此未使用符号名称进行call rel32=-4注释。puts并且看起来像一个call跳入 main 中调用指令中间的损坏。请记住,rel32调用编码中的位移只是一个占位符,直到链接器填充一个真实的偏移量(在这种情况下是一个 PLT 存根,除非您静态链接 libc)。
call rel32=-4
rel32
脚注 1 :交错源代码可能很混乱,对优化构建没有多大帮助;为此,请考虑https://godbolt.org/或其他可视化哪些指令与哪些源代码行相关的方法。