探索Lua5.2内部实现:虚拟机指令(5)Arithmetic

以下内容转载自 https://blog.csdn.net/yuanlin2008/article/details/8494303

 

name    args    desc
OP_ADD    A B C    R(A) := RK(B) + RK(C)
OP_SUB    A B C    R(A) := RK(B) - RK(C)
OP_MUL    A B C    R(A) := RK(B) * RK(C)
OP_DIV    A B C    R(A) := RK(B) / RK(C)
OP_MOD    A B C    R(A) := RK(B) % RK(C)
OP_POW    A B C    R(A) := RK(B) ^ RK(C)
上表中的指令都是与lua本身的二元操作符一一对应的标准3地址指令。B和C两个操作数计算的结果存入A中。

local a = 1;
a = a + 1;
a = a - 1;
a = a * 1;
a = a / 1;
a = a % 1;
a = a ^ 1;
main <test.lua:0,0> (8 instructions at 0x80048eb0)
0+ params, 2 slots, 1 upvalue, 1 local, 1 constant, 0 functions
    1    [1]    LOADK        0 -1    ; 1
    2    [2]    ADD          0 0 -1    ; - 1
    3    [3]    SUB          0 0 -1    ; - 1
    4    [4]    MUL          0 0 -1    ; - 1
    5    [5]    DIV          0 0 -1    ; - 1
    6    [6]    MOD          0 0 -1
    7    [7]    POW          0 0 -1    ; - 1
    8    [7]    RETURN       0 1
constants (1) for 0x80048eb0:
    1    1
locals (1) for 0x80048eb0:
    0    a    2    9
upvalues (1) for 0x80048eb0:
    0    _ENV    1    0  
可以看到,生成的指令没有多余的操作,每个指令都对应一个完整的二元计算操作。

name    args    desc
OP_UNM    A B    R(A) := -R(B)
OP_NOT    A B    A B R(A) := not R(B)
上表中指令对应'-'和'not'一元操作符,表示将B取反或not后放入A中。

local a = 1;
local b = not a;
local c = -a;
    1    [1]    LOADK        0 -1    ; 1
    2    [2]    NOT          1 0
    3    [3]    UNM          2 0
    4    [3]    RETURN       0 1 
在编译和指令生成阶段,lua还支持所有一元和二元操作符表达式的常量表达式折叠”(const expression folding)优化。也就是如果计算操作数如果都是数字常量,可以在编译期计算出结果,就直接使用这个结果值,而不用生成计算指令。

local a = 1 + 1;
local b = not 1;
    1    [1]    LOADK        0 -1    ; 2
    2    [2]    LOADBOOL     1 0 0
    3    [2]    RETURN       0 1
从生成的结果可以看到1+1并没有生成对应的OP_ADD,而是直接把结果2赋值给了a。并且也没有为not 1生成OP_NOT指令,而是直接将false赋值给了b。
name    args    desc
OP_LEN    A B    R(A) := length of R(B)
LEN直接对应'#'操作符,返回B对象的长度,并保存到A中。

local a = #"foo";
    1    [1]    LOADK        0 -1    ; "foo"
    2    [1]    LEN          0 0
    3    [1]    RETURN       0 1 
name    args    desc
OP_CONCAT    A B C    R(A) := R(B).. ... ..R(C)
CONCAT将B和C指定范围内的字符串按顺序传接到一起,将结果存入到A。

local a = "foo1".."foo2".."foo3";
    1    [1]    LOADK        0 -1    ; "foo1"
    2    [1]    LOADK        1 -2    ; "foo2"
    3    [1]    LOADK        2 -3    ; "foo3"
    4    [1]    CONCAT       0 0 2
    5    [1]    RETURN       0 1 

--------------------- 
作者:yuanlin2008 
来源:CSDN 
原文:https://blog.csdn.net/yuanlin2008/article/details/8494303 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值