name | args | desc |
---|---|---|
OP_JMP | A sBx | pc+=sBx; if (A) close all upvalues >= R(A) + 1 |
JMP執行一個跳轉,sBx表示跳轉的偏移位置,被加到當前指向下一指令的指令指針上。如果sBx為0,表示沒有任何跳轉;1表示跳過下一個指令;-1表示重新執行當前指令。如果A>0,表示需要關閉所有從寄存器A+1開始的所有local變量。實際執行的關閉操作只對upvalue有效。
JMP最直接的使用就是對應lua5.2新加入的goto語句:
- ::l::
- goto l;
- 1 [1] JMP 0 -1 ; to 1
- 2 [2] RETURN 0 1
- do
- local a;
- function f() a = 1 end
- end
- main <test.lua:0,0> (5 instructions at 0x80048eb0)
- 0+ params, 2 slots, 1 upvalue, 1 local, 1 constant, 1 function
- 1 [2] LOADNIL 0 0
- 2 [3] CLOSURE 1 0 ; 0x80049128
- 3 [3] SETTABUP 0 -1 1 ; _ENV "f"
- 4 [3] JMP 1 0 ; to 5
- 5 [4] RETURN 0 1
- constants (1) for 0x80048eb0:
- 1 "f"
- locals (1) for 0x80048eb0:
- 0 a 2 5
- upvalues (1) for 0x80048eb0:
- 0 _ENV 1 0
- function <test.lua:3,3> (3 instructions at 0x80049128)
- 0 params, 2 slots, 1 upvalue, 0 locals, 1 constant, 0 functions
- 1 [3] LOADK 0 -1 ; 1
- 2 [3] SETUPVAL 0 0 ; a
- 3 [3] RETURN 0 1
- constants (1) for 0x80049128:
- 1 1
- locals (0) for 0x80049128:
- upvalues (1) for 0x80049128:
- 0 a 1 0
JMP其他的功能就是配合邏輯和關係指令(統稱為test指令),實現程序的條件跳轉。每個test輯指令與JMP搭配,都會將接下來生成的指令分為兩個集合,滿足條件的為true集合,否則為false集合。當test條件滿足時,指令指針回+1,跳過後面緊跟的JMP指令,然後繼續執行。當test條件不滿足時,則繼續執行,也就到了JMP,然後跳轉到分支代碼。
name | args | desc |
---|---|---|
OP_EQ | ABC | if ((RK(B) == RK(C)) ~= A) then pc++ |
OP_LT | ABC | if ((RK(B) < RK(C)) ~= A) then pc++ |
OP_LE | ABC | if ((RK(B) <= RK(C)) ~= A) then pc++ |
關係指令對RK(B)和RK(C)進行比較,然後將比較結果與A指定的boolean值進行比較,來決定最終的boolean值。A在這里為每個關係指令提供了兩種比較目標,滿足和不滿足。比如OP_LT何以用來實現“<”和“>”。
- local a,b,c;
- a = b < c;
- 1 [1] LOADNIL 0 2
- 2 [2] LT 1 1 2
- 3 [2] JMP 0 1 ; to 5
- 4 [2] LOADBOOL 0 0 1
- 5 [2] LOADBOOL 0 1 0
- 6 [2] RETURN 0 1
name | args | desc |
---|---|---|
OP_TEST | AC | if not (R(A) <=> C) then pc++ |
OP_TESTSET | ABC | if (R(B) <=> C) then R(A) := R(B) else pc++ |
邏輯指令用於實現and和or邏輯運算符,或者在條件語句中判斷一個寄存器。TESTSET將寄存器B轉化成一個boolean值,然後與C進行比較。如果不相等,跳過後面的JMP指令。否則將寄存器B的值賦給寄存器A,然後繼續執行。TEST是TESTSET的簡化版,不需要賦值操作。
- local a,b,c;
- a = b and c;
- 1 [1] LOADNIL 0 2
- 2 [2] TESTSET 0 1 0
- 3 [2] JMP 0 1 ; to 5
- 4 [2] MOVE 0 2
- 5 [2] RETURN 0 1
上面的代碼等價於
- if b then
- a = c
- else
- a = b
- end
No comments:
Post a Comment