Lua虚拟机之字节码(三)

       Lua的字节码在意义上等价于cpu的指令码,但lua本身并没有那么多强大复杂的指令,只用了6个位来表示操作码,这表示lua最多只有64个操作码(实际使用到的还没有这么多),一个字节码由四字节组成,这些个opcode又可进一步分成四大类,分别是iABC,iABx,iAsBx,iAx,这里i代表opcode,A,B,C分别代表参数,s代表有符号参数。



Lua虚拟机之字节码(三)_第1张图片

图1 iABC




图2 iABx




图3 iAsBx




图4 iAx


      上图中1,2,3,4分别代表了字节码的四种格式,对于各种形式的操作码,其不同位置的参数又可能会有特殊的含义,对于每个参数,或者没被使用,或者被使用,或者代表一个寄存器,或者代表一个常量,如下

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 */
};
      对于某个具体的操作码的各参数的意义是定义在luaP_opmodes数组中,但对于外部来说,可以不用直接操作此表以得到各参数的意义,lopcodes.h中提供了许多关于字节码操作的宏,这其中就有关于opmodes数组的

#define getOpMode(m)	(cast(enum OpMode, luaP_opmodes[m] & 3))
#define getBMode(m)	(cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
#define getCMode(m)	(cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
#define testAMode(m)	(luaP_opmodes[m] & (1 << 6))
#define testTMode(m)	(luaP_opmodes[m] & (1 << 7))

     

     关于字节码操作的,lopcodes.h中又定义了一系列的宏来帮助你操作节字码中的各个位。

#define GET_OPCODE(i)	(cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
#define SET_OPCODE(i,o)	((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
		((cast(Instruction, o)<>pos) & MASK1(size,0)))
#define setarg(i,v,pos,size)	((i) = (((i)&MASK0(size,pos)) | \
                ((cast(Instruction, v)<

     对每个字节码感兴趣的,可以参考lopcodes.h中的OpCode的定义,这是一个enum,而对字节码进行解释执行,则是在lvm.c中的luaV_execute中。



你可能感兴趣的:(lua)