This article mainly discusses the Lua Command System (the file lopcodes. c involved ).
In Lua, a 32-bit unsigned int type is used to represent a command operation code. The 32-bit value contains a 6-bit operation code and a 26-bit command field.
All instructions have an opcode in the first 6 bits.
Instructions can have the following fields:
'A': 8 bits
'B': 9 bits
'C': 9 bits
'Bx ': 18 bits (' B 'and 'C' together)
'Sbx': signed BX
Enum opmode {IABC, iabx, iasbx};/* Basic Instruction format */
According to the enumerated values above, there are three types of script codes: IABC, iabx, and iasbx. The structure is as follows:
For command fields a, B, c, there are three types of value sources:
/*
** R (x)-register
** Kst (x)-constant (in constant table)
** Rk (x) = If ISK (x) Then kst (indexK (x) else R (X)
*/
Here, R is used to represent the register value, kst is used to represent the constant table, and rk may be a constant table or register.
In lua5.14, there are a total of 38 command operation codes. The operation code name is as follows:
Const char * const luap_opnames [num_opcodes + 1] ={< br/> "move", <br/> "loadk", <br/> "loadbool ", <br/> "loadnil", <br/> "getupval", <br/> "getglobal", <br/> "gettable", <br/> "setglobal ", <br/> "setupval", <br/> "settable", <br/> "newtable", <br/> "self", <br/> "add ", <br/> "sub", <br/> "Mul", <br/> "Div", <br/> "Mod", <br/> "pow ", <br/> "UNM", <br/> "not", <br/> "len", <br/> "Concat", <br/> "JMP ", <br/> "EQ", <br/> "LT", <br/> "Le", <br/> "test", <br/> "testset ", <br/> "call", <br/> "tailcall", <br/> "return", <br/> "forloop", <br/> "forprep ", <br/> "tforloop", <br/> "setlist", <br/> "close", <br/> "closure", <br/> "vararg ", <br/> null <br/>}; <br/>
The enumerated value of the operation code, which corresponds to the name of the preceding operation code for convenient calling:
Typedef Enum {<br/>/* example <br/> nameargsdescription <br/> example */<br/> op_move,/* a Br (): = R (B) */<br/> op_loadk,/* A bxr (a): = kst (BX) */<br/> op_loadbool, /* a B Cr (a): = (bool) B; If (c) PC ++ */<br/> op_loadnil,/* a Br (): =...: = R (B): = nil */<br/> op_getupval,/* a Br (): = Upvalue [B] */</P> <p> op_getglobal,/* A bxr (a): = GBL [kst (BX)] */<br/> op_gettable,/* a B Cr (a): = R (B) [rk (c)] */</P> <p> op_setglobal, /* A bxgbl [kst (BX)]: = R (A) */<br/> op_setupval,/* A bupvalue [B]: = R () */<br/> op_settable,/* a B Cr (a) [rk (B)]: = rk (c) */</P> <p> op_newtable, /* a B Cr (a) :{} (size = B, c) */</P> <p> op_self,/* a B Cr (a + 1): = R (B); R (A): = R (B) [rk (c)] */</P> <p> op_add, /* a B Cr (a): = rk (B) + rk (c )* /<Br/> op_sub,/* a B Cr (a): = rk (B)-rk (c) */<br/> op_mul, /* a B Cr (a): = rk (B) * rk (c) */<br/> op_div,/* a B Cr (): = rk (B)/rk (c) */<br/> op_mod,/* a B Cr (a): = rk (B) % rk (c) */<br/> op_pow,/* a B Cr (a): = rk (B) ^ rk (c) */<br/> op_unm, /* a Br (a): =-R (B) */<br/> op_not,/* a Br (a): = Not r (B) */<br/> op_len,/* a Br (a): = length of R (B) */</P> <p> op_concat, /* a B Cr (a): = R (B )....... R (c) */</P> <p> op_jmp,/* sbxpc + = Sbx */</P> <p> op_eq,/* a B cif (rk (B) = rk (c ))~ = A) Then PC ++ */<br/> op_lt,/* a B cif (rk (B) <rk (c ))~ = A) Then PC ++ */<br/> op_le,/* a B cif (rk (B) <= rk (c ))~ = A) Then PC ++ */</P> <p> op_test,/* a CIF not (R (A) <=> C) then PC ++ */<br/> op_testset,/* a B cif (R (B) <=> C) then R (A): = R (B) else PC ++ */</P> <p> op_call,/* a B Cr (),..., R (A + C-2): = R (A) (R (A + 1 ),..., R (A + B-1) */<br/> op_tailcall,/* a B creturn R (A) (R (A + 1 ),..., R (A + B-1) */<br/> op_return,/* A breturn R (),..., R (A + B-2) (see note) */</P> <p> op_forloop,/* A sbxr (A) + = R (A + 2 ); <br/> If R (A) <? = R (A + 1) Then {PC + = sbx; R (A + 3) = R (A)} */<br/> op_forprep, /* A sbxr (a)-= R (A + 2); PC + = sbx */</P> <p> op_tforloop, /* a Cr (a + 3 ),..., R (A + 2 + C): = R (A) (R (A + 1), R (A + 2 )); <br/> If R (A + 3 )~ = Nil then R (A + 2) = R (A + 3) else PC + + + */<br/> op_setlist,/* a B Cr (a) [(C-1) * fpf + I]: = R (A + I), 1 <= I <= B */</P> <p> op_close, /* a close all variables in the stack up to (> =) R (A) */<br/> op_closure,/* A bxr (): = closure (kproto [BX], R (),..., R (A + n) */</P> <p> op_vararg/* a Br (A), R (A + 1 ),..., R (A + B-1) = vararg */<br/>} opcode; <br/>
The operation mode corresponding to 38 operation codes is as follows:
# Define opmode (T, A, B, C, M) (t) <7) | (a) <6) | (B) <4) | (c) <2) | (m )) </P> <p> const lu_byte luap_opmodes [num_opcodes] ={< br/>/* t a B C mode opcode */<br/> opmode (0, 1, opargr, opargn, IABC)/* op_move */<br/>, opmode (0, 1, opargk, opargn, iabx)/* op_loadk */<br/>, opmode (0, 1, opargu, opargu, IABC)/* op_loadbool */<br/>, opmode (0, 1, opargr, opargn, IABC) /* op_loadnil */<br/>, opmode (0, 1, opargu, opargn, IABC)/* op_getupval */<br/>, opmode (0, 1, opargk, opargn, iabx)/* op_getglobal */<br/>, opmode (0, 1, opargr, opargk, IABC)/* op_gettable */<br/>, opmode (0, 0, opargk, opargn, iabx)/* op_setglobal */<br/>, opmode (0, 0, opargu, opargn, IABC)/* op_setupval */<br/>, opmode (0, 0, opargk, opargk, IABC)/* op_settable */<br/>, opmode (0, 1, opargu, opargu, IABC) /* op_newtable */<br/>, opmode (0, 1, opargr, opargk, IABC)/* op_self */<br/>, opmode (0, 1, opargk, opargk, IABC)/* op_add */<br/>, opmode (0, 1, opargk, opargk, IABC)/* op_sub */<br/>, opmode (0, 1, opargk, opargk, IABC)/* op_mul */<br/>, opmode (0, 1, opargk, opargk, IABC)/* op_div */<br/>, opmode (0, 1, opargk, opargk, IABC)/* op_mod */<br/>, opmode (0, 1, opargk, opargk, IABC) /* op_pow */<br/>, opmode (0, 1, opargr, opargn, IABC)/* op_unm */<br/>, opmode (0, 1, opargr, opargn, IABC)/* op_not */<br/>, opmode (0, 1, opargr, opargn, IABC)/* op_len */<br/>, opmode (0, 1, opargr, opargr, IABC)/* op_concat */<br/>, opmode (0, 0, opargr, opargn, iasbx)/* op_jmp */<br/>, opmode (1, 0, opargk, opargk, IABC)/* op_eq */<br/>, opmode (1, 0, opargk, opargk, IABC) /* op_lt */<br/>, opmode (1, 0, opargk, opargk, IABC)/* op_le */<br/>, opmode (1, 1, opargr, opargu, IABC)/* op_test */<br/>, opmode (1, 1, opargr, opargu, IABC)/* op_testset */<br/>, opmode (0, 1, opargu, opargu, IABC)/* op_call */<br/>, opmode (0, 1, opargu, opargu, IABC)/* op_tailcall */<br/>, opmode (0, 0, opargu, opargn, IABC)/* op_return */<br/>, opmode (0, 1, opargr, opargn, iasbx) /* op_forloop */<br/>, opmode (0, 1, opargr, opargn, iasbx)/* op_forprep */<br/>, opmode (1, 0, opargn, opargu, IABC)/* op_tforloop */<br/>, opmode (0, 0, opargu, opargu, IABC)/* op_setlist */<br/>, opmode (0, 0, opargn, opargn, IABC)/* op_close */<br/>, opmode (0, 1, opargu, opargn, iabx)/* op_closure */<br/>, opmode (0, 1, opargu, opargn, IABC)/* op_vararg */<br/>}; </P> <p>
The formula for calculating the operation mode is as follows:
# Define opmode (T, A, B, C, M) (t) <7) | (a) <6) | (B) <4) | (c) <2) | (m ))
Represented by an 8-bit value
/*
** Masks for instruction properties. The format is:
** Bits 0-1: op Mode
** Bits 2-3: C Arg Mode
** Bits 4-5: B Arg Mode
** Bit 6: Instruction Set register
** Bit 7: operator is a test
*/
From low to high in turn indicates the following meanings:
The first and second bits indicate the operation code mode. Value: Enum opmode {IABC, iabx, iasbx};/* Basic Instruction format */
The second and third bits indicate the C mode parameter. The value is set to Enum opargmask {
Opargn,/* argument is not used */
Opargu,/* argument is used */
Opargr,/* argument is a register or a jump offset */
Opargk/* argument is a constant or register/constant */
};
Opargn indicates unused parameters, opargu indicates available parameters, opargr indicates register parameters or jump instructions, and opargk indicates constant table or register parameters,
The fourth and fifth digits indicate the B mode parameter. The value range is the same as that of C.
The value 6th indicates whether register parameter A is set.
The value 7th indicates whether to perform a test.