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

先从简单的目标来分析这个大规模的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函数里,定义了几个局部变量,分别第5,6,7,8行的变量。第10行作两个变量nTest1和nTest2的加法,然后赋值给变量nTest3。第11行显示变量nTest3的值,是用10进制输出显示。在第13到16行是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编译器,在这里主要介绍生成X86的NASM汇编的代码。上面的汇编代码就是NASM的汇编格式,可以使用NASM编译生成目标文件,然后再用连接程序生成可执行文件。如果不能看懂上面的NASM汇编,就需要去看NASM手册了,这个手册在网上有下载。如果想更深入理解汇编生成机器码的过程,当然也可以深入分析NASM的程序实现。

从上面的C和汇编也可以看出,汇编代码比C代码要复杂,行数也比较多,还分了数据段和代码段。所以使用C编译器是可以大大地提高生产效率的,并且更容易理解,这样就容易降低软件的成本,容易开发大规模的软件工程。

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://www.cnblogs.com/captainbed

原文地址:https://www.cnblogs.com/skiwnchh/p/10163828.html

时间: 2024-10-13 17:31:54

LCC编译器的源程序分析 1 C编译器的目标的相关文章

GCC编译器原理(一)------交叉编译器制作和GCC组件及命令

1.1 交叉编译器制作 默认安装的 GCC 编译系统所产生的代码适用于本机,即运行 GCC 的机器,但也可将 GCC 安装成能够生成其他的机器代码.安装一些必须的模块,就可产生多种目标机器代码,而且可通过命令行选择一种希望使用的代码. 1.1.1 目标机 从网站 http://gcc.gnu.org/install/specific.html 可以得到有可能的最新目标机列表.在此站点中可找到更新过的目标机列表,以及向各种目标机进行移植的最新信息.关于每种可能的目标机都有一个简短介绍,可以查找说明

自学C语言第二课——选择编译器并开始分析别人的代码

听说现在我在大学大学的同学普遍用的编译器是VC6.0,为了方便向他们请教,于是我刚开始决定选择VC6.0来学习.可是安装的过程出现种种问题,我又不想用绿色版,所以最后选择了安装极为方便的DEV-C++.我想要从分析别人的代码开始学起.同学向我推荐了一本书.然后,我就开始分析书里面的代码. 例题1: 通过百度和看我在大学的同学给我的资料,我认识到: 1.关于<stdio.h> stdio.h就是指“standardinput&output" 意思就是说标准输入输出头文件! 所以

深入研究Clang(四) Clang编译器的简单分析

作者:史宁宁(snsn1984) 首先我们确定下Clang编译器的具体内容和涵盖范围.之前在<LLVM每日谈之二十 Everything && Clang driver>中曾经提到过,Clang driver(命令行表示是clang)和Clang前端(按照具体实现来说就是Clang的那些库所实现的前端)是不同的,同时还存在一个Clang编译器(命令行表示是clang -cc1).Clang编译器不仅仅包含了Clang前端,还包括使用LLVM的哭实现的编译器的中间阶段以及后端,同

MYC编译器源码分析

前文.NET框架源码解读之MYC编译器讲了MyC编译器的架构,整个编译器是用C#语言写的,上图列出了MyC编译器编译一个C源文件的过程,编译主路径如下: 首先是入口Main函数用来解析命令行参数,读取源文件,并开始编译过程.Main函数在MyC.cs文件,而IO.cs文件主要保存读取源码文件的相关操作.下表是Main函数的源码(批注用注释的方式显示),IO.cs文件用单独的一个小节说明: public static void Main() { try { // 看源码注释,代码是99年写的,也就

SQLite3源程序分析之Lemon分析器生成工具

1.概述 Lemon是一个LALR(1)文法分析器生成工具.虽然它是SQLite作者针对SQLite写的一个分析器生成工具,但是它与bison和yacc类似,是一个可以独立于SQLite使用的开源的分析器生成工具.而且它使用与yacc(bison)不同的语法规则,可以减少编程时出现错误的机会.Lemon比yacc和bison更精致.更快,而且是可重入的,也是线程安全的——这对于支持多线程的程序是非常重要的. Lemon的主要功能就是根据上下文无关文法(CFG),生成支持该文法的分析器.程序的输入

SQLite3源程序分析

回调函数1.SQL访问数据库非常方便,只需简单的三个函数: sqlite3_open(char* szDbFileName, sqlite3 ** db) sqlite3_exec(sqlite3 *db, char* szSqlCMD, callback, 0, char **zErrMsg) sqlite3_close(sqlite3 *db) static int callback(void *NotUsed, int argc, char **argv, char **azColName

SQLite源程序分析之回叫机制

1.SQL访问数据库非常方便,只需简单的三个函数: sqlite3_open(char* szDbFileName, sqlite3 ** db) sqlite3_exec(sqlite3 *db, char* szSqlCMD, callback, 0, char **zErrMsg) sqlite3_close(sqlite3 *db) static int callback(void *NotUsed, int argc, char **argv, char **azColName) 2.

[转载] 像 IDE 一样使用 vim

原文: https://github.com/yangyangwithgnu/use_vim_as_ide 看了这篇文章要是再不会用vim就不能怪我了. 所需即所获:像 IDE 一样使用 vim [email protected]2015-02-15 13:30:59 谢谢 捐赠:支付宝 [email protected] .支付宝链接https://shenghuo.alipay.com/send/payment/[email protected] ,支付宝二维码 $_$ 二手书:书,我提高开

所需即所获:像 IDE 一样使用 vim

所需即所获:像 IDE 一样使用 vim 转载 [email protected]2015-11-08 10:05:53 谢谢 捐赠:支付宝 [email protected] .支付宝链接https://shenghuo.alipay.com/send/payment/[email protected] ,支付宝二维码 $_$ 二手书:书,我提高开发技能的重要手段之一,随着职业生涯的发展,书籍也在不断增多,对我而言,一本书最多读三遍,再往后,几乎没有什么营养吸收,这部分书对我已基本无用,但对其