LuaJit分析(四)luajit 64位与32位字节码区别

对一个lua脚本文件,只有一条语句 print(“hello”, “world”),分别生成字节码文件如下:

32位字节码:

1b4c 4a02 022d 0200 0300 0300 0536 0000 0027 0101 0027 0202 0042 0003 014b 0001

000a 776f 726c 640a 6865 6c6c 6f0a 7072 696e 7400

64位字节码:

1b4c 4a02 0a2d 0200 0400 0300 0536 0000 0027 0201 0027 0302 0042 0003 014b 0001

000a 776f 726c 640a 6865 6c6c 6f0a 7072 696e 7400

 上述红色字体表示的是有区别的地方,第一处是文件头部的flags标志,32位的是02,64位的是0a,有flags字段的定义:

#define BCDUMP_F_BE   0x01
#define BCDUMP_F_STRIP    0x02
#define BCDUMP_F_FFI    0x04
#define BCDUMP_F_FR2    0x08

可知,64位的BCDUMP_F_FR2为1,即可以从这个字段判断是32位还是64位字节码文件

第二处是原型头部的frame大小,32位是3,64位是4,即64位栈帧大小要比32位多1

第三处和第四处是指令的内容,栈帧变大后,同时指令中的索引也同时增大,对32位字节码反汇编内容如下:

0001    GGET     0   0      ; "print"
0002    KSTR     1   1      ; "hello"
0003    KSTR     2   2      ; "world"
0004    CALL     0   1   3
0005    RET0     0   1

64位字节码反汇编内容如下:

0001    GGET     0   0      ; "print"
0002    KSTR     2   1      ; "hello"
0003    KSTR     3   2      ; "world"
0004    CALL     0   1   3
0005    RET0     0   1

KSTR指令用于获取常量的内容,KSTR 2 1即将函数原型中常量索引为1的常量放入到栈中相对BASE偏移为2的内存处。Luajit中解释器的实现在对应的vm_<arch>.dasc文件中,这里以X86为例,即vm_x86.dasc文件,其中对KSTOR解释执行的代码如下:

case BC_KSTR:
    |  ins_AND    // RA = dst, RD = str const (~)
    |  mov RD, [KBASE+RD*4]
    |  mov dword [BASE+RA*8+4], LJ_TSTR
    |  mov [BASE+RA*8], RD
    |  ins_next
break;

这里 RA为指令中的目标位置,即相对于即相对于BASE的位置 ,RD为常量的索引,先根据KBASE获取的常量的地址,再保存到RD中,接着把LJ_TSTR标志(字符串类型)和常量地址保存在了RA指定位置的栈中,然后执行下一条指令,可以看出栈中的每一个元素占8字节存储

接着看x64下的BC_KSTR解释:<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值