lua5.1位元組碼檔案分析

lua5.1位元組碼檔案分析

http://www.doc88.com/p-2853755460794.html
其中對lua5.1位元組碼已做出詳細介紹,我這裡就不重複了,只講解一個位元組碼分析的例子

概要

這裡寫圖片描述

這裡寫圖片描述

lua原始檔

sample.lua

local a = 0; 
local c = 1.1
b = "stringType"
d = false
e = {}
f ={1,2,3}
function HaveParameter(x,y)
end
function NoParameter()
local function NoParameter1()
local m=4
end 
function NoParameter2()
local m=5
end  
return 
end
for i = 1, 10 do 
a = a   2
end
for k,v in pairs(f) do
print(k)
end

編譯後的lua檔案

luac.out

這裡寫圖片描述

閱讀注意,大小有關的指令從後往前閱讀(小端) 比如 01000000代表的是0x00000001

Pos   Hex Data           Description or Code
----------------------------------------------------------------------
0000                     ** source chunk: sample.lua
** global header start **
0000  1B4C7561           header signature: "\27Lua"
0004  51                 version (major:minor hex digits)
0005  00                 format (0=official)
0006  01                 endianness (1=little endian)
0007  04                 size of int (bytes)
0008  04                 size of size_t (bytes)
0009  04                 size of Instruction (bytes)
000A  08                 size of number (bytes)
000B  00                 integral (1=integral)
* number type: double
* x86 standard (32-bit, little endian, double
** global header end **
000C                     ** function [0] definition (level 1)
** start of function **
000C  0B000000           string size (11)
0010  73616D706C652E6C   "sample.l"
0018  756100             "ua\0"
source name: sample.lua
001B  00000000           line defined (0)
001F  00000000           last line defined (0)
0023  00                 nups (0)
0024  00                 numparams (0)
0025  02                 is_vararg (2)
0026  09                 maxstacksize (9)
* code:
0027  22000000           sizecode (34)
002B  01000000           [01] loadk      0   0        ; 0
002F  41400000           [02] loadk      1   1        ; 1.1
0033  81C00000           [03] loadk      2   3        ; "stringType"
0037  87800000           [04] setglobal  2   2        ; b
003B  82000000           [05] loadbool   2   0   0    ; false
003F  87000100           [06] setglobal  2   4        ; d
0043  8A000000           [07] newtable   2   0   0    ; array=0, hash=
0047  87400100           [08] setglobal  2   5        ; e
004B  8A008001           [09] newtable   2   3   0    ; array=3, hash=
004F  C1C00100           [10] loadk      3   7        ; 1
0053  01010200           [11] loadk      4   8        ; 2
0057  41410200           [12] loadk      5   9        ; 3
005B  A2408001           [13] setlist    2   3   1    ; index 1 to 3
005F  87800100           [14] setglobal  2   6        ; f
0063  A4000000           [15] closure    2   0        ; 0 upvalues
0067  87800200           [16] setglobal  2   10       ; HaveParameter
006B  A4400000           [17] closure    2   1        ; 0 upvalues
006F  87C00200           [18] setglobal  2   11       ; NoParameter
0073  81C00100           [19] loadk      2   7        ; 1
0077  C1000300           [20] loadk      3   12       ; 10
007B  01C10100           [21] loadk      4   7        ; 1
007F  A0000080           [22] forprep    2   1        ; to [24]
0083  0C004200           [23] add        0   0   264  ; 2
0087  9F40FF7F           [24] forloop    2   -2       ; to [23] if loo
008B  85400300           [25] getglobal  2   13       ; pairs
008F  C5800100           [26] getglobal  3   6        ; f
0093  9C000101           [27] call       2   2   4
0097  16800080           [28] jmp        3            ; to [32]
009B  C5810300           [29] getglobal  7   14       ; print
009F  00028002           [30] move       8   5
00A3  DC410001           [31] call       7   2   1
00A7  A1800000           [32] tforloop   2       2    ; to [34] if exi
00AB  1680FE7F           [33] jmp        -5           ; to [29]
00AF  1E008000           [34] return     0   1
* constants:
00B3  0F000000           sizek (15)
00B7  03                 const type 3
00B8  0000000000000000   const [0]: (0)
00C0  03                 const type 3
00C1  9A9999999999F13F   const [1]: (1.1)
00C9  04                 const type 4
00CA  02000000           string size (2)
00CE  6200               "b\0"
const [2]: "b"
00D0  04                 const type 4
00D1  0B000000           string size (11)
00D5  737472696E675479   "stringTy"
00DD  706500             "pe\0"
const [3]: "stringType"
00E0  04                 const type 4
00E1  02000000           string size (2)
00E5  6400               "d\0"
const [4]: "d"
00E7  04                 const type 4
00E8  02000000           string size (2)
00EC  6500               "e\0"
const [5]: "e"
00EE  04                 const type 4
00EF  02000000           string size (2)
00F3  6600               "f\0"
const [6]: "f"
00F5  03                 const type 3
00F6  000000000000F03F   const [7]: (1)
00FE  03                 const type 3
00FF  0000000000000040   const [8]: (2)
0107  03                 const type 3
0108  0000000000000840   const [9]: (3)
0110  04                 const type 4
0111  0E000000           string size (14)
0115  4861766550617261   "HavePara"
011D  6D6574657200       "meter\0"
const [10]: "HaveParameter"
0123  04                 const type 4
0124  0C000000           string size (12)
0128  4E6F506172616D65   "NoParame"
0130  74657200           "ter\0"
const [11]: "NoParameter"
0134  03                 const type 3
0135  0000000000002440   const [12]: (10)
013D  04                 const type 4
013E  06000000           string size (6)
0142  706169727300       "pairs\0"
const [13]: "pairs"
0148  04                 const type 4
0149  06000000           string size (6)
014D  7072696E7400       "print\0"
const [14]: "print"
* functions:
0153  02000000           sizep (2)
0157                     ** function [0] definition (level 2)
** start of function **
0157  00000000           string size (0)
source name: (none)
015B  08000000           line defined (8)
015F  0A000000           last line defined (10)
0163  00                 nups (0)
0164  02                 numparams (2)
0165  00                 is_vararg (0)
0166  02                 maxstacksize (2)
* code:
0167  01000000           sizecode (1)
016B  1E008000           [1] return     0   1
* constants:
016F  00000000           sizek (0)
* functions:
0173  00000000           sizep (0)
* lines:
0177  01000000           sizelineinfo (1)
[pc] (line)
017B  0A000000           [1] (10)
* locals:
017F  02000000           sizelocvars (2)
0183  02000000           string size (2)
0187  7800               "x\0"
local [0]: x
0189  00000000             startpc (0)
018D  00000000             endpc   (0)
0191  02000000           string size (2)
0195  7900               "y\0"
local [1]: y
0197  00000000             startpc (0)
019B  00000000             endpc   (0)
* upvalues:
019F  00000000           sizeupvalues (0)
** end of function **
01A3                     ** function [1] definition (level 2)
** start of function **
01A3  00000000           string size (0)
source name: (none)
01A7  0C000000           line defined (12)
01AB  14000000           last line defined (20)
01AF  00                 nups (0)
01B0  00                 numparams (0)
01B1  00                 is_vararg (0)
01B2  02                 maxstacksize (2)
* code:
01B3  05000000           sizecode (5)
01B7  24000000           [1] closure    0   0        ; 0 upvalues
01BB  64400000           [2] closure    1   1        ; 0 upvalues
01BF  47000000           [3] setglobal  1   0        ; NoParameter2
01C3  1E008000           [4] return     0   1
01C7  1E008000           [5] return     0   1
* constants:
01CB  01000000           sizek (1)
01CF  04                 const type 4
01D0  0D000000           string size (13)
01D4  4E6F506172616D65   "NoParame"
01DC  7465723200         "ter2\0"
const [0]: "NoParameter2"
* functions:
01E1  02000000           sizep (2)
01E5                     ** function [0] definition (level 3)
** start of function **
01E5  00000000           string size (0)
source name: (none)
01E9  0D000000           line defined (13)
01ED  0F000000           last line defined (15)
01F1  00                 nups (0)
01F2  00                 numparams (0)
01F3  00                 is_vararg (0)
01F4  02                 maxstacksize (2)
* code:
01F5  02000000           sizecode (2)
01F9  01000000           [1] loadk      0   0        ; 4
01FD  1E008000           [2] return     0   1
* constants:
0201  01000000           sizek (1)
0205  03                 const type 3
0206  0000000000001040   const [0]: (4)
* functions:
020E  00000000           sizep (0)
* lines:
0212  02000000           sizelineinfo (2)
[pc] (line)
0216  0E000000           [1] (14)
021A  0F000000           [2] (15)
* locals:
021E  01000000           sizelocvars (1)
0222  02000000           string size (2)
0226  6D00               "m\0"
local [0]: m
0228  01000000             startpc (1)
022C  01000000             endpc   (1)
* upvalues:
0230  00000000           sizeupvalues (0)
** end of function **
0234                     ** function [1] definition (level 3)
** start of function **
0234  00000000           string size (0)
source name: (none)
0238  10000000           line defined (16)
023C  12000000           last line defined (18)
0240  00                 nups (0)
0241  00                 numparams (0)
0242  00                 is_vararg (0)
0243  02                 maxstacksize (2)
* code:
0244  02000000           sizecode (2)
0248  01000000           [1] loadk      0   0        ; 5
024C  1E008000           [2] return     0   1
* constants:
0250  01000000           sizek (1)
0254  03                 const type 3
0255  0000000000001440   const [0]: (5)
* functions:
025D  00000000           sizep (0)
* lines:
0261  02000000           sizelineinfo (2)
[pc] (line)
0265  11000000           [1] (17)
0269  12000000           [2] (18)
* locals:
026D  01000000           sizelocvars (1)
0271  02000000           string size (2)
0275  6D00               "m\0"
local [0]: m
0277  01000000             startpc (1)
027B  01000000             endpc   (1)
* upvalues:
027F  00000000           sizeupvalues (0)
** end of function **
* lines:
0283  05000000           sizelineinfo (5)
[pc] (line)
0287  0F000000           [1] (15)
028B  12000000           [2] (18)
028F  10000000           [3] (16)
0293  13000000           [4] (19)
0297  14000000           [5] (20)
* locals:
029B  01000000           sizelocvars (1)
029F  0D000000           string size (13)
02A3  4E6F506172616D65   "NoParame"
02AB  7465723100         "ter1\0"
local [0]: NoParameter1
02B0  01000000             startpc (1)
02B4  04000000             endpc   (4)
* upvalues:
02B8  00000000           sizeupvalues (0)
** end of function **
* lines:
02BC  22000000           sizelineinfo (34)
[pc] (line)
02C0  01000000           [01] (1)
02C4  02000000           [02] (2)
02C8  03000000           [03] (3)
02CC  03000000           [04] (3)
02D0  04000000           [05] (4)
02D4  04000000           [06] (4)
02D8  05000000           [07] (5)
02DC  05000000           [08] (5)
02E0  06000000           [09] (6)
02E4  06000000           [10] (6)
02E8  06000000           [11] (6)
02EC  06000000           [12] (6)
02F0  06000000           [13] (6)
02F4  06000000           [14] (6)
02F8  0A000000           [15] (10)
02FC  08000000           [16] (8)
0300  14000000           [17] (20)
0304  0C000000           [18] (12)
0308  16000000           [19] (22)
030C  16000000           [20] (22)
0310  16000000           [21] (22)
0314  16000000           [22] (22)
0318  17000000           [23] (23)
031C  16000000           [24] (22)
0320  1A000000           [25] (26)
0324  1A000000           [26] (26)
0328  1A000000           [27] (26)
032C  1A000000           [28] (26)
0330  1B000000           [29] (27)
0334  1B000000           [30] (27)
0338  1B000000           [31] (27)
033C  1A000000           [32] (26)
0340  1B000000           [33] (27)
0344  1C000000           [34] (28)
* locals:
0348  0B000000           sizelocvars (11)
034C  02000000           string size (2)
0350  6100               "a\0"
local [0]: a
0352  01000000             startpc (1)
0356  21000000             endpc   (33)
035A  02000000           string size (2)
035E  6300               "c\0"
local [1]: c
0360  02000000             startpc (2)
0364  21000000             endpc   (33)
0368  0C000000           string size (12)
036C  28666F7220696E64   "(for ind"
0374  65782900           "ex)\0"
local [2]: (for index)
0378  15000000             startpc (21)
037C  18000000             endpc   (24)
0380  0C000000           string size (12)
0384  28666F72206C696D   "(for lim"
038C  69742900           "it)\0"
local [3]: (for limit)
0390  15000000             startpc (21)
0394  18000000             endpc   (24)
0398  0B000000           string size (11)
039C  28666F7220737465   "(for ste"
03A4  702900             "p)\0"
local [4]: (for step)
03A7  15000000             startpc (21)
03AB  18000000             endpc   (24)
03AF  02000000           string size (2)
03B3  6900               "i\0"
local [5]: i
03B5  16000000             startpc (22)
03B9  17000000             endpc   (23)
03BD  10000000           string size (16)
03C1  28666F722067656E   "(for gen"
03C9  657261746F722900   "erator)\0"
local [6]: (for generator)
03D1  1B000000             startpc (27)
03D5  21000000             endpc   (33)
03D9  0C000000           string size (12)
03DD  28666F7220737461   "(for sta"
03E5  74652900           "te)\0"
local [7]: (for state)
03E9  1B000000             startpc (27)
03ED  21000000             endpc   (33)
03F1  0E000000           string size (14)
03F5  28666F7220636F6E   "(for con"
03FD  74726F6C2900       "trol)\0"
local [8]: (for control)
0403  1B000000             startpc (27)
0407  21000000             endpc   (33)
040B  02000000           string size (2)
040F  6B00               "k\0"
local [9]: k
0411  1C000000             startpc (28)
0415  1F000000             endpc   (31)
0419  02000000           string size (2)
041D  7600               "v\0"
local [10]: v
041F  1C000000             startpc (28)
0423  1F000000             endpc   (31)
* upvalues:
0427  00000000           sizeupvalues (0)
** end of function **
042B                     ** end of chunk **

提供一個把32位指令轉換為位元組碼函式


extern "C"
{
#include "lauxlib.h"  
#include "lualib.h"  
#include "lua.h"
#include "lopcodes.h"
}
#include "stdlib.h"
static void PrintInstruction(Instruction i)
{
OpCode o = GET_OPCODE(i);
int a = GETARG_A(i);
int b = GETARG_B(i);
int c = GETARG_C(i);
int bx = GETARG_Bx(i);
int sbx = GETARG_sBx(i);
//輸出操作碼對應的名字
printf("%-9s\t", luaP_opnames[o]);
switch (getOpMode(o))
{
//操作碼對應的基本指令有3種,enum OpMode {iABC, iABx, iAsBx}; 
//操作屬性 操作暫存器還是常量還是無  enum OpArgMask {OpArgN,  OpArgU,  OpArgR, OpArgK   };
case iABC:
//3個運算元 
printf("%d", a);
//常量的話去掉最高位取負減1,用負數來區分暫存器和常量
if (getBMode(o) != OpArgN) printf(" %d", ISK(b) ? (-1 - INDEXK(b)) : b);
if (getCMode(o) != OpArgN) printf(" %d", ISK(c) ? (-1 - INDEXK(c)) : c);
break;
case iABx:
//2個運算元
//常量就直接取負減1,用負數來區分暫存器和常量
if (getBMode(o) == OpArgK) printf("%d %d", a, -1 - bx); else printf("%d %d", a, bx);
break;
case iAsBx:
//帶符號的2個運算元,或者只有一個,還有一個運算元可能不用的
if (o == OP_JMP) printf("%d", sbx); else printf("%d %d", a, sbx);
break;
default:
break;
}
printf("\n");
}
//#define BITRK     (1 << (8))
/* test whether value is a constant */
/* this bit 1 means constant (0 means register) */
#define ISK(x)      ((x) & BITRK)
int main(int argc, char* argv[])
{
//比如LOADK 0 -1,這裡生成的和前面LOADK 0 0 不一樣是因為表達方式不一樣,負數來區分常量表還是登錄檔,易於閱讀
//保持和luac -l -l sample.lua 生成的指令格式一致
Instruction i = 0x00000001;
PrintInstruction(i);
return 0;
}

其它閱讀筆記,主要參考lopcodes.h ,lopcodes.c,print.c

#define BITRK       (1 << (8))
/* test whether value is a constant */
/* this bit 1 means constant (0 means register) */
#define ISK(x)      ((x) & BITRK)
1代表常量,最高位為1,常量的話去掉這位,實際8位,暫存器最大255
#define INDEXK(r)  ((int)(r) & ~BITRK)

1代表常量,最高位為1,常量的話去掉這位,實際8位,暫存器最大255
#define INDEXK(r) ((int)(r) & ~BITRK)

總結:

lua中的常量是直接儲存在檔案中的,比如字元,數字(整數和浮點數),數字是採用浮點數編碼
指令長度為32位,包含操作碼和運算元
每個結尾指令後面都會預設新增return 0 1
lua5.2的位元組碼檔案有變化,由於參考資料較少,先用lua5.1做個基礎
執行過程主要可參考lcode.c,生成位元組碼lparser.c解析位元組碼,lvm.c執行位元組碼

附錄

浮點數計算方式:http://blog.csdn.net/chenyujing1234/article/details/7683635