Lua虚拟机之字节码(三)

来源:互联网 发布:电脑视频剪辑小软件 编辑:程序博客网 时间:2024/05/21 22:33

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




图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_OP)&MASK1(SIZE_OP,POS_OP))))#define getarg(i,pos,size)(cast(int, ((i)>>pos) & MASK1(size,0)))#define setarg(i,v,pos,size)((i) = (((i)&MASK0(size,pos)) | \                ((cast(Instruction, v)<<pos)&MASK1(size,pos))))#define GETARG_A(i)getarg(i, POS_A, SIZE_A)#define SETARG_A(i,v)setarg(i, v, POS_A, SIZE_A)#define GETARG_B(i)getarg(i, POS_B, SIZE_B)#define SETARG_B(i,v)setarg(i, v, POS_B, SIZE_B)#define GETARG_C(i)getarg(i, POS_C, SIZE_C)#define SETARG_C(i,v)setarg(i, v, POS_C, SIZE_C)#define GETARG_Bx(i)getarg(i, POS_Bx, SIZE_Bx)#define SETARG_Bx(i,v)setarg(i, v, POS_Bx, SIZE_Bx)#define GETARG_Ax(i)getarg(i, POS_Ax, SIZE_Ax)#define SETARG_Ax(i,v)setarg(i, v, POS_Ax, SIZE_Ax)#define GETARG_sBx(i)(GETARG_Bx(i)-MAXARG_sBx)#define SETARG_sBx(i,b)SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))#define CREATE_ABC(o,a,b,c)((cast(Instruction, o)<<POS_OP) \| (cast(Instruction, a)<<POS_A) \| (cast(Instruction, b)<<POS_B) \| (cast(Instruction, c)<<POS_C))#define CREATE_ABx(o,a,bc)((cast(Instruction, o)<<POS_OP) \| (cast(Instruction, a)<<POS_A) \| (cast(Instruction, bc)<<POS_Bx))#define CREATE_Ax(o,a)((cast(Instruction, o)<<POS_OP) \| (cast(Instruction, a)<<POS_Ax))

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



0 0
原创粉丝点击