Pcode生成
P-code 语言是一种栈式机的语言。此类栈式机没有累加器和通用寄存器,有一个栈式存储器,有四个控制寄存器(指令寄存器 I,指令地址寄存器 P,栈顶寄存器 T和基址寄存器 B),算术逻辑运算都在栈顶进行。
Pcode的指令格式为:
F :操作码
L :层次差 (标识符引用层减去定义层)
A :不同的指令含义不同
对于不同的Pcode指令,各指令含义如下:
指令 | 具体含义 |
---|---|
LIT 0, a | 取常量a放到数据栈栈顶 |
OPR 0, a | 执行运算,a表示执行何种运算(+ - * /) |
LOD l, a | 取变量放到数据栈栈顶(相对地址为a,层次差为l) |
STO l, a | 将数据栈栈顶内容存入变量(相对地址为a,层次差为l) |
CAL l, a | 调用过程(入口指令地址为a,层次差为l) |
INT 0, a | 数据栈栈顶指针增加a |
JMP 0, a | 无条件转移到指令地址a |
JPC 0, a | 条件转移到指令地址a |
OPR 0 0 | 过程调用结束后,返回调用点并退栈 |
OPR 0 1 | 栈顶元素取反 |
OPR 0 2 | 次栈顶与栈顶相加,退两个栈元素,结果值进栈 |
OPR 0 3 | 次栈顶减去栈顶,退两个栈元素,结果值进栈 |
OPR 0 4 | 次栈顶乘以栈顶,退两个栈元素,结果值进栈 |
OPR 0 5 | 次栈顶除以栈顶,退两个栈元素,结果值进栈 |
OPR 0 6 | 栈顶元素的奇偶判断,结果值在栈顶 |
OPR 0 7 | |
OPR 0 8 | 次栈顶与栈顶是否相等,退两个栈元素,结果值进栈 |
OPR 0 9 | 次栈顶与栈顶是否不等,退两个栈元素,结果值进栈 |
OPR 0 10 | 次栈顶是否小于栈顶,退两个栈元素,结果值进栈 |
OPR 0 11 | 次栈顶是否大于等于栈顶,退两个栈元素,结果值进栈 |
OPR 0 12 | 次栈顶是否大于栈顶,退两个栈元素,结果值进栈 |
OPR 0 13 | 次栈顶是否小于等于栈顶,退两个栈元素,结果值进栈 |
OPR 0 14 | 栈顶值输出至屏幕 |
OPR 0 15 | 屏幕输出换行 |
OPR 0 16 | 从命令行读入一个输入置于栈顶 |
根据Pcode指令的相关含义,在语法分析的同时填入Pcode。
地址回填
在Pcode生成中,地址回填是最难也是最重要的部分。对于不同的代码,我们采取不同的地址回填策略。
- if-then语句的目标代码生成模式
if <condition> then <statement>
[if]
<condition>
JPC addr1
<statement>
addr1:
- If-then-else语句的目标代码生成模式:
if <condition> then <statement>[else]
[if]
<condition>
JPC addr1
<statement>
JMP addr2
addr1: [else]
<statement>
addr2
- while-do语句的目标代码生成模式:
while <condition> do <statement>
[while]
addr2: <condition>
JPC addr3
<statement>
JPC addr2
addr3:
- repeat-until语句的目标代码生成模式:
repeat <statement> until <condition>
[repeat]
addr4: <statement>
[until]
<condition>
JPC addr4