/********************************************* TEXT: C程序的机器级表示
AUTHOR: arden chao
DATE: 2006-10-17
EMAIL: arden1019@gmail.com
VERSION:1.0.0
\*********************************************/
参考文献:
《深入理解计算机系统》中国电力出版社,2004,ISBN 7-5083-2175-8 ,[美]Randal E.Bryant David O'Hallaron著 ,龚奕利,雷迎春译。
《C\C++深层探索》中国邮电出版社,2002,ISBN 7-115-10915-X 姚新颜编著。
《GNU/Linux编程指南》清华大学出版社,2001,ISBN 7-302-05550-5/TP.3273[美]Kurt Wall 等著 ,张辉等译。
《UNIX环境高级编程》机械工业出版社,2000,ISBN 7-111-07579-X [美]W.Richard Stevens著,尤晋元 等译。
////////////////////////
//2006-10-17 前言及准备
////////////////////////
在遇到《CSAPP》之前,在遇到一些C语言中奇怪的问题时,我就已经开始尝试从编译器得到的汇编代码中寻找答案。但是,每次都需要编译到汇编码从大量的不易读代码中分析问题,并不是很好的选择。于是我就想,是不是可以编写一本这样的参考手册,在C语言和汇编中做一些对照。比如,想明白switch语句汇编级是如何表示的?那我可以在此参考手册中很容易的找到答案,而不必为此目的专门再写一段程序了。然而,那个时候的我还没有这样的能力及时间来完成这件事情。
过了不久,一个偶然的机会,我遇见了《CSAPP》。读了简单的几页纸后,我发现这就是我寻找的东西。于是如获至宝,从china-pub处购得一本雷迎春先生的译本。书中的第三章主要就是阐述了C程序的汇编、机器级代码的表示。从汇编的基本指令、寻址方式到特定C语言模块的分析,将C语言和汇编的种种关联很清晰的呈现我的面前。
今天开始想把我在这块区域的一些尝试纪录下来,希望能对自己的理解负责任,也希望偶然能给与我一样的求学者以帮助。到目前为止,虽然Java和Dot Net盛行,但我认为想成为一流的程序员,还是需要距离系统本身近一些,这些分析能力至少应该具备。
此为前言,下为准备。
可以和我一起分享这篇不成熟文字的朋友,可能需要了解C语言及汇编语言的语法,大学时候汇编课堂上的东西可能还会拿出来直接用。在我们提到XXX寻址方式的时候,不要回避,即使不能马上在脑子里给我答案,也应该像我似的,Google一下,短时间里做以温习。
还有,你得会使用一个C编译器。我们会使用gcc作为此文字的编译器。在windows平台下,你可以安装Dev-Cpp得到一个IDE环境,其中包含了我们需要的编译器。如果在类linux下,操作系统应该已经包含了gcc环境。没有使用MS的编译器,是因为我都是在IDE环境使用VS,cl也用过几次,但总不如找个熟悉的编译器来的硬气。而且我现在也不知道此文档会发展到什么程度,万一那天需要分析一下编译器实现的时候,我们的gcc至少会把源代码放在我们跟前,而CL的动作,我们没办法确定。当然,还有很多C的编译器,但我都不熟悉:(。
老习惯,从一个简单的例子中,给出最简单分析的方式:
我们给出一段简单的c代码,并演示如何得到汇编代码。
1:打开dev-cpp,输入下面的test代码,保存为asm01.c文件。
2:开始--运行--cmd,在命令行模式,切换目录到asm01.c所在目录
3:键入下面命令: gcc -O2 -S asm01.c
注意:
1:gcc命令中 O 和 S 都是大写的。O2的意思是2级优化,S的意思是只进行编译,生成.s的汇编代码文件。
2:如果你在命令行运行gcc时提示没有找到该命令,你需要将gcc所在目录添加到系统环境变量的path中,gcc所在目录在dev-cpp所在目录的bin目录中,例如我的机器上我在path环境变量中添加了如下项目c:\dev-cpp\bin,记住,使用;分隔符。
3:我的机器环境为PIII-800 \win2000p sp4 \dev-cpp
/////////////////// C CODE ///////////////////////
// file name:asm01.c
int test(int a)
{
int b=a;
return b;
}
///////////////// 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
就写这么多吧,下次,我计划一起复习一下编译器。