TinyC编译器2—中间代码Pcode(上)

1.Pcode、Pcode虚拟机及Pcode模拟器概述

  • Pcode 是 TinyC 编译器的中间代码
  • Pcode 虚拟机是一个用来运行 Pcode 命令的、假想的机器(一个代码区(code)、一个指令指针(eip)、一个栈(stack)、一个变量表(var_table)、一个函数表(func_table)以及一个标签表(label_table))
  • Pcode 模拟器是解释和运行 Pcode 的程序

2.变量声明命令

var 命令,声明变量,向下增长栈的空间,将新增的空间分配(绑定)给刚声明的变量,并将变量名及分配给它的地址保存到变量表中。

var a           ; 栈顶向下增长 1 个单元,将新的栈顶单元分配(绑定)给 a
var x, y, z     ; 栈顶向下增长 3 个单元,将新的栈顶单元依次分配(绑定)给 x, y, z

var 命令的背后的栈与符号表运行逻辑:

------------+-----------                   ------------+-----------
    stack   | bind var                         stack   | bind var
------------+-----------                   ------------+-----------
    ...     |                                  ...     |
------------+-----------      var a        ------------+-----------
    ...     |             ------------->       ...     |
------------+-----------                   ------------+-----------
    ...     |<-                                ...     |
------------+-----------                   ------------+-----------
                                                /      |<-   a
                                           ------------+-----------

“<-”指向栈顶元素,当用var 命令声明一个新变量后,就汇出现右图情况。出现 / 的原因是没有赋初值。注意:如果此单元在被赋初值之前被使用(读取),则虚拟机将出错终止。

3.入栈及出栈命令

push / pop 命令,将元素放入栈顶,或取出栈顶元素。

push 2   ; 将常数 2 入栈
push a   ; 将变量 a 的值入栈, a 必须已被声明、且已被赋值过
pop      ; 将栈顶向上减少一个单位
pop a    ; 取出栈顶元素,并赋给变量 a , a 必须已被声明

注意:当虚拟机执行push命令的时候

  • 如果变量表中有这个变量,并且已经被赋初值,那么这个变量以及这个初值会被放到栈顶
  • 如果变量表中有这个变量,但是没有被赋初值,那么虚拟机将报错
  • 如果变量表中没有这个变量,虚拟机将报错

pop a 命令运行后,栈顶的元素被取出,并将其值赋给了变量 a ,相当于 a = stack.pop() ,此命令是唯一一个能给 直接 给变量赋值的命令。

当执行pop命令的时候,如果后面是一个变量名,那么虚拟机就会将栈顶元素的值赋值给那个变量,同时栈顶元素也就没了。

4.数据运算命令

add / sub / mul / div / mod / cmpeq / cmpne / cmpgt / cmplt / cmpge / cmple / and / or / not / neg 

分别对应:

+, -, *, /, %, ==, !=, >, <, >=, <=, &&, ||, !, -

所有二元操作中, 原栈顶元素是第二个操作符 。

举个例子:

------------+-----------                   ------------+-----------
    stack   | bind var                         stack   | bind var
------------+-----------      sub          ------------+-----------
    ...     |             ------------->       ...     |
------------+-----------                   ------------+-----------
     5      |                                   -7     |<-
------------+-----------                   ------------+-----------
     12     |<-
------------+-----------
Pcode:
push 1           a = 1 + 2 * 3;
push 2
push 3
mul
add
pop a

理解:Pcode 的运行过程,其实相似于表达式的逆波兰表达式(后缀表达式)

5.退出命令

exit 命令,退出虚拟机的运行,并设置退出码,有以下用法:

exit 0      ; 退出码为 0
exit a      ; 退出码为 a 的值
exit ~      ; 退出码为栈顶元素的值

上面的代码中用 “ ~ ” 来代表栈顶,这将是 Pcode 中的一个约定。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值