请问可以有人解释一下吗?我有一个C程序,我能转换成汇编吗?如果可以,怎么做呢?
gcc -O2 -S -c foo.c
来获取可读性更高的汇编输出。使用gcc,您可以使用-S
选项:
gcc -O2 -S myfile.c
大多数其他选项(例如-O2
)也可以在此处使用,以确定产生何种类型的汇编代码。
然而,请注意,这只是暴露了编译器经过的一个中间步骤(不是生成汇编源文件,而是它所代表的机器代码)。将此代码通过汇编器传递后的最终结果与直接编译为机器代码没有任何区别。
这就是编译器的作用。
编译器将您的C程序编译为机器语言,这是机器程序的二进制表示。当人类想要编写机器语言时,他们会使用汇编语言编写它,然后将其翻译为二进制机器语言。
汇编代码只是二进制机器语言的可读形式。
C程序:
$ cat test.c
#include <stdio.h>
int main(int argc, char **argv) {
int a = 11+12;
printf("a = %d\n", a);
return 0;
}
$ gcc -c test.c
将其拆开:
$ objdump -d test.o
test.o: file format elf32-i386
Disassembly of section .text:
00000000 <main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 e4 f0 and $0xfffffff0,%esp
6: 83 ec 20 sub $0x20,%esp
9: c7 44 24 1c 17 00 00 movl $0x17,0x1c(%esp)
10: 00
11: b8 00 00 00 00 mov $0x0,%eax
16: 8b 54 24 1c mov 0x1c(%esp),%edx
1a: 89 54 24 04 mov %edx,0x4(%esp)
1e: 89 04 24 mov %eax,(%esp)
21: e8 fc ff ff ff call 22 <main+0x22>
26: b8 00 00 00 00 mov $0x0,%eax
2b: c9 leave
2c: c3 ret
您的编译器应该有一些选项来实现这个功能。例如,对于gcc,您可以使用-S选项。以下是一个简短的示例:
// test.c
#include <stdio.h>
int
main ()
{
printf ("hello, world\n");
return 0;
}
-S
选项进行编译。这将生成一个test.s文件,其中包含汇编代码:.file "test.c"
.section .rodata
.LC0:
.string "hello, world"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $4, %esp
movl $.LC0, (%esp)
call puts
movl $0, %eax
addl $4, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
既然你提到了Dev-C ++,值得一提的是-S
标志也可以在那里使用。假设在Windows上,Dev-C ++仍将命名输出为.exe,但结果不会是可执行文件,因此只需将扩展名更改为.txt或其他格式,以便可以在所选编辑器中读取。在“项目”>“项目选项”>“参数”>“编译器”或“工具”>“编译器选项”下添加选项/标志。