/********************************************* TEXT: C程序的机器级表示
AUTHOR: arden chao
DATE: 2006-10-17
EMAIL: arden1019@gmail.com
VERSION:1.0.0
\*********************************************/
////////////////////////////////
//2006-10-18 编译器与调试器入门
////////////////////////////////
使用gcc,可以参考gcc手册。
我们在这里就简单介绍一下我们需要的一些选项。
我们先看看一个源代码文件,是经过那些步骤变成可执行文件的:
-----------
源代码文件
*.c *.h
-----------
|
|
-----------
预处理器[-E]
-----------
|
|
-----------
编译器[-c]
-----------
|
|
-----------
目标代码
*.o
-----------
|
|
-----------
链接器
-----------
|
|
-----------
可执行文件
-----------
我们来一步一步完成这个过程:
还拿asm01.c做示范吧
<1>我们首先可以得到预处理后的文件:gcc -E asm01.c -o asm01.cpp
////////////////////// CPP CODE ////////////////////////
// filename: asm01.c
# 1 "asm01.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "asm01.c"
int test(int a)
{
int b=a;
return b;
}
<2>然后我们看看编译后的文件,首先可以让他在汇编完成后停下来:gcc -x cpp-output -S asm01.cpp -o asm01.s
///////////////// ASM CODE /////////////////////
//file name: asm01.s
.file "asm01.c"
.text
.p2align 4,,15
.globl _test
.def _test; .scl 2; .type 32; .endef
_test:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
popl %ebp
ret
/*********************************************************************PS: 解释一下-x选项,我在google上找了半天才找到一个中文的解释:)
http://www.shanghai.ws/gnu/gcc_1.htm
-x language
明确指出后面输入文件的语言为language (而不是从文件名后缀得到的默认选择).这个选项应用于后面 所有的输入文件,直到遇着下一个`-x'选项. language的可选值有`c', `objective-c', `c-header', `c++', `cpp-output', `assembler',和`assembler-with-cpp'.
-x none
关闭任何对语种的明确说明,因此依据文件名后缀处理后面的文件(就象是从未使用过`-x'选项).
如果只操作四个阶段(预处理,编译,汇编,连接)中的一部分,可以使用`-x'选项(或文件名后缀)告诉 gcc从哪里开始,用`-c', `-S',或`-E'选项告诉gcc到 哪里结束.注意,某些选项组合(例如, `-x cpp-output -E')使gcc不作任何事情.
\**********************************************************************/
<3>下面是到目标代码:gcc -x assembler -c asm01.s -o asm01.o
要想看这个二进制文件的内容,我们需要使用一个反汇编器.dev-cpp有一个叫做objdump的程序,我们可以使用带-d(Disassembly)选项来得到这个二进制文件的机器码表示及汇编码对照。
////////////// THE CONSOLE OUTPUT /////////////////////////
//
D:\project>objdump -d asm01.o
asm01.o: file format pe-i386
Disassembly of section .text:
00000000 <_test>:
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: 89 45 fc mov %eax,0xfffffffc(%ebp)
c: 8b 45 fc mov 0xfffffffc(%ebp),%eax
f: c9 leave
10: c3 ret
<4>最后就是链接了:gcc asm01.o -o asm01.exe
想要分析这个.exe程序,我们就需要反汇编程序了。我们并不把视线放到这里来,而且我们的asm01.exe也没有程序入口点。
PS:[2006-11-05]其实这个过程我们可以使用相应的应用程序来完成。
使用cpp来将.c文件翻译成.i文件,它只是进行预编译操作。完成头文件include、宏替换、过滤注释等操作。
使用ccl进行编译成.s文件
使用as编译成.o文件
使用ld链接成可执行文件
gdb这个题目,太多地方有详细的介绍,我比较推荐陈皓先生的文章:《用GDB调试程序》,可以拜访他的blog: http://blog.csdn.net/haoel