3.4 数据运算命令

add / sub / mul / div / mod / cmpeq / cmpne / cmpgt / cmplt / cmpge / cmple / and / or / not / neg 命令,包括算术、比较和逻辑运算命令。对应于 TinyC 中的以下运算符:

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

注意最后一个 “ - ” 是反号的意思,应和减号区别开来。

以上命令中,除 not 和 neg 命令外,其余命令均为二元操作命令,先取出栈顶两个元素,进行运算后,再将结果放回栈顶, not 和 neg 命令则为一元操作命令,只对栈顶一个元素进行操作。所有二元操作中, 原栈顶元素是第二个操作符

“ add ” 命令运行后栈的变化如下:

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

“ sub ” 命令运行后栈的变化如下,注意, 原栈顶元素是第二个操作符 ,最后的结果是 5 - 12

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

“ cmpgt ” 命令运行后栈的变化如下,注意原栈顶元素是第二个操作符,最后的结果是 5 > 12 ,因此是 0 (非真)。

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

“ neg ” 命令运行后栈的变化如下,栈顶位置不变,栈顶元素被反号。

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

数据运算命令和入栈、出栈命令组合,即可实现简单的表达式求值。如:

  1. a = 1 + 2 * 3;
  2. b = 8 - 5;

可以翻译成以下 Pcode :

  1. push 1 ; a = 1 + 2 * 3;
  2. push 2
  3. push 3
  4. mul
  5. add
  6. pop a
  7.  
  8. push 8 ; b = 8 - 5;
  9. push 5
  10. sub
  11. pop b

注意表达式中的元素的入栈顺序为 从左向右入栈 ,这样的顺序和人的阅读顺序是一致的。