当前搜索:

LCC编译器的源程序分析(47)计算需要使用栈大小

计算栈的大小,是通过后端接口的代码来完成计算的。栈的大小,主要就是局部变量、临时变量、调用参数和返回值等使用的字节大小,如果变量可以放到寄存器,就不需加到栈的大小里。上面已经看了下面的代码:#044          case Blockbeg: #045                {#046                      Symbol *p = cp->u.block...
阅读(3044) 评论(0)

LCC编译器的源程序分析(46)计算需要使用栈大小

从目标代码里,可以看到下面一行:#009 sub esp, 16在这行里是保留栈的大小,值为16。但16个字节是怎么样计算出来的呢?下面就来分析LCC的代码,看它是怎么样计算的。它是在函数gencode里进行计算的,它的代码如下:#001 void gencode(Symbol caller[], Symbol callee[]) #002 {#003     Code cp;...
阅读(2833) 评论(2)

LCC编译器的源程序分析(45)函数代码入口和出口的代码生成

由于C语言可以动态地分配局部变量,因此它的运行环境都是基于栈式的分配来实现的,所以在函数的入口就会生成一段分配栈的代码,如下:#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第2...
阅读(3519) 评论(0)

LCC编译器的源程序分析(44)函数名称的代码生成

当把所有的源程序生成DAG表示后,就进入了编译器的最后处理阶段,LCC是把DAG生成汇编的目标代码。在这一阶段,编译器为源程序定义和使用的变量选择存储单元,并把中间指令翻译成完成相同任务的汇编代码指令序列。在代码生成里,需要处理的问题是存储管理、指令选择、寄存器分配、计算次序等等。在第一节里就已经看到了汇编代码生成,函数的名称生成如下:#001 [global $main]那么在LCC...
阅读(2799) 评论(0)

LCC编译器的源程序分析(43)赋值表达式的有向无环图

由于INDIR树与ADDRL树的类型相同,所以已经转换为ADDRL树,直接对ADDRL树进行进访问了,下面就是在函数listnodes里处理赋值表达式的ADDRL树,它的代码如下:#412  case ADDRL: #413         { #414               assert(tlab == 0 && flab == 0);#415               ...
阅读(2662) 评论(0)

LCC编译器的源程序分析(42)赋值表达式的有向无环图

 上一次说到赋值表达式转换为有向无环图的函数listnodes,下面继续来分析这个函数代码。当赋值树处理时,就运行下面的分支来处理:#256  case ASGN: #257         { #258               assert(tlab == 0 && flab == 0);#259               if (tp->kids[0]->op =...
阅读(2700) 评论(0)

LCC编译器的源程序分析(41)赋值表达式的有向无环图

前面已经介绍怎么样把赋值表达式变换到树的中间表示,接着下来编译器要做的事情就是怎么样把树变换成有向无环图。也许你会问为什么要把树变换成有向无环图,而不是直接生成最终代码呢?其实,学习过数据结构就很清楚有向无环图的应用,编译器里就是利用有向无环图的特性来进行局部代码优化的,最主要的优化就是删除公共表达式。下面就来分析LCC从树到有向无环图的实现代码。上面函数dcllocal里调用转换函数如下:...
阅读(3701) 评论(2)

LCC编译器的源程序分析(40)赋值表达式树

前面分析了表达式的语法,也分析了语句的语法,但它们最终的目的就是生成合适的中间表示,在LCC里是采用树作为中间表示的。现在就来分析语句生成什么样的树表示,下面的语句是来自例子里,如下:int nTest1 = 1;这个语句是声明了一个局部变量nTest1,并且给nTest1赋值为1。LCC编译器要把它变换到分析树的表示,这样才利于后面的分析和使用。它的分析树如下:  左子树=右子树...
阅读(2873) 评论(0)

在VC2005里使用STLPORT

听说STLPORT的性能不错,心动不如行动,立即就上网下载STLPORT下来使用,先到下面的网址下载源程序:http://nchc.dl.sourceforge.net/sourceforge/stlport/STLport-5.1.3.zip这个压缩包不是很大,才1.6M,很轻松地就下载完成了。接着下来就是解压,比如我解压到目录:E:/software/LIB/STLport-5...
阅读(3667) 评论(1)

LCC编译器的源程序分析(39)goto语句

在现代设计的程序里,很少再用到goto语句了。虽然使用goto语句是比较高效,但它使程序也会得非常难懂,非常难维护,比较容易出错,所以很少使用goto语句的。goto语句为无条件跳转语句,它的一般形式为: goto 标号;在LCC里的是用下面的代码来处理:#001 case GOTO:    #002         walk(NULL, 0, 0);#003         ...
阅读(2622) 评论(0)

LCC编译器的源程序分析(38)return语句

在实现中,程序其实就是处理数据,然后输出处理过的结果,在C语句里最直接的方式就是函数的返回值。比如求两个数据的最大值,就可以通过函数返回值来返回最大值。而函数的返回值是通过函数中的return语句获得的。return语句后面是一个表达式,需要调用表达式函数来处理。下面来分析LCC里的代码:#001 case RETURN: #002         {#003           ...
阅读(2870) 评论(0)

LCC编译器的源程序分析(37)default语句

default语句是使用在switch语句的复合语句里,它是所有其它分支不能处理时的分支处理。在LCC里是如下处理的: #001 case DEFAULT: #002         if (swp == NULL)#003               error("illegal default label/n");#004         else if (swp->def...
阅读(2548) 评论(0)

LCC编译器的源程序分析(36)case语句

case语句是使用在switch语句之中,它实现了选择一个分支执行。当表达式的值与case后面的常量表达式的值相等时,就执行此case语句后面的语句。LCC处理这个语句的代码如下:#001 case CASE:     #002         {#003               int lab = genlabel(1);#004               if (swp ...
阅读(2680) 评论(0)

LCC编译器的源程序分析(35)switch语句

switch语句是多分支选择语句,主要方便多个选择的情况使用,当然也可以使用if语句来实现,但嵌套的if语句过多会使用程序的可读性降低。switch(表达式){ case 常量表达式1:       语句1; case 常量表达式2:       语句2; … case 常量表达式n:       语句n; default:       语句n+1}...
阅读(2854) 评论(0)

LCC编译器的源程序分析(34)continue语句

continue语句的作用是跳过循环体中后面尚未执行的语句,接着进行下一次是否执行循环的判断。比如下面的例子: while(表达式1) {       …       if(表达式2) continue;       … }下面就来仔细地分析LCC里处理continue语句的源程序:#001 case CONTINUE: #002         walk(...
阅读(3097) 评论(0)
29条 共2页1 2 下一页 尾页
    个人资料
    • 访问:5902261次
    • 积分:76279
    • 等级:
    • 排名:第22名
    • 原创:1625篇
    • 转载:61篇
    • 译文:11篇
    • 评论:2102条
    文章存档