LCC编译器的源程序分析(1)C编译器的目标

原创 2007年05月07日 20:01:00
先从简单的目标来分析这个大规模的C编译器,毕竟它的功能比较复杂,并且源程序的行数也是非常多的。因此,把简单的目标定出来,然后再分析它,这样才会有的放矢。接着再跟着编译运行的主线来分析它的源程序。下面先看一下简单的C例子,如下:
 
#001 #include <stdio.h>
#002 
#003 int main(void)
#004 {
#005  int nTest1 = 1;
#006  int nTest2 = 2;
#007  int nTest3;
#008  int i;
#009  
#010  nTest3 = nTest1 + nTest2;
#011  printf("nTest3 = %d/r/n",nTest3);
#012  
#013  for (i = 0; i < 5; i++)
#014  {
#015         printf("%d/r/n",nTest3+i);
#016  }
#017  
#018  printf(__TIME__" "__DATE__"/r/nhello world/n");
#019  return 0;
#020 }
#021 
 
上面的程序就是用来说明编译器工作的例子,它在第一行里包含了头文件stdio.h,由于后面调用printf函数输出显示到屏幕里。第二行空行,第三行是main函数,它是C程序的入口函数。在main函数里,定义了几个局部变量,分别第5678行的变量。第10行作两个变量nTest1nTest2的加法,然后赋值给变量nTest3。第11行显示变量nTest3的值,是用10进制输出显示。在第1316行是5次输出nTest3+i值。在第18行里输出编译这个程序的时间和hello world的字符串。
 
C编译器的任务,就是把上面的源程序变换到汇编代码输出,或者变成其它中间代码输出。在这里LCC编译器是输出汇编代码的,所以就不介绍其它的中间代码输出。那么LCC把上面的源程序变成什么样的汇编输出呢?下面就先把它的目标代码看一下,如下:
 
#001 [global $main]
#002 [section .text]
#003 $main:
#004 push ebx
#005 push esi
#006 push edi
#007 push ebp
#008 mov ebp, esp
#009 sub esp, 16
#010 mov dword [ebp + -12], 1
#011 mov dword [ebp + -16], 2
#012 mov edi, dword [ebp + -12]
#013 mov esi, dword [ebp + -16]
#014 lea edi, [esi + edi]
#015 mov dword [ebp + -8], edi
#016 mov edi, dword [ebp + -8]
#017 push dword edi
#018 lea edi, [$L2]
#019 push dword edi
#020 call $printf
#021 add esp, 8
#022 mov dword [ebp + -4], 0
#023 $L3:
#024 mov edi, dword [ebp + -8]
#025 mov esi, dword [ebp + -4]
#026 lea edi, [esi + edi]
#027 push dword edi
#028 lea edi, [$L7]
#029 push dword edi
#030 call $printf
#031 add esp, 8
#032 $L4:
#033 inc dword [ebp + -4]
#034 cmp dword [ebp + -4], 5
#035 jl near $L3
#036 lea edi, [$L8]
#037 push dword edi
#038 call $printf
#039 add esp, 4
#040 mov eax, 0
#041 $L1:
#042 mov esp, ebp
#043 pop ebp
#044 pop edi
#045 pop esi
#046 pop ebx
#047 ret
#048 [extern $printf]
#049 [section .data]
#050 times ($-$$) & 0 nop
#051 $L8:
#052 db '00:30:28 Apr 07 2007', 13, 10, 'hello world', 10, 0
#053 times ($-$$) & 0 nop
#054 $L7:
#055 db '%d', 13, 10, 0
#056 times ($-$$) & 0 nop
#057 $L2:
#058 db 'nTest3 = %d', 13, 10, 0
#059 
 
LCC是可以生成很多目标代码的C编译器,在这里主要介绍生成X86NASM汇编的代码。上面的汇编代码就是NASM的汇编格式,可以使用NASM编译生成目标文件,然后再用连接程序生成可执行文件。如果不能看懂上面的NASM汇编,就需要去看NASM手册了,这个手册在网上有下载。如果想更深入理解汇编生成机器码的过程,当然也可以深入分析NASM的程序实现。
从上面的C和汇编也可以看出,汇编代码比C代码要复杂,行数也比较多,还分了数据段和代码段。所以使用C编译器是可以大大地提高生产效率的,并且更容易理解,这样就容易降低软件的成本,容易开发大规模的软件工程。
 
 
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

精妙SQL语句

说明:复制表(只复制结构,源表名:a 新表名:b)SQL: select * into b from a where 1说明:拷贝表(拷贝资料,源表名:a 目标表名:b)SQL: insert int...

lcc源代码解析之types.c

最近好TM的忙啊,坑爹教练让每天五点钟起床去练车,平均每天至少有四个设备启动,运行中异常重启的问题报过来,我也是醉了。 今天终于有点时间继续写blog了,废话不多说,代码上。 今天解析lcc中的一...

lcc源代码详解之介绍

LCC,全称为"Local C Compiler"或"Little C Compiler",是一个小型自由的ANSI C编译器,源代码开放,由Chris Fraser和David Hanson设计开发...
  • b2b160
  • b2b160
  • 2009-03-26 11:08
  • 3091

LCC编译器的源程序分析(2)LCC编译器的预处理

上面已经介绍了C编译器的目标,其实在实现这个目标之前,是经历了很多阶段处理的,其中第一个阶段的处理,就是预处理。预处理的任务是做什么呢?在LCC里预处理主要是把所有包含的头文件和源程序生成一个中间文件...

LCC编译器的源程序分析(59)代码生成的源程序注释

下面详细地注释了gen.c的源程序,这样看起来就比较容易理解,希望对你有所帮助。#001 #include "c.h"#002 #003 static char rcsid[] = "$Id: gen...

DataList嵌套问题 如何删除内层子DataList的记录

WebForm1        http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"> ...

[龙讯增刊1号]龙芯哪里来

LSLSLSLSLSLSLSLSLSLSLSLSLSLSLSLS                   ...

从2008高考人数想到的软件人才

今天无意间看到下面这段新闻报道:“2007年全国高考报名人数首次突破1000万,达到1010万;2008年,这个纪录将被再次刷新。在今天召开的2008年全国普通高校招生考试工作电视电话会议上,教育部部...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)