lua的字節碼
lua源碼在執行前,會被編譯為字節碼,字節碼能加快程序的加載,保存lua源碼被意外的修復。lua的字節碼只在具有相同的字長和字節順序的機器上能夠移植。
luac編譯器能將lua源碼編譯為字節碼二進制文件,其命令如:
luac a.lua
luac默認的輸出文件為luac.out,可以通過 -o 選項來指定輸出文件。
luac -o a.out a.lua
當Lua發布新版時,luac生成的二進制文件的內部格式可能改變。
字節碼文件頭
lua5.1字節碼文件頭的長度為12字節,在我的環境里(Win7 64位,VS下編譯為Win32應用)如下:
1b4c 7561 5100 0104 0404 0800
其中第1-4字節為:"\033Lua";第5字節標識lua的版本號,lua5.1為 0x51;第6字節為官方中保留,lua5.1中為 0x0;
第7字節標識字節序,little-endian為0x01,big-endian為0x00;
第8字節為sizeof(int);第9字節為sizeof(size_t);第10字節為sizeof(Instruction),Instruction為lua內的指令類型,在32位以上的機器上為unsigned int;第11字節為sizeof(lua_Number),lua_Number即為double;
第12字節是判斷lua_Number類型起否有效,一般為 0x00;
lua5.2字節碼文件頭的長度為18字節,在我的環境里(Win7 64位,VS下編譯為Win32應用)如下:
1b4c 7561 5200 0104 0404 0800 1993 0d0a 1a0a
其中第1-12字節與lua5.1意義相同,第5字節在lua5.2中為 0x52;
第13-18字節是為了捕獲字節碼的轉換錯誤而設置的,其值為 "\x19\x93\r\n\x1a\n";
PS:lua在判斷字節序時使用的方法如下:
1 void luaU_header (char* h)
2 {
3 int x=1;
4 //...
5 *h++=(char)*(char*)&x; /* endianness */
6 //...
7 }
在little-endian時,*(char*)&x值為0x01;big-endian時,*(char*)&x值為 0x00;
字節碼文件正文
lua5.1 在文件頭之后,就是正頭,它由一個個函數組成,其中第一個函數包含由文件內全部內容,引全局函數名為"@"+文件件名(包含".lua"后綴),在此文件中定義的函數都會在全局函數中以常量字符串保存;
每個函數的內容緩存如下:
源文件名的長度(包括'\0'),為sizeof(size_t)個字節長,只有全局函數有源文件名,其它內部函數其長度填0;
源文件名(包括\0),長度為長度*sizeof(char)個字節;
函數行數,全局函數的填0,長度為sizeof(int)個字節;
函數的最后一行,全局函數的填0,長度為sizeof(int)個字節;
函數的upvalues數目,長度為sizeof(char)個字節;
函數的參數個數,全局函數的填0,長度為sizeof(char)個字節;
函數的vararg個數,只有全局函數有;
函數最大的棧數目,長度為sizeof(char)個字節;
函數的指令數目,長度為sizeof(int)個字節;
函數的指令,長度為指令數目*sizeof(Instruction)個字節;
函數中常量的數目,長度為sizeof(int)個字節;
函數中的常量,長度為常量數目*(常量類似標識長度+指定常量點用的長度),常量類似標識長度為sizeof(char)個字節;
函數中的內部函數數目,長度為sizeof(int)個字節;
內部函數的定,格式同外部函數;
函數的調試信息;
文件binc.lua的內容如下:
1 local i = 6;
2 return 1;
其正文的字節碼(lua5.1編譯,不包括調試信息,前面的空白外為文件頭):
0a00 0000
4062 696e 632e 6c75 6100 0000 0000 0000
0000 0000 0202 0400 0000 0100 0000 4140
0000 5e00 0001 1e00 8000 0200 0000 0300
0000 0000 0018 4003 0000 0000 0000 f03f
0000 0000
lua5.2 的正文部分與lua5.1存在差別。其沒有源文件名的說明,別對於upvalue的處理也不一樣,lua5.2中upvalue在常量后面定義,由upvalue的數目后加上分upvalue的定義組成。
明的了字節碼的各部分組成之后,需要對其二進制數據做解析,現主要從指令、常量和upvalue部分來分析。
這部分內容留在下次繼續。
個人博客:http://lontoken.com/