上次已经说明了怎么样选择合适的指令,现在就来介绍生成最终的代码,如下:
#010mov dword [ebp + -12], 1
其实生成上面的代码是通过后面的语句来构造出来的,它的过程如下:
ASGNI4(ADDRLP4(nTest1), CNSTI4(1))
stmt: ASGNI4(addr,rc) / mov dword %0, %1
addr: base / [%0]
base: ADDRLP4 / ebp + %a
rc: con / %0
con: CNSTI4 / %a
在中间表示里,通过指令模式匹配到语句(stmt: ASGNI4(addr,rc) / mov dword %0, %1),然后通过树的两子节点来选择addr和rc的生成。addr又通过模式匹配选择到addr: base / [%0],接着再进一下就选择base: ADDRLP4 / ebp + %a,这样就可以生成[ebp + -12]代码了。右节点选择rc: con / %0,接着选择con: CNSTI4 / %a,这样就可以生成下面的代码:
mov dword [ebp + %a], %a
最后通过格式化把这个变量分配的栈位置-12输出,再把常量的值1输出,就生成最终的代码:
mov dword [ebp + -12], 1
这样就完成了语句(int nTest1 = 1;)编译过程。
在函数emitcode里调用函数emitasm,代码如下:
#001unsigned emitasm(Node p, int nt) {
#002int rulenum;
#003short *nts;
#004char *fmt;
#005Node kids[10];
#006
#007p = reuse(p, nt);
#008rulenum = getrule(p, nt);
#009nts = IR->x._nts[rulenum];
#010fmt = IR->x._templates[rulenum];
#011assert(fmt);
#012if (IR->x._isinstruction[rulenum] && p->x.emitted)
#013 print("%s", p->syms[RX]->x.name);
#014else if (*fmt == '#')
#015 (*IR->x.emit2)(p);
#016else {
#017 if (*fmt == '?') {
#018 fmt++;
#019 assert(p->kids[0]);
#020 if (p->syms[RX] == p->x.kids[0]->syms[RX])
#021 while (*fmt++ != '/n')
#022 ;
#023 }
#024 for ((*IR->x._kids)(p, rulenum, kids); *fmt; fmt++)
#025 if (*fmt != '%')
#026 (void)putchar(*fmt);
#027 else if (*++fmt == 'F')
#028 print("%d", framesize);
#029 else if (*fmt >= '0' && *fmt <= '9')
#030 emitasm(kids[*fmt - '0'], nts[*fmt - '0']);
#031 else if (*fmt >= 'a' && *fmt < 'a' + NELEMS(p->syms))
#032 fputs(p->syms[*fmt - 'a']->x.name, stdout);
#033 else
#034 (void)putchar(*fmt);
#035}
#036return 0;
#037}
第7行处理可重用的节点。
第8行就是从模式匹配里的两个值来找到相应的语句编号rulenum。
第9行和第10行获取语句的模板。
第24行到第35行就是按照mov dword %0, %1来格式化输出代码到文件里。
这样就完成了代码的生成工作。
分享到:
相关推荐
简单的C编译器源代码分析,便于理解编译器原理。
LCC编译器的源程序分析。包含LCC词法分析,语法分析,语义分析,中间代码生成等
纯粹C语言编译器LCC完整源代码,还有C99参考手册
《可变目标C编译器—设计与实现》(A Retargetable C Compiler: Design and Implementation)中c编译器源代码4.2版,可成功编译,对编译器有兴趣的可看看。
包含lcc编译器的源码、可变目标C编译器—设计与实现pdf
lcc编译器 传上来是为了自己使用,公司只能上有限的网,呵呵
lcc刚开始只是针对C语言的一个子集的编译器,所以其最初的设计目标非常有限,仅定位于针对一般的编译器实现、特别是代码生成的教学的需要。
《可变目标C编译器-设计与实现》一书讲的lcc的源代码。 官方网站: http://www.cs.princeton.edu/software/lcc/
lcc 编译器 c c++,非常好用的C语言编译器,绝对可用,放心下载
LCC编译器源码分析
编译器LCC源代码语法分析词法分析语法制导中间代码
lcc编译器(64位+32位),做实验用。
LCC编译器的源程序分析,学习编译原理的好资料
请搜索LCC编译器的源程序分析 从哪里下载资源分少的doc版本.thx
你可以用LCC-Win32开发32位的控制台程序、Windows常规程序、动态连接库(DLL) 以及静态连接库(LIB)。LCC编译器支持标准的ANSI C,同时支持 C语言的扩展。通过下载相关工具,LCC-Win32还提供对Eiffel、Fortran语言的...
LCC编译器源码,是一款C语言编译器,可以使用VC编译, 配合nasm可以开发Windows控制台应用程序
lcc 源代码 分析 源程序 pdf 第20-41篇lcc 源代码 分析 源程序 pdf 第20-41篇
可变目标c编译器的源代码,写的很是不错,自己想做编译器的朋友可以参考一下
完整的LCC编译器源码。LCC是一种开源的C编译器,可用作商业用途。《可变目标C编译器-设计与实现》一书是对它的注释与说明。