本篇文章,主要探讨一下lua中的指令系统(涉及到的文件 lopcodes.c )。
在lua中,用32位的unsigned int类型来表示一条指令操作码,32位值包含了6位的操作码和26位的指令字段两部分内容。
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 */
依据上面的枚举值,指令码目前有三种形式,即iABC,iABx,iAsBx,结构图如下:
对于指令字段A,B,C,有以下三种形式的取值来源:
/*
** R(x) - register
** Kst(x) - constant (in constant table)
** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
*/
其中,用R来表示寄存器值,Kst表示常量表,RK表示可能是常量表或者寄存器。
lua5.14中总共拥有38条指令操作码,操作码名称如下:
操作码枚举值,和上面的操作码名称一一对应,方便调用:
38条操作码对应的操作模式如下:
操作模式计算公式如下:
#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
用8位值来表示
/*
** 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 A
** bit 7: operator is a test
*/
依次从低位到高位表示如下含义:
第0,1位表示操作码模式,取值于 enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
第2,3位表示参数C模式,取值于 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表示未用参数,OpArgU表示可用参数,OpArgR表示寄存器参数或者跳转指令,OpArgK表示常量表或者寄存器参数,
第4,5位表示参数B模式,取值于C取值范围一致。
第6位表示寄存器参数A是否被设置。
第7位表示是否测试操作。