E-COM-NET
首页
在线工具
Layui镜像站
SUI文档
联系我们
推荐频道
Java
PHP
C++
C
C#
Python
Ruby
go语言
Scala
Servlet
Vue
MySQL
NoSQL
Redis
CSS
Oracle
SQL Server
DB2
HBase
Http
HTML5
Spring
Ajax
Jquery
JavaScript
Json
XML
NodeJs
mybatis
Hibernate
算法
设计模式
shell
数据结构
大数据
JS
消息中间件
正则表达式
Tomcat
SQL
Nginx
Shiro
Maven
Linux
lcc
LCC
编译器的源程序分析(64)符号表的结构注释
<iframe align="top" marginwidth="0" marginheight="0" src="http://www.zealware.com/46860.html" frameborder="0" width="468" scrolling="
wapysun
·
2007-12-28 07:00
编译器
LCC
编译器的源程序分析(69)全局变量的初始化
intg_nTest=100;#003 #004 intmain(void)#005 {#006 intnTest1=1;#007 intnTest2=2;像第2行代码就是全局变量的声明和初始化在一起的,那么在
LCC
caimouse
·
2007-08-31 22:00
汇编
tree
null
编译器
代码分析
initialization
LCC
编译器的源程序分析(68)内存分配链表
LCC
采用大块内存的方法,那它分配内存也是比较特殊的,它的源程序如下:#001 //大块内存结构。
caimouse
·
2007-08-26 11:00
LCC
编译器的源程序分析(67)删除内存链表
LCC
的内存分配是使用先分配大块内存,然后再从大块内存里分配出来小块内存,这样减少调用malloc的次数,当然也就减少调用函数free释放内存的次数,以便提高
LCC
的内存管理的性能。
caimouse
·
2007-08-23 21:00
qq
null
编译器
[转载]
LCC
编译器的源程序分析(57)不同目标代码生成的接口结构
LCC
为了生成不同机器的目标代码,它提供了一个接口给后端的代码生成,以便可以只修改后端,就可以达到生成不同的机器代码。它的接口如下:#001 //后端代码生成接口,可以写生成不同的目标代码。
leibniz_zsu
·
2007-08-23 12:00
struct
String
qq
编译器
templates
[转载]
LCC
编译器的源程序分析(56)寄存器分配的属性结构
现在详细地分析寄存器分配的属性结构,它的定义如下:#001 typedefstruct{#002 Symbolvbl;//保存变量符号,而不是临时变量.#003 shortset;//寄存器类型,比如整数,或者浮点数。#004 shortnumber;//寄存器编号。#005 unsignedmask;//寄存器字节大小,比如EAX,还是AX。#006 }*Regnode;
leibniz_zsu
·
2007-08-23 12:00
数据结构
struct
编译器
X86
[转载]
LCC
编译器的源程序分析(55)最终代码的生成
上次已经说明了怎么样选择合适的指令,现在就来介绍生成最终的代码,如下:#010 movdword[ebp+-12],1其实生成上面的代码是通过后面的语句来构造出来的,它的过程如下:ASGNI4(ADDRLP4(nTest1),CNSTI4(1))stmt:ASGNI4(addr,rc)/movdword%0,%1addr:base/[%0]base:ADDRLP4/ebp+%arc:con/%0c
leibniz_zsu
·
2007-08-23 12:00
[转载]
LCC
编译器的源程序分析(54)指令模式匹配
在
LCC
编译器里,先把下面的语句翻译成中间表示,intnTest1=1;其中间表示的树如下:ASGNI4(ADDRLP4(nTest1),CNSTI4(1))然后根据上述的中间表示进行指令模式匹配。
leibniz_zsu
·
2007-08-23 12:00
c
工作
struct
null
编译器
[转载]
LCC
编译器的源程序分析(53)指令的选择
在本例子里,
LCC
是选择下面的指令生成的:#010 movdword[ebp+-12],1 现在就来分析选择指令过程的代码,先分析函数gen的代码:#001 Nodegen(Nodeforest){#002
leibniz_zsu
·
2007-08-23 12:00
struct
汇编
编译器
[转载]
LCC
编译器的源程序分析(52)寄存器溢出
下面就来分析
LCC
的寄存溢出算法。spillee是用来计算那个寄存器最好保存到内存里,然后重新使用的。
leibniz_zsu
·
2007-08-22 13:00
算法
null
input
编译器
variables
[转载]
LCC
编译器的源程序分析(51) 分配一个寄存器
分配一个寄存器的函数是ralloc,它会调用getreg函数来获取一个寄存器。下面先来分析函数ralloc的代码,如下:#001 staticvoidralloc(Nodep){#002 inti;#003 unsignedmask[2];#004 #005 mask[0]=tmask[0];#006 mask[1]=tmask[1];#007 assert(p);#008 debug
leibniz_zsu
·
2007-08-22 13:00
算法
null
编译器
templates
[转载]
LCC
编译器的源程序分析(50) 分配一个寄存器
在代码生成的函数gencode里,需要产生寄存器给临时变量使用。下面就来分析这段代码,如下:#056 caseGen:caseJump:#057 caseLabel: #058 if(prunetemps)#059 cp->u.forest=prune(cp->u.forest);#060
leibniz_zsu
·
2007-08-22 13:00
[转载]
LCC
编译器的源程序分析(7)词法分析
下面开始关键字、ID等识别,采用这种词法分析,是最高效的,由于在识别的过程里,就已经区分它是什么关键字,而不像其它的词法分析程序,需要查找才能决定是否是关键字。#074 case'i':#075 if(rcp[0]=='f'#076 &&!(map[rcp[1]]&(DIGIT|LETTER))){#077
leibniz_zsu
·
2007-08-17 13:00
[转载]
LCC
编译器的源程序分析(6)词法分析
在最开始的例子程序里,程序是由一些单词和符号组成的。其实程序就是一串长长的字符串,这些字符串是按一定的规则编写的,那么就需要检查这些单词和符号是否符合定义的规则。在C语言里,就是定义了C语法和语义。在最开始的例子里,C编译器最先进行词法分析的语句是下面这句:typedefunsignedintsize_t;那么C编译器是怎么样把上面的字符串识别出来的呢?其实词法分析就是把上面的字符串识别为下面的单
leibniz_zsu
·
2007-08-17 13:00
[转载]
LCC
编译器的源程序分析(5)行号同步与类型初始化
上面已经介绍打开文件输入,并且分析了读取到缓冲区里的代码,接着下来就是分析行号同步的处理,还有类型初始化。 先来看看生成中间文件hello.i中的源程序,在它的第1行和第2行如下:#001 #line1"hello.c"#002 #line1"include/stdio.h"#003 #004 #005 #006 #007 typedefunsignedintsize_t; 这样的源程序是怎么样被
leibniz_zsu
·
2007-08-17 13:00
[转载]
LCC
编译器的源程序分析(4)处理文件参数
上面已经介绍选择不同的目标输出的参数处理,那么接着下来,自然的事情就是处理剩下的两个参数的问题,当然
LCC
是可以处理更多其它参数的,但这里只介绍两个文件参数的处理。
leibniz_zsu
·
2007-08-17 13:00
[转载]
LCC
编译器的源程序分析(3)选择不同的目标代码接口
在
LCC
里,最重要的一个特征是可以输出不同的目标代码。比如同一个C程序,可以生成MIPS,X86等汇编代码,只需要选择不同的目标参数。
leibniz_zsu
·
2007-08-17 13:00
汇编
struct
interface
编译器
binding
X86
[转载]
LCC
编译器的源程序分析(2)
LCC
编译器的预处理
在
LCC
里预处理主要是把所有包含的头文件和源程序生成一个中间文件,并且把所有宏展开,替换为真实的值。
leibniz_zsu
·
2007-08-17 13:00
[转载]
LCC
编译器的源程序分析(1)C编译器的目标
先从简单的目标来分析这个大规模的C编译器,毕竟它的功能比较复杂,并且源程序的行数也是非常多的。因此,把简单的目标定出来,然后再分析它,这样才会有的放矢。接着再跟着编译运行的主线来分析它的源程序。下面先看一下简单的C例子,如下: #001 #include#002 #003 intmain(void)#004 {#005 intnTest1=1;#006 intnTest2=2;#007 in
leibniz_zsu
·
2007-08-17 13:00
LCC
编译器的源程序分析(66)DAG树分析例子
前面已经介绍创建分析树,下面就来详细地说明一个例子,看看到底生成什么样的分析树,C源程序如下:#005 intnTest1=1;#006 intnTest2=2;#007 intnTest3;#008 inti;#009 #010 nTest3=nTest1+nTest2; 把上面的源程序分析后,就生成下面的DAG树,如下:#2 ADDRLP4count=1nTest1#3 CNS
caimouse
·
2007-08-13 22:00
LCC
编译器的源程序分析(65)后端接口的结构注释
因为
LCC
后端可以生成不同机器结构的代码,所以需要定义后端的接口结构,当不同的模块实现这些接口时,就可以实现不同的机器代码生成。下面就是这个接口的结构定义注释。
caimouse
·
2007-08-11 19:00
LCC
编译器的源程序分析(65)后端接口的结构注释
因为
LCC
后端可以生成不同机器结构的代码,所以需要定义后端的接口结构,当不同的模块实现这些接口时,就可以实现不同的机器代码生成。下面就是这个接口的结构定义注释。
anjichan4261
·
2007-08-11 19:00
后端
前端
LCC
编译器的源程序分析(64)符号表的结构注释
符号表是用来保存每个符号信息的,因为编译器分析源程序的过程会生成很多符号的属性,后端根据这些属性来生成合适的指令和代码的格式。 #001 //符号表结构.#002 //#003 //蔡军生 2007/08/10QQ:9073204#004 //#005 structsymbol#006 {#007 char*name;//符号的名称,大多数情况是源程序的符号.#008 intscope;//符
caimouse
·
2007-08-10 21:00
struct
list
table
扩展
float
编译器
LCC
编译器的源程序分析(63)创建DAG森林的源程序
#001 //#002 voidwalk(Treetp,inttlab,intflab)#003 {#004 //创建DAG森林.#005 listnodes(tp,tlab,flab);#006 #007 //如果DAG森林生成.#008 if(forest)#009 {#010 Nodelist=forest->link;#011 forest->link
caimouse
·
2007-08-09 21:00
LCC
编译器的源程序分析(62)生成常量树节点的流程
在
LCC
里分析下面的语句:#005 intnTest1=1;就需要把1生成一个常量树节点,那么在
LCC
里用怎么样的流程来创建这个树节点的呢?
caimouse
·
2007-08-07 21:00
LCC
编译器的源程序分析(61)复合语句的代码块流程
LCC
编译器要分析下面的程序,大体流程是这样的。
caimouse
·
2007-08-03 20:00
Date
编译器
LCC
编译器的源程序分析(60)代码表的结构
在
LCC
里使用代码表来表示代码块,前端把所有代码属性放到代码表里,后端根据代码表来生成代码,它的结构如下:#001//代码表结构定义.#002//蔡军生2007/07/27#003structcode#004
anjichan4261
·
2007-07-27 23:00
c/c++
后端
前端
LCC
编译器的源程序分析(60)代码表的结构
在
LCC
里使用代码表来表示代码块,前端把所有代码属性放到代码表里,后端根据代码表来生成代码,它的结构如下:#001 //代码表结构定义.#002 //蔡军生2007/07/27#003 structcode
caimouse
·
2007-07-27 23:00
c
struct
table
null
编译器
Types
LCC
编译器的源程序分析(59)代码生成的源程序注释
下面详细地注释了gen.c的源程序,这样看起来就比较容易理解,希望对你有所帮助。#001 #include"c.h"#002 #003 staticcharrcsid[]="$Id:gen.c3552007-02-1822:08:49Zdrh$";#004 #005 #definereadsreg(p)/#006 (generic((p)->op)==INDIR&&(p)->kids[0]-
caimouse
·
2007-07-22 17:00
struct
汇编
null
编译器
templates
wildcard
LCC
编译器的源程序分析(58)后端使用的节点结构
在
LCC
编译器后端,主要使用下面的节点结构来标识代码属性。#001 #002 //节点注释的扩展,主要是代码生成使用。
caimouse
·
2007-07-21 21:00
struct
qq
扩展
编译器
wildcard
LCC
编译器的源程序分析(58)后端使用的节点结构
在
LCC
编译器后端,主要使用下面的节点结构来标识代码属性。#001#002//节点注释的扩展,主要是代码生成使用。
anjichan4261
·
2007-07-21 21:00
后端
数据结构与算法
LCC
编译器的源程序分析(57)不同目标代码生成的接口结构
LCC
为了生成不同机器的目标代码,它提供了一个接口给后端的代码生成,以便可以只修改后端,就可以达到生成不同的机器代码。它的接口如下:#001 //后端代码生成接口,可以写生成不同的目标代码。
caimouse
·
2007-07-20 21:00
String
qq
struct
编译器
templates
LCC
编译器的源程序分析(57)不同目标代码生成的接口结构
LCC
为了生成不同机器的目标代码,它提供了一个接口给后端的代码生成,以便可以只修改后端,就可以达到生成不同的机器代码。它的接口如下:#001//后端代码生成接口,可以写生成不同的目标代码。
anjichan4261
·
2007-07-20 21:00
后端
LCC
编译器的源程序分析(56)寄存器分配的属性结构
现在详细地分析寄存器分配的属性结构,它的定义如下:#001 typedefstruct{#002 Symbolvbl;//保存变量符号,而不是临时变量.#003 shortset;//寄存器类型,比如整数,或者浮点数。#004 shortnumber;//寄存器编号。#005 unsignedmask;//寄存器字节大小,比如EAX,还是AX。#006 }*Regnode;
caimouse
·
2007-07-17 22:00
数据结构
struct
编译器
X86
LCC
编译器的源程序分析(56)寄存器分配的属性结构
现在详细地分析寄存器分配的属性结构,它的定义如下:#001typedefstruct{#002Symbolvbl;//保存变量符号,而不是临时变量.#003shortset;//寄存器类型,比如整数,或者浮点数。#004shortnumber;//寄存器编号。#005unsignedmask;//寄存器字节大小,比如EAX,还是AX。#006}*Regnode;#007#008//寄存器集合类型:
anjichan4261
·
2007-07-17 22:00
数据结构与算法
LCC
编译器的源程序分析(55)最终代码的生成
上次已经说明了怎么样选择合适的指令,现在就来介绍生成最终的代码,如下:#010 movdword[ebp+-12],1其实生成上面的代码是通过后面的语句来构造出来的,它的过程如下:ASGNI4(ADDRLP4(nTest1),CNSTI4(1))stmt:ASGNI4(addr,rc)/movdword%0,%1addr:base/[%0]base:ADDRLP4/ebp+%arc:con/%0c
caimouse
·
2007-07-16 21:00
工作
编译器
templates
LCC
编译器的源程序分析(54)指令模式匹配
在
LCC
编译器里,先把下面的语句翻译成中间表示,intnTest1=1;其中间表示的树如下:ASGNI4(ADDRLP4(nTest1),CNSTI4(1))然后根据上述的中间表示进行指令模式匹配。
caimouse
·
2007-07-14 19:00
c
工作
struct
null
编译器
LCC
编译器的源程序分析(53)指令的选择
在本例子里,
LCC
是选择下面的指令生成的:#010 movdword[ebp+-12],1 现在就来分析选择指令过程的代码,先分析函数gen的代码:#001 Nodegen(Nodeforest){#002
caimouse
·
2007-07-11 19:00
struct
汇编
编译器
LCC
编译器的源程序分析(52)寄存器溢出
下面就来分析
LCC
的寄存溢出算法。spillee是用来计算那个寄存器最好保存到内存里,然后重新使用的。
caimouse
·
2007-07-09 21:00
算法
null
input
编译器
variables
LCC
编译器的源程序分析(51) 分配一个寄存器
分配一个寄存器的函数是ralloc,它会调用getreg函数来获取一个寄存器。下面先来分析函数ralloc的代码,如下:#001 staticvoidralloc(Nodep){#002 inti;#003 unsignedmask[2];#004 #005 mask[0]=tmask[0];#006 mask[1]=tmask[1];#007 assert(p);#008 debug
caimouse
·
2007-07-06 21:00
算法
null
编译器
templates
LCC
编译器的源程序分析(50) 分配一个寄存器
在代码生成的函数gencode里,需要产生寄存器给临时变量使用。下面就来分析这段代码,如下:#056 caseGen:caseJump:#057 caseLabel: #058 if(prunetemps)#059 cp->u.forest=prune(cp->u.forest);#060
caimouse
·
2007-07-04 21:00
struct
null
编译器
LCC
编译器的源程序分析(49) 寄存器分配
前面已经说到要分配寄存器,下面就来分析寄存器分配的函数askreg。#001 staticSymbolaskreg(Symbolrs,unsignedrmask[]){#002 inti;#003 #004 if(rs->x.wildcard==NULL)#005 returnaskfixedreg(rs);#006 for(i=31;i>=0;i--){#007
caimouse
·
2007-07-03 21:00
null
编译器
LCC
编译器的源程序分析(48) 寄存器分配
在
LCC
里是使用非常简单的寄存器分配算法,并且局限于森林里的临时变量的分配。
caimouse
·
2007-07-01 12:00
LCC
编译器的源程序分析(47)计算需要使用栈大小
计算栈的大小,是通过后端接口的代码来完成计算的。栈的大小,主要就是局部变量、临时变量、调用参数和返回值等使用的字节大小,如果变量可以放到寄存器,就不需加到栈的大小里。上面已经看了下面的代码:#044 caseBlockbeg:#045 {#046 Symbol*p=cp->u.block.locals;#047
caimouse
·
2007-06-28 22:00
存储
编译器
LCC
编译器的源程序分析(46)计算需要使用栈大小
下面就来分析
LCC
的代码,看它是怎么样计算的。
caimouse
·
2007-06-27 21:00
null
编译器
LCC
编译器的源程序分析(45)函数代码入口和出口的代码生成
由于C语言可以动态地分配局部变量,因此它的运行环境都是基于栈式的分配来实现的,所以在函数的入口就会生成一段分配栈的代码,如下:#002 [section.text]#003 $main:#004 pushebx#005 pushesi#006 pushedi#007 pushebp#008 movebp,esp#009 subesp,16第2行是NASM汇编的代码段开始。第3行是函数的名称,在NA
caimouse
·
2007-06-23 21:00
LCC
编译器的源程序分析(44)函数名称的代码生成
当把所有的源程序生成DAG表示后,就进入了编译器的最后处理阶段,
LCC
是把DAG生成汇编的目标代码。
caimouse
·
2007-06-22 21:00
汇编
null
存储
任务
编译器
LCC
编译器的源程序分析(43)赋值表达式的有向无环图
由于INDIR树与ADDRL树的类型相同,所以已经转换为ADDRL树,直接对ADDRL树进行进访问了,下面就是在函数listnodes里处理赋值表达式的ADDRL树,它的代码如下:#412 caseADDRL:#413 {#414 assert(tlab==0&&flab==0);#415 if(tp->u.sym->genera
caimouse
·
2007-06-21 23:00
list
null
编译器
LCC
编译器的源程序分析(42)赋值表达式的有向无环图
上一次说到赋值表达式转换为有向无环图的函数listnodes,下面继续来分析这个函数代码。当赋值树处理时,就运行下面的分支来处理:#256 caseASGN: #257 {#258 assert(tlab==0&&flab==0);#259 if(tp->kids[0]->op==FIELD)#260
caimouse
·
2007-06-20 23:00
算法
list
tree
null
编译器
LCC
编译器的源程序分析(41)赋值表达式的有向无环图
下面就来分析
LCC
从树到有向无环图的实现代码。上面函数dcllocal里调用转换函数如下:wal
caimouse
·
2007-06-19 23:00
上一页
3
4
5
6
7
8
9
10
下一页
按字母分类:
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
其他