用一个ax_ch和bx_ch来记录上次的对应寄存器发生改变时,改变后的寄存器内部的值,然后每次要进行下次变更时先和这两个变量进行比较看是否可以继承上次的寄存器的值,若可以则不进行变更。这样可以很好的对这种情况进行优化。
3) 相关函数
void getasm(char *s,int os_flag):目标代码生成
四 测试数据和测试结果
此次测试一共使用了7组测试样例(in1.txt, in2.txt, in3.txt, in4.txt, in5.txt, in6.txt, in7.txt),分别来测试本编译器的词法分析器,语法分析器,以及四元组和汇编代码的生成。
1) In1.txt
In1.txt中的内容为: int a,b; int main() {
a=b-c; }
显然c是一个未定义的变量,运行编译器后应该显示c是未知变量,实际运行结果如图:
结果与预期相同。 2) In2.txt
In2.txt中的内容为: int a,b; {
a=a+b; }
显然没有int main(),不符合语法结构,应该输出语法错误,实际运行结果如图:
提示词法分析成功而语法分析出错,与预期结果相同。 3) In3.txt
In3.txt中的内容为: int a,b; int main() {
if (a
If语句后没有跟语句块,不符合语法结构,应该输出语法错误,实际运行结果如图:
提示词法分析成功而语法分析出错,与预期结果相同。 4) In4.txt
In4.txt中的内容为: int a,b,c; int main() { a=0; a=b; a=b+c; b=a/b;
b=a*a*a-c/a; }
词法与文法均正确应当生成对应的中间代码和目标代码,结果如下图:
对应生成了in4.o文件和in4.asm文件分别保存中间代码和目标代码。 in4.o中内容为:
可以看出中间代码的翻译完全正确,证明编译器对于赋值语句的翻译完全正确。 In4.asm中内容为: .386
DATA SEGMENT USE16 DW a,b,c,k0,k1,k2 DATA ENDS
STACK SEGMENT USE16 STACK DB 200 DUP(0) STACK ENDS
CODE SEGMENT USE16
ASSUME DS:DATA,SS:STACK,CS:CODE START:
MOV AX,DATA MOVA DS,AX MOV AX,0 MOV a,AX MOV AX,b MOV a,AX MOV AX,b MOV BX,c ADD AX,BX MOV k0,AX MOV AX,k0 MOV a,AX MOV AX,a CWD
MOV BX,b IDIV BX MOV k0,AX MOV AX,k0 MOV b,AX MOV AX,a MOV BX,a IMUL AX,BX MOV k1,AX MOV AX,k1 MOV BX,a IMUL AX,BX MOV k1,AX MOV AX,c CWD
MOV BX,a IDIV BX MOV k2,AX
MOV AX,k1 MOV BX,k2 SUB AX,BX MOV k0,AX MOV AX,k0 MOV b,AX CODE ENDS
END START
可以看出在没有开启汇编代码的优化开关时代码很冗长,在开启优化开关后的结果如下:
.386
DATA SEGMENT USE16 DW a,b,c,k0,k1,k2 DATA ENDS
STACK SEGMENT USE16 STACK DB 200 DUP(0) STACK ENDS
CODE SEGMENT USE16
ASSUME DS:DATA,SS:STACK,CS:CODE START:
MOV AX,DATA MOVA DS,AX MOV AX,0 MOV a,AX MOV AX,b MOV a,AX MOV BX,c ADD AX,BX MOV a,AX CWD
MOV BX,b IDIV BX MOV b,AX MOV AX,a MOV BX,a IMUL AX,BX IMUL AX,BX
相关推荐: