有没有办法让gcc输出原始二进制文件?

是否有一组命令行选项可以说服gcc从自包含的源文件生成一个平面的二进制文件? 例如,假设foo.c的内容是

static int f(int x) { int y = x*x; return y+2; } 

没有外部引用,没有什么要导出到链接器。 我想用这个function的机器指令来得到一个小文件,没有任何其他装饰。 有点像(DOS).COM文件,除了32位保护模式。

试试这个:

 $ cc -c test.c $ objcopy -O binary test.o binfile 

你可以确定它是正确的objdump

 $ objdump -d test.o test.o: file format pe-i386 Disassembly of section .text: 00000000 <_f>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 ec 04 sub $0x4,%esp 6: 8b 45 08 mov 0x8(%ebp),%eax 9: 0f af 45 08 imul 0x8(%ebp),%eax d: 89 45 fc mov %eax,-0x4(%ebp) 10: 8b 45 fc mov -0x4(%ebp),%eax 13: 83 c0 02 add $0x2,%eax 16: c9 leave 17: c3 ret 

和二进制文件比较:

 $ hexdump -C binfile 00000000 55 89 e5 83 ec 04 8b 45 08 0f af 45 08 89 45 fc |U......E...E..E.| 00000010 8b 45 fc 83 c0 02 c9 c3 |.E......| 00000018 

您可以使用objcopy将文本段拉出.o文件或a.out文件。

 $ cat qc f() {} $ cc -S -O qc $ cat qs .file "qc" .text .globl f .type f, @function f: pushl %ebp movl %esp, %ebp popl %ebp ret .size f, .-f .ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3" .section .note.GNU-stack,"",@progbits $ cc -c -O qc $ objcopy -O binary qo q.bin $ od -X q.bin 0000000 5de58955 000000c3 0000005 $ objdump -d qo qo: file format elf32-i386 Disassembly of section .text: 00000000 <f>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 5d pop %ebp 4: c3 ret 

其他答案肯定是要走的路。 但是,我不得不指定额外的命令行参数objcopy为了我的输出是预期的。 请注意,我正在开发64位机器上的32位代码,因此是-m32参数。 此外,我更喜欢英特尔汇编语法,所以你也会在参数中看到。

 $ cat test.c int main() { return 0; } $ gcc -nostdinc -m32 -masm=intel -Wall -c test.c -o test.o $ objdump --disassemble --disassembler-options intel test.o test.o: file format elf32-i386 Disassembly of section .text: 00000000 <main>: 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: b8 00 00 00 00 mov eax,0x0 8: 5d pop ebp 9: c3 ret 

好的,这里是我必须指定的地方,我特别只想要.text部分:

 $ objcopy --only-section=.text --output-target binary test.o test.bin $ hexdump -C test.bin 00000000 55 89 e5 b8 00 00 00 00 5d c3 |U.......].| 0000000a 

我花了大约2个小时的阅读和尝试不同的选择,才想出来。 希望这节省了其他人的时间。

您可以直接使用-Wl,<linker option>将选项传递给链接-Wl,<linker option>

相关文档从man gcc下面复制

轮候册,选项
将选项作为选项传递给链接器。 如果选项包含逗号,则在逗号处将其拆分为多个选项。 您可以使用此语法将参数传递给选项。 例如,-Wl,-Map,output.map将-map output.map传递给链接器。 当使用GNU链接器时,你也可以用-Wl,-Map = output.map获得同样的效果。

所以,如果你通过-Wl,--oformat=binary你将生成一个二进制文件,而不是elf格式。 其中--oformat=binary告诉ld生成一个二进制文件。

这消除了单独的objcopy的需要。

请注意,– --oformat=binary可以在链接器脚本中表示为OUTPUT_FORMAT("binary") 。 如果您想要处理平面二进制文件,那么您很有可能会从链接器脚本提供的高级别控制中受益。