4.1 使用 Pcode 模拟器运行 Pcode
Pcode 模拟器是本人用 python 编写的用来运行 Pcode 的程序,下载地址在这里:pysim.py。
下面先让我们来运行一个简单的例子:
- ; int a, b;
- var a, b
- ; a = 1 + 2;
- push 1
- push 2
- add
- pop a
- ; b = a * 2
- push a
- push 2
- mul
- pop b
- ; print("a = %d, b = %d", a, b);
- push a
- push b
- print "a = %d, b = %d"
将以上命令存为 pcode_1.asm 文件,同时将 pysim.py 下载下来,把两个文件放到终端的当前目录,在终端输入:
- $ python pysim.py pcode_1.asm
输出:
- a = 3, b = 6
下面再来单步执行以上 Pcode 代码,先将终端最大化(为达到好的显示效果,建议使用 gnome-terminal 或 Mate-terminal ),再输入:
- $ python pysim.py pcode_1.asm -d
之后,终端上就出现了下图所示的内容:图4.1 Pcode模拟器单步执行界面1
上图中,上半部分一共有 3 列,分别是 Code、 Stack 和 Bind var,分别表示代码、栈和绑定的变量。各列之间都用 “|” 隔开了。其中 Code 列下是我们编写的 Pcode 代码,注释已经全部都过滤掉了,在第一行的 “var a, b” 的最前面有一个 “->” ,这就是指令指针(eip),它永远指向下一个将要执行的指令。 Code 列中最后一行 “exit 0” 是模拟器自动增加的,这样程序运行到这里时会自动退出。
图中的下半部分有一行 ”Terminal”, 此行下面的区域用来表示 Pcode 虚拟机中的终端,print 和 readint 命令的输入和输出内容都将显示在此行以下。
最底下一行是 “press enter to step, -r to run.” ,表示若按回车,则模拟器会执行一步,按 “-r” 再回车,则模拟器会一直运行到程序结束。
现在,让我们敲一下回车,可以看到模拟器运行了一步,终端上的内容变成了下面的:图4.2 Pcode 模拟器单步执行界面2
可以看到 “var a, b” 执行之后,指令指针(eip)指向了第二行,栈上的第一行和第二行的内容由空内容都变成了 “/”,而 “Bind var” 那一列上多了 “a” 和 “b” ,且 “b” 的后面有一个 “<-” , 这是用来指示栈顶的。这些变化和上一章中对 var 命令的描述是完全一致的。
接下来,让我们一步一步的运行代码,细心观察每一步运行后代码区、栈区以及终端区的变化,可以看到随着命令的运行,指令指针一直在向下移动,栈顶指针则随 push / pop /print 等命令不断的上、下移动,终端区则在 print 命令运行后出现了 “a = 3, b = 6” ,程序在 “exit 0” 后退出,整个过程如下:图4.3 Pcode 模拟器单步执行过程
好了,Pcode 模拟器的使用就介绍完了,建议读者利用上一章中介绍的 Pcode 命令编写一些简单的程序,再使用 Pcode 单步运行一遍,以加深对这些命令及虚拟机的记忆。
下面来介绍 Pcode 的最后两组命令。