简单C编译器精品.ppt
文本预览下载声明
活动记录中的存储分配 int f(){ //0,1,2号单元存放控制信息 int a = 100+200; // a 占3号单元 int b = 300 + 400 +a; //b占4号单元 } 翻译后所得四元式序列: Init 4 100 0 //100存放于临时单元4中,3号已分给a Init 5 200 0 //200存放于临时单元5中 Add 4 5 4 //两个临时变量相加,5号单元可释放 Mov 3 4 0 //4号单元内容送给a, 4号单元可释放 Init 5 300 0 //b分配4号单元,300存于临时单元5中 Init 6 400 0 // 400存于临时单元6中 Add 5 6 5 //临时单元6可释放 Add 5 3 5 //临时单元5加a,结果存于临时单元5中 Mov 4 5 0 //临时单元5内容送到b中,临时单元5可释放 栈式存储分配所引起的问题 int * dangle(){ int j = 20; return j; } void main(){ int * q = dangle(); printf(The location which q points to is :); printf(%d .\n,*q); } //编译会通过吗? //存在问题吗?如果错误应如何改进? 中间代码的生成 如何由源程序得到四元式序列? 1. 应从表达式的翻译着手(C把非0当为真,0当为假) (要注意的是短路运算的翻译) 2. 在1的基础上翻译if while 等语句并不难 3. 另一个难点就是调用函数时如何传递参数,如何取回返回值 表达式的翻译 1.表达式的语法图 (和标准C的略有不同, 如“尚未支持逗号表达式” ) 2. 由表达式的语法图写程序(expression.cpp), 用“与项”为例 ExprNode andTerm(){ ExprNode left = relationTerm(); while(token == AND){ getToken(); changeArithToCondition(left); backpatch(left.truelist,csIndex); ExprNode right = relationTerm(); changeArithToCondition(right); left.truelist = right.truelist; left.falselist = mergeList(left.falselist,right.falselist); } return left; } 3. 尚未解决的问题: 除了红色部分,其他语句是做什么用的? (用于处理短路运算) 表达式的翻译 3. typedef struct { // truelist和falselist用于处理短路运算 //它们都为-1时,ExprNode对象代表的是四则算术运算的结果 int truelist; //真出口链 int falselist; //假出口链 int address; //存放表达式值的地址 //若为负数,则存放全局变量的地址 //若为正数,则为局部变量的相对地址 bool isTemp; //是否为临时变量 }ExprNode; // ExprNode结构体存放运算数、或者运算结果的相关信息 四则运算表达式的翻译 加法的翻译 int main(){ int a = 300, b = 400,c; c = a + b; } Init 4 300 0 //临时单元4存放300, 3号单元给a Mov 3 4 0 //临时单元4的内容复制到3号单元 Init 5 400 0 //临时单元4用完就释放,因为b要占内存,此时把4号单元分配给b,5号单元用于存放临时变量 Mov 4 5 0 //把5号单元内容复制到4号单元 Add 3 4 6 //把5号单元分配给c,所以a+b的值存到一个临时变量中,临时变量占据6号单元 Mov 5 6 0 //把6号单元的内容复制到5号单元 (实际上,可以把300等立即数存于指令中,如80X86的指令 mov eax, 300 ,而不必在运行时显式地把立即数300存于一个临时变量中,这里为简单起 见,规定参与四则运算的运算数都要占一个内存单元) 四则运算表达式的翻译 乘法、除法、取余运算的翻译和加减速法的翻译类似 只是通过gen(…)函数生成指令是略有不同。 加法与乘法的优先级关系已经在语法图中体现。 短路运算的翻译 布尔表达式实际上可
显示全部