Lua5.3 虚拟机指令分析(二)赋值指令

本文深入分析Lua5.3虚拟机的赋值指令,包括OP_MOVE、OP_LOADBOOL、OP_LOADNIL、OP_LOADK系列、OP_GETUPVAL、OP_SETUPVAL、OP_GETTABUP、OP_SETTABUP等,探讨了它们在处理局部变量、常量和不在寄存器中的数据(如upvalue和table中的值)时的作用。
摘要由CSDN通过智能技术生成

Lua5.3 虚拟机指令分析(二)赋值指令

Lua VM 是基于寄存器结构实现的,也就是说,每段 Lua  chunk 代码都被翻译为一组对256 个寄存器的操作指令。这有点类似于我们为Lua编写 C 扩展。
C 函数通常是从 lua_State 中取出参数逐个记录在 C 的局部变量中,然后利用C 代码直接对这些值进行操作。

可以类比 把寄存器类比于 Lua 的寄存器。它们的确有相似之处, C 中的局部变量处于C 堆栈上,而Lua 的寄存器则处于 Lua 的数据栈中。

给Lua 局部变量赋值的过程,是由 OP_MOVE 、 OP_LOADK 、 OP_LOADKX  、 OP_LOADBOOL、  OP_LOADNIL、 OP_GETUPVAL、 OP_SETUPVAL 这组操作码完成的。

值得来源有三处:

第一:其它寄存器,即局部变量。OP_MOVE 可以完成这个工作

OP_MOVE A B R(A) := R(B)

OP_MOVE 用来将寄存器B中的值拷贝到寄存器A中。
由于Lua是register based vm,大部分的指令都是直接对寄存器进行操作,而不需要对数据进行压栈和弹栈,所以需要OP_MOVE 指令的地方并不多。
最直接的使用之处就是将一个local变量复制给另一个local变量时:

TTcs-Mac-mini:OpCode ttc$ cat tOP_MOVE.lua 
local a
local b = a
TTcs-Mac-mini:OpCode ttc$ ./luac -l -l tOP_MOVE.lua

main <tOP_MOVE.lua:0,0> (3 instructions at 0x7f905ac039b0)
0+ params, 2 slots, 1 upvalue, 2 locals, 0 constants, 0 functions
    1   [1] LOADNIL     (iABC) [A]0 [ISK]0[B]0[ISK]0
    2   [2] MOVE        (iABC) [A]1 [ISK]0[B]0[ISK]0
    3   [2] RETURN      (iABC) [A]0 [ISK]0[B]1[ISK]0
constants (0) for 0x7f905ac039b0:
locals (2) for 0x7f905ac039b0:
    0   a(name)      2(startpc)     4(endpc)
    1   b(name)      3(startpc)     4(endpc)
upvalues (1) for 0x7f905ac039b0:
    0    _ENV(name)      1(instack)      0(idx)
TTcs-Mac-mini:OpCode ttc$ 

在编译过程中,Lua会将每个local变量都分配到一个指定的寄存器中。在运行期,lua使用local变量所对应的寄存器id来操作local变量,而local变量的名字除了提供debug信息外,没有其他作用。

在这里a被分配给register 0,b被分配给register 1。MOVE表示将a(register 0)的值赋给b(register 1)。其他使用的地方基本都是对寄存器的位置有特殊要求的地方,比如函数参数的传递等等。

第二: 常量,nil 和 bool 类型的数据比较短,可以通过指令直接加载(不需要先加载常量表到寄存器)。

OP_LOADBOOL A B C R(A) := (Bool)B; if (C) pc++

LOADBOOL 将 B 所表示的 boolean 值装载到寄存器 A 中。B 使用 0 和 1 分别代表 false 和 true。C 也表示一个boolean值,如果C为1,就跳过下一个指令。

TTcs-Mac-mini:OpCode ttc$ cat tOP_LOADBOOL.lua 
local a = true


TTcs-Mac-mini:OpCode ttc$ ./luac -l -l tOP_LOADBOOL.lua

main <tOP_LOADBOOL.lua:0,0> (2 instructions at 0x7ff1754039d0)
0+ params, 2 slots, 1 upvalue, 1 local, 0 constants, 0 functions
    1   [1] LOADBOOL    (iABC) [A]0 [ISK]0[B]1[ISK]0[C]0
    2   [1] RETURN      (iABC) [A]0 [ISK]0[B]1[ISK]0
constants (0) for 0x7ff1754039d0:
locals (1) for 0x7ff1754039d0:
    0   a(name)      2(startpc)     3(endpc)
upvalues (1) for 0x7ff1754039d0:
    0    _ENV(name)      1(instack)      0(idx)
TTcs-Mac-mini:OpCode ttc$ 


TTcs-Mac-mini:OpCode ttc$ cat tOP_LOADBOOL_2.lua 

local b = 1 < 2

TTcs-Mac-mini:OpCode ttc$ ./luac -l -l tOP_LOADBOOL_2.lua

main <tOP_LOADBOOL_2.lua:0,0> (5 instructions at 0x7fda7d4039d0)
0+ params, 2 slots, 1 upvalue, 1 local, 2 constants, 0 functions
    1   [2] LT          (iABC) [A]1 [ISK]256[B]-1[ISK]256[C]-2  ; 1 2
    2   [2] JMP         (iAsBx) [A]0 [sBx]1 ; to 4
    3   [2] LO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值