4.1 使用 Pcode 模拟器运行 Pcode

Pcode 模拟器是本人用 python 编写的用来运行 Pcode 的程序,下载地址在这里:pysim.py

下面先让我们来运行一个简单的例子:

  1. ; int a, b;
  2. var a, b
  3.  
  4. ; a = 1 + 2;
  5. push 1
  6. push 2
  7. add
  8. pop a
  9.  
  10. ; b = a * 2
  11. push a
  12. push 2
  13. mul
  14. pop b
  15.  
  16. ; print("a = %d, b = %d", a, b);
  17. push a
  18. push b
  19. print "a = %d, b = %d"

将以上命令存为 pcode_1.asm 文件,同时将 pysim.py 下载下来,把两个文件放到终端的当前目录,在终端输入:

  1. $ python pysim.py pcode_1.asm

输出:

  1. a = 3, b = 6

下面再来单步执行以上 Pcode 代码,先将终端最大化(为达到好的显示效果,建议使用 gnome-terminalMate-terminal ),再输入:

  1. $ python pysim.py pcode_1.asm -d

之后,终端上就出现了下图所示的内容:images/p_01.png图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” 再回车,则模拟器会一直运行到程序结束。

现在,让我们敲一下回车,可以看到模拟器运行了一步,终端上的内容变成了下面的:images/p_02.png图4.2 Pcode 模拟器单步执行界面2

可以看到 “var a, b” 执行之后,指令指针(eip)指向了第二行,栈上的第一行和第二行的内容由空内容都变成了 “/”,而 “Bind var” 那一列上多了 “a” 和 “b” ,且 “b” 的后面有一个 “<-” , 这是用来指示栈顶的。这些变化和上一章中对 var 命令的描述是完全一致的。

接下来,让我们一步一步的运行代码,细心观察每一步运行后代码区、栈区以及终端区的变化,可以看到随着命令的运行,指令指针一直在向下移动,栈顶指针则随 push / pop /print 等命令不断的上、下移动,终端区则在 print 命令运行后出现了 “a = 3, b = 6” ,程序在 “exit 0” 后退出,整个过程如下:images/animation.gif图4.3 Pcode 模拟器单步执行过程

好了,Pcode 模拟器的使用就介绍完了,建议读者利用上一章中介绍的 Pcode 命令编写一些简单的程序,再使用 Pcode 单步运行一遍,以加深对这些命令及虚拟机的记忆。

下面来介绍 Pcode 的最后两组命令。