3.3 入栈及出栈命令

push / pop 命令,将元素放入栈顶,或取出栈顶元素。有以下用法:

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

“push 2” 命令运行后,常数 2 被放入栈顶,如下:

  1. ------------+----------- ------------+-----------
  2. stack | bind var stack | bind var
  3. ------------+----------- push 2 ------------+-----------
  4. ... | -------------> ... |
  5. ------------+----------- ------------+-----------
  6. ... |<- ... |
  7. ------------+----------- ------------+-----------
  8. 2 |<-
  9. ------------+-----------

“push a” 命令运行后,变量 a 的值 <5> 被放入栈顶,如下图。

  1. ------------+----------- ------------+-----------
  2. stack | bind var stack | bind var
  3. ------------+----------- ------------+-----------
  4. 5 | a 5 | a
  5. ------------+----------- push a ------------+-----------
  6. ... | -------------> ... |
  7. ------------+----------- ------------+-----------
  8. ... |<- ... |
  9. ------------+----------- ------------+-----------
  10. 5 |<-
  11. ------------+-----------

当虚拟机执行 push 命令时,若后面是一个变量名,则虚拟机会在其变量表中查找此变量名,如果查到了,且该变量的值不是空值 “/” ,则将此变量名对应的值放入栈顶,但若此时该变量尚未被赋初值(为空值 “/” ),则虚拟机将出错而终止,如果没有查找到,则虚拟机也会出错终止。

“pop” 命令运行后,栈顶向上减少一个单位,栈顶元素被丢弃,如下:

  1. ------------+----------- ------------+-----------
  2. stack | bind var stack | bind var
  3. ------------+----------- pop ------------+-----------
  4. ... | -------------> ... |
  5. ------------+----------- ------------+-----------
  6. ... | ... |<-
  7. ------------+----------- ------------+-----------
  8. ... |<-
  9. ------------+-----------

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

  1. ------------+----------- ------------+-----------
  2. stack | bind var stack | bind var
  3. ------------+----------- ------------+-----------
  4. ... | a 5 | a
  5. ------------+----------- pop a ------------+-----------
  6. ... | -------------> ... |
  7. ------------+----------- ------------+-----------
  8. ... | ... |<-
  9. ------------+----------- ------------+-----------
  10. 5 |<-
  11. ------------+-----------

当虚拟机执行 pop 命令后,若后面是一个变量名,虚拟机会在其变量表中查找此变量名,若查到了,则虚拟机会将栈顶元素取出,赋给该变量名对应的栈单元,若没查到,虚拟机会出错终止。

此处同样需要注意的是,若此时 栈顶单元 尚未被赋初值(为空值 “/” ),则虚拟机将出错而终止。总而言之,栈上未被赋初值的单元是不能被使用(读取)的,此约束对后面将要介绍的所有命令都有效,因此后面就不再重复申明此约束了。