// Author: simon // Author: ynwdlxm@163.com // Date: 2024/4/13 22:53 // Desc: 操作码 每条指令占4 个字节(32 比特),其中 6 比特用于操作码(Opcode),26 比特用于操作数(Operand) // * iABC 模式指令可以携带 A、B、C 三个操作数,分别占用 8、9、9 个比特 // * iABx 模式指令可以携带 A 和 Bx 两个操作数,分别占用 8 和 18 个比特 // * iAsBx 模式的指令可以携带 A 和 sBx 两个操作数,分别占用 8 和 18 个比特 // * iAx 模式的指令中携带一个操作数,占用全部 26 比特 // * 在 四种模式中,只用 iAsBx 模式下的 sBx 操作数会被解释成有符号整数,其他情况下操作数均被解释成无符号整数 package vm // op MODE const ( IABC = iota IABx IAsBx IAx ) // Lua 5.3 共定义了 47 条指令,按照作用, // 可大致分为 常量加载指令、运算符相关指令、循环和跳转指令、函数调用相关指令、表操作指令以及 Upvalue 操作指令 const ( MOVE = iota LOADK LOADKX LOADBOOL LOADNIL GETUPVAL GETTABUP GETTABLE SETTABUP SETUPVAL SETTABLE NEWTABLE SELF ADD SUB MUL MOD POW DIV IDIV BAND BOR BXOR SHL SHR UNM BNOT NOT LEN CONCAT JMP EQ LT LE TEST TESTSET CALL TALLCALL RETURN FORLOOP FORPREP TFORCALL TFORLOOP SETLIST CLOSURE VARARG EXTRAARG ) // 操作数 const ( OpArgN = iota // 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 ) type opcode struct { testFlag byte // operator is a test (next instruction must be a jump) setAFlag byte // instruction set register A argBMode byte // B arg mode argCMode byte // C arg mode opMode byte // op mode name string } var opcodes = []opcode{ /*testFlag setAFlag argBMode argCMode opMode name */ {0, 1, OpArgR, OpArgN, IABC, "MOVE "}, {0, 1, OpArgK, OpArgN, IABx, "LOADK "}, {0, 1, OpArgN, OpArgN, IABx, "LOADKX "}, {0, 1, OpArgU, OpArgU, IABC, "LOADBOOL "}, {0, 1, OpArgU, OpArgN, IABC, "LOADNIl "}, {0, 1, OpArgU, OpArgN, IABC, "GETUPVAL "}, {0, 1, OpArgU, OpArgK, IABC, "GETTABUP "}, {0, 1, OpArgR, OpArgK, IABC, "GETTABLE "}, {0, 0, OpArgK, OpArgK, IABC, "GETTABUP "}, {0, 0, OpArgU, OpArgN, IABC, "SETUPVAL "}, {0, 0, OpArgK, OpArgK, IABC, "SETTABLE "}, {0, 1, OpArgU, OpArgU, IABC, "NEWTABLE "}, {0, 1, OpArgR, OpArgK, IABC, "SELF "}, {0, 1, OpArgK, OpArgK, IABC, "ADD "}, {0, 1, OpArgK, OpArgK, IABC, "SUB "}, {0, 1, OpArgK, OpArgK, IABC, "MUL "}, {0, 1, OpArgK, OpArgK, IABC, "MOD "}, {0, 1, OpArgK, OpArgK, IABC, "POW "}, {0, 1, OpArgK, OpArgK, IABC, "DIV "}, {0, 1, OpArgK, OpArgK, IABC, "IDIV "}, {0, 1, OpArgK, OpArgK, IABC, "BAND "}, {0, 1, OpArgK, OpArgK, IABC, "BOR "}, {0, 1, OpArgK, OpArgK, IABC, "BXOR "}, {0, 1, OpArgK, OpArgK, IABC, "SHL "}, {0, 1, OpArgK, OpArgK, IABC, "SHR "}, {0, 1, OpArgR, OpArgN, IABC, "UNM "}, {0, 1, OpArgR, OpArgN, IABC, "BNOT "}, {0, 1, OpArgR, OpArgN, IABC, "NOT "}, {0, 1, OpArgR, OpArgN, IABC, "LEN "}, {0, 1, OpArgR, OpArgR, IABC, "CONCAT "}, {0, 0, OpArgR, OpArgN, IAsBx, "JMP "}, {1, 0, OpArgK, OpArgK, IABC, "EQ "}, {1, 0, OpArgK, OpArgK, IABC, "LT "}, {1, 0, OpArgK, OpArgK, IABC, "LE "}, {1, 0, OpArgN, OpArgU, IABC, "TEST "}, {1, 1, OpArgR, OpArgU, IABC, "TESTSET "}, {0, 1, OpArgU, OpArgU, IABC, "CALL "}, {0, 1, OpArgU, OpArgU, IABC, "TALLCALL "}, {0, 0, OpArgU, OpArgN, IABC, "RETURN "}, {0, 1, OpArgR, OpArgN, IAsBx, "FORLOOP "}, {0, 1, OpArgR, OpArgN, IAsBx, "FORREEP "}, {0, 0, OpArgU, OpArgU, IABC, "SETLIST "}, {0, 1, OpArgU, OpArgN, IABx, "CLOSURE "}, {0, 1, OpArgU, OpArgN, IABC, "VARARG "}, {0, 0, OpArgU, OpArgU, IAx, "EXTRAARG "}, }