第7章

指令集

1 序

指令集可分为两大类,真实硬件指令集和虚拟机指令集。

真实硬件指令集又分为两类:

  • CISC (复杂指令集):CISC 以 X86 系列为代表,指令系统较为复杂,硬件实现也比较复杂。
  • RISC (精简指令集):RISC 的指令系统较为精简,目的是降低硬件实现的复杂度,以 RISC-V 、ARM为代表。

虚拟机指令集可分为三种:

  • 基于栈的指令集:纯栈操作,所有的运算都基于栈,其中以 Java 字节码指令集为代表。
  • 基于寄存器的指令集:纯寄存器操作,所有的运算基于寄存器,其中以安卓的 Dalvik 字节码指令集为代表。
  • 基于栈和寄存器的指令集:混合式操作,类似于 RISC 指令集,但是又与真实硬件系统有差异。

虚拟机的指令与设计的字节码保存文件存在较强相关性,所以要真正理解虚拟机指令,还需要理解字节码文件的存储格式。

2 目录


指令集 的子部分

7.1 基于栈的指令集


基于栈的指令集参考Java的指令集。

7.2 基于寄存器的指令集


Dalvik 字节码指令集的字节码指令集不支持无符号整数运算,因此参照 Dalvik 设计了以下指令集。

基于纯寄存器的指令集,指令系统存在下列的要求:

  • 每条指令按照 16 bit 对齐。
  • 寄存器的索引位宽有 4 bit、8 bit、16 bit。
  • 最多支持 65536 个寄存器。
  • 每个寄存器 32 bit。
  • 64 bit寄存器由相邻的两个 32 bit 寄存器组合而成。
  • 指令操作码位宽为 8 bit。
  • 指令中可有子操作码,具体位宽看具体的指令格式。
  • 32 bit 寄存器内可以存储 32 bit的整数、浮点数。
  • 64 bit 寄存器内可以存储 64 bit的整数、浮点数。
  • 位宽小于 32 位的值,需要进行扩展(零扩展、符号扩展)到 32 bit。
  • 助记符中的 I 表示寄存器索引,后面的数字表示索引位宽

指令格式

总体格式:

操作码 + [ 操作子码 ] + ( 操作数 )*
  • 操作子码可选。
  • 操作数可以有多个。

寄存器位宽索引支持的寄存器数量:

位宽寄存器数量索引范围
4 bit16[ 0, 15 ]
8 bit256[ 0, 255 ]
16 bit65536[ 0, 65535 ]

空指令

文本格式: nop

助记符操作码对齐注解
格式8 bit8bit指令宽度:16 bit
nop0空操作,用于对齐

常量赋值指令

文本格式: op des, imm

助记符操作码目的寄存器立即数注解
8 bit4 bit4 bit4 bit 立即数,指令宽度:16 bit
const-w32-I4-i4desimmimm 为有符号整数,有符号扩展至 32 bit。
const-w64-I4-i4desimmimm 为有符号整数,有符号扩展至 32 bit。
const-w32-I4-u4desimmimm 为无符号整数,无符号扩展至 32 bit。
const-w64-I4-u4desimmimm 为无符号整数,无符号扩展至 32 bit。
8 bit8 bit16 bit16 bit 立即数,指令宽度:32 bit
const-w32-I8-i16desimmimm 为有符号整数,有符号扩展至 32 bit。
const-w64-I8-i16desimmimm 为有符号整数,有符号扩展至 64 bit。
const-w32-I8-u16desimmimm 为无符号整数,无符号扩展至 32 bit。
const-w64-I8-u16desimmimm 为无符号整数,无符号扩展至 64 bit。
const-w32-I8-L16desimmimm 为无符号整数。imm 存放在寄存器的低 16 bit,不改变高 16 bit。
const-w32-I8-H16desimmimm 为无符号整数。imm 存放在寄存器的高 16 bit,不改变低 16 bit。
8 bit8 bit32 bit32 bit 立即数,指令宽度:48 bit
const-w32-I8desimm原样拷贝,支持32 bit 整数和浮点。
const-w64-I8-i32desimmimm 为有符号整数,有符号扩展至 64 bit。
const-w64-I8-u32desimmimm 为无符号整数,无符号扩展至 64 bit。
8 bit8 bit64 bit64 bit 立即数,指令宽度:80 bit
const-w64-I8desimm原样拷贝,支持64 bit整数和浮点。

文本格式:op.sub des,imm

助记符操作码操作子码目的寄存器立即数注解
8 bit8 bit8 bit8 bit指令宽度:32 bit
const-w32-I8subopdesimmimm 为无符号整数

操作子码定义

助记符操作子码注解
B0imm存放在寄存器的第 1 个字节,不改变其他字节。
B1imm存放在寄存器的第 2 个字节,不改变其他字节。
B2imm存放在寄存器的第 3 个字节,不改变其他字节。
B3imm存放在寄存器的第 4 个字节,不改变其他字节。

寄存器赋值指令

文本格式:op des,src

文本格式:op des,src

助记符操作码目的寄存器源寄存器注解
8 bit4 bit4 bit指令宽度:16 bit
move-w32-I4dessrc32 位寄存器值传递
move-w64-I4dessrc64 位寄存器值传递
8 bit8 bit16 bit指令宽度:32 bit
move-w32-I8I16dessrc32 位寄存器值传递
move-w64-I8I16dessrc64 位寄存器值传递

文本格式:op.sub des,src

助记符操作码操作子码目的寄存器源寄存器注解
8 bit8 bit8 bit8 bit指令宽度:32 bit
mov-I8subdessrc
8 bit8 bit16 bit16 bit指令宽度:48 bit
mov-I16subdessrc

操作子码定义

助记符含义:

  • 目标位宽-源数据获取转换位宽

    • i:符号扩展。
    • u:零扩展。
    • 只有目标位宽时,表示源位宽直接拷贝传递。
  • 目标类型-源类型

    • 表示从源类型转换到目标类型
助记符操作子码注解
w32-B0-i80获取寄存器的第 1 个字节,进行符号扩展到 32 位
w32-B0-u81获取寄存器的第 1 个字节,进行零扩展到 32 位
w32-B1-i82获取寄存器的第 2 个字节,进行符号扩展到 32 位
w32-B1-u83获取寄存器的第 2 个字节,进行零扩展到 32 位
w32-B2-i84获取寄存器的第 3 个字节,进行符号扩展到 32 位
w32-B2-u85获取寄存器的第 3 个字节,进行零扩展到 32 位
w32-B3-i86获取寄存器的第 4 个字节,进行符号扩展到 32 位
w32-B3-u87获取寄存器的第 4 个字节,进行零扩展到 32 位
w32-L16-i168获取寄存器的低 16 位,进行符号扩展到 32 位
w32-L16-u169获取寄存器的低 16 位,进行零扩展到 32 位
w32-H16-i1610获取寄存器的高 16 位,进行符号扩展到 32 位
w32-H16-u1611获取寄存器的高 16 位,进行零扩展到 32 位
w321232 位原值拷贝传递
w64-B0-i813获取寄存器的第 1 个字节,进行符号扩展到 64 位
w64-B0-u814获取寄存器的第 1 个字节,进行零扩展到 64 位
w64-B1-i815获取寄存器的第 2 个字节,进行符号扩展到 64 位
w64-B1-u816获取寄存器的第 2 个字节,进行零扩展到 64 位
w64-B2-i817获取寄存器的第 3 个字节,进行符号扩展到 64 位
w64-B2-u818获取寄存器的第 3 个字节,进行零扩展到 64 位
w64-B3-i819获取寄存器的第 4 个字节,进行符号扩展到 64 位
w64-B3-u820获取寄存器的第 4 个字节,进行零扩展到 64 位
w64-L16-i1621获取寄存器的低 16 位,进行符号扩展到 32 位
w64-L16-u1622获取寄存器的低 16 位,进行零扩展到 32 位
w64-H16-i1623获取寄存器的高 16 位,进行符号扩展到 32 位
w64-H16-u1624获取寄存器的高 16 位,进行零扩展到 32 位
w64-i3225获取寄存器的 32 位,进行符号扩展到 64 位
w64-u3226获取寄存器的 32 位,进行零扩展到 64 位
w642764 位原值拷贝传递
i32-f322832 位有符号整数转 32 位浮点数
i32-f642932 位有符号整数转 64 位浮点数
u32-f323032 位无符号整数转 32 位浮点数
u32-f643132 位无符号整数转 64 位浮点数
i64-f323264 位有符号整数转 32 位浮点数
i64-f643364 位有符号整数转 32 位浮点数
u64-f323464 位无符号整数转 32 位浮点数
u64-f643564 位无符号整数转 64 位浮点数
f32-i323632 位浮点数转 32 位有符号
f32-i643732 位浮点数转 64 位有符号
f32-u323832 位浮点数转 32 位无符号
f32-u643932 位浮点数转 64 位无符号
f32-f644932 位浮点数转 64 位浮点数
f64-i324164 位浮点数转 32 位有符号
f64-i644264 位浮点数转 64 位有符号
f64-u324364 位浮点数转 32 位无符号
f64-u644464 位浮点数转 64 位无符号
f64-f324564 位浮点数转 32 位浮点数

数学运算指令

  • 有二地址、三地址分类。
  • 每类的主操作码不一致。

三地址操作

三地址文本格式: op.sub des,src,src2

助记符操作码操作子码目的寄存器源寄存器源操作数注解
8 bit8 bit8 bit4 bit4 bit指令宽度:32 bit
math-I4subdessrcsrc2
8 bit8 bit16 bit8 bit8 bit指令宽度:48 bit
math-I16I8subdessrcsrc2
8 bit8 bit16 bit16 bit16 bit指令宽度:64 bit
math-I16subdessrcsrc2

子码定义

助记符操作子码注解
add-int32032 位有符号 加 +
sub-int32132 位有符号 减 -
mul-int32232 位有符号 乘 *
div-int32332 位有符号 除 /
mod-int32432 位有符号 模 %
add-uint32532 位无符号 加 +
sub-uint32632 位无符号 减 -
mul-uint32732 位无符号 乘 *
div-uint32832 位无符号 除 /
mod-uint32932 位无符号 模 %
add-int641064 位有符号 加 +
sub-int641164 位有符号 减 -
mul-int641264 位有符号 乘 *
div-int641364 位有符号 除 /
mod-int641464 位有符号
add-uint641564 位无符号 加 +
sub-uint641664 位无符号 减 -
mul-uint641764 位无符号 乘 *
div-uint641864 位无符号 除 /
mod-uint641964 位无符号 模 %
add-flt322032 位浮点 加 +
sub-flt322132 位浮点 减 -
mul-flt322232 位浮点 乘 *
div-flt322332 位浮点 除 /
mod-flt322432 位浮点 模 %
add-flt642564 位浮点 加 +
sub-flt642664 位浮点 减 -
mul-flt642764 位浮点 乘 *
div-flt642864 位浮点 除 /
mod-flt642964 位浮点 模 %
sl-w323032 位 左移
sr-w323132 位 右移
sra-w323232 位 算术右移
rol-w323332 位 循环左移
ror-w323432 位 循环右移
and-w323532 位 位与
or-w323632 位 位或
xor-w323732 位 位异或
sl-w643864 位 左移
sr-w643964 位 右移
sra-w644064 位 算术右移
rol-w324164 位 循环左移
ror-w324264 位 循环右移
and-w644364 位 位与
or-w644464 位 位或
xor-w644564 位 位异或
andl-w324632 位 逻辑与
orl-w324732 位 逻辑或
cmp-int3248src < src2 : des=-1
cmp-uint3249src == src2 : des=0
cmp-int6450src > src2 : des=1
cmp-uint6451
cmp-flt3252
cmp-flt6453

二地址操作

二地址文本格式: op.sub des,src

助记符操作码操作子码目的寄存器源寄存器源操作数注解
8 bit8 bit8 bit8 bit指令宽度:32 bit
math-I8subdessrc
8 bit8 bit16 bit16 bit指令宽度:48 bit
math-I16subdessrc

子码定义

助记符操作子码注解
not-w32032 位 按位取反
not-w64164 位 按位取反
inv-w32232 位 逻辑取反
inv-w64364 位 逻辑取反
neg-int32432 位 符号取反
neg-int64564 位 符号取反
neg-flt32632 位 符号取反
neg-flt64764 位 符号取反
abs-int32832 位 取绝对值
abs-int64964 位 取绝对值
abs-flt321032 位 取绝对值
abs-flt641164 位 取绝对值
sin-flt3212三角函数
cos-flt3213三角函数
tan-flt3214三角函数
asin-flt3215三角函数
acos-flt3216三角函数
atan-flt3217三角函数
sin-flt6418三角函数
cos-flt6419三角函数
tan-flt6420三角函数
asin-flt6421三角函数
acos-flt6422三角函数
atan-flt6423三角函数

跳转指令

直接跳转指令

文本格式: goto imm

助记符操作码对齐立即数注解
8 bit8 bit指令宽度: 16 bit
goto8imm8 bit有符号偏移
8 bit8 bit16 bit指令宽度: 32 bit
goto16imm
8 bit8 bit32 bit指令宽度: 48 bit
goto32imm

分支跳转指令

文本格式
jbr src,src2,imm
jbr src,imm
  • 类型编码:标识操作数的类型。
  • 操作子码:标识比较方法。
  • 和 0 比较时,无源操作数 src2。
助记符操作码操作子码类型码源操作数源操作数立即数注解
8 bit4 bit4 bit
8 bit8 bit16 bit指令宽度: 32 bit
8 bit8 bit32 bit指令宽度: 32 bit
16 bit16 bit16 bit指令宽度: 32 bit
16 bit16 bit32 bit指令宽度: 32 bit
srcsrc2imm
操作子码
助记符操作子码注解
eq0if( src == src2 ) goto imm
ne1if( src != src2 ) goto imm
lt2if( src < src2 ) goto imm
le3if( src <= src2 ) goto imm
gt4if( src > src2 ) goto imm
ge5if( src >= src2 ) goto imm
eqz6if( src == 0 ) goto imm
nez7if( src != 0 ) goto imm
ltz8if( src < 0 ) goto imm
lez9if( src <= 0 ) goto imm
gtz10if( src > 0 ) goto imm
gez11if( src >= 0 ) goto imm

注意: 和 0 比较时,无源操作数 src2。

类型码
助记符操作子码注解
int32032 位有符号比较
uint32132 位无符号比较
int64264 位有符号比较
uint64364 位无符号比较
flt32432 位浮点数比较
flt64564 位浮点数比较

返回指令

文本格式: op src op imm

助记符操作码操作子码立即数码源操作数注解
8 bit8 bit指令宽度: 16 bit
return-void无参数返回
return-w32-I8返回 32 bit 值
return-w64-I8返回 64 bit 值
8 bit4 bit4 bit16/32/64 bit
操作子码
助记符操作子码注解
I160寄存器索引16位
int321立即数转换到32位有符号整数
uint322立即数转换到32位有符号整数
int643立即数转换到32位有符号整数
uint644立即数转换到32位有符号整数
flt325立即数转换到32位有符号整数
flt646立即数转换到32位有符号整数
立即数码
助记符操作子码注解
B16016 位立即数
B32132 位立即数
B64264 位立即数

函数调用指令

不固定参数调用

文本格式:op argcnt, arg,arg2,…,func

助记符操作码参数个数参数寄存器函数注解
8 bit8 bit16 bit32 bit
invoke-virtual-nofixargcntarg…func调用虚函数
invoke-direct-nofixargcntarg…func直接调用函数
invoke-static-nofixargcntarg…func调用静态函数
invoke-interface-nofixargcntarg…func调用接口函数
invoke-native-nofixargcntarg…func调用C语言函数

范围参数调用

文本格式:op argcnt,start, end,func

助记符操作码参数个数起始寄存器结束寄存器索引函数注解
8 bit8 bit16 bit16 bit32 bit
invoke-virtual-rangeargcntarg…func调用虚函数
invoke-direct-rangeargcntarg…func直接调用函数
invoke-static-rangeargcntarg…func调用静态函数
invoke-interface-rangeargcntarg…func调用接口函数
invoke-native-rangeargcntarg…func调用C语言函数

获取返回值指令

文本格式:op des

助记符操作码对齐源寄存器注解
8 bit8 bit指令宽度: 16 bit
get-result-w32-I8des获取32位返回值
get-result-w64-I8des获取64位返回值
get-result-obj-I8des获取对象返回值
8 bit8 bit16 bit指令宽度: 32 bit
get-result-w32-I16des获取32位返回值
get-result-w64-I16des获取64位返回值
get-result-obj-I16des获取对象返回值

异常处理指令

文本格式:op des

助记符操作码对齐源寄存器注解
8 bit8 bit指令宽度: 16 bit
get-exception-I8des获取异常对象
throw-I8src抛出异常对象
8 bit8 bit16 bit指令宽度: 32 bit
get-exception-I16des获取异常对象
throw-I16src抛出异常对象

7.3 基于栈和寄存器的指令集


本章节描述的是作者按照 RISC 指令系统设计的虚拟机指令集。

其类似与硬件指令集,可作为编译器后端指令系统目标,用于提供类似硬件指令系统环境,避免编译原理初学者陷入对硬件指令系统不了解的深渊。 降低学习难度,提高学习效率。

这类指令的主要特点如下:

  • 1 寄存器的数量固定;
  • 2 指令所操作的寄存器数量固定;
  • 3 指令的含义简单;

1 寄存器

虚拟机的寄存器分为三种:

  • 1 整数寄存器:主要用于整数运算,位宽为 64 bit,根据指令的含义可选择 32 bit 和 64 bit 运算模式。
  • 2 浮点寄存器:主要用于浮点数运算,位宽为 64 bit,和通用寄存器一致,可选择位宽模式。
  • 3 系统寄存器:对用户不可见,与虚拟机运行系统相关,对其进行操作隐藏在相关指令的实现细节中。
  • 4 根据指令格式,整数寄存器、浮点寄存器最多可以有32个。

2 指令格式

每条指令是 32bit 大小对齐的,其中最低 9bit 是操作码,其余23bit作为操作数或者操作码的补充。如下表所示:

操作码操作数
9 bit23 bit

2.1 格式1

操作码操作数
9 bit23 bit

2.2 格式2

多数指令使用此格式。

操作码目的操作数源操作数源操作数操作子码
9 bit5 bit5 bit5 bit8 bit

2.3 格式3

该格式主要用于比较指令后的三元选择赋值操作。

操作码目的操作数源操作数源操作数源操作数操作子码
9 bit5 bit5 bit5 bit5 bit3 bit

2.4 格式4

当指令中需要使用立即数时,且在指令中没有足够的空间可以存储时,可以使用指令后跟32bit对齐的立即数操作数。

  • 32bit立即数:32bit 指令跟 1 个 32bit 立即数,虚拟机解析执行时,按照指令表达的语义参与运算。
  • 64bit立即数:32bit 指令跟 2 个 32bit 立即数,虚拟机解析执行时,按照指令表达的语义,组合成 64bit,后参与运算。
  • 其他位宽的立即数类似。

格式如下所示:

指令立即数 1立即数 2立即数 n
32 bit32 bit32 bit32 bit

3 寄存器与寄存器—指令集

3.1 空指令

空指令一般用于对齐,在本指令集中没有特殊含义,执行空操作。

格式如下:

助记符操作码操作数
9 bit23 bit
Nop00

3.2 算术运算

算术运算包含 +、-、*、/、%,支持的运算类型有 int32、uint32、int64、uint64、flt32、flt64。

  • 文本格式: op des,src,src2
  • 指令含义:des = src op src2
  • 子操作码:可以用于将运算结果进行截断、扩展。
  • 助记符后缀的数字(32、64)标识指令运算使用的寄存器位宽。
  • 助记符后缀的 i 表示进行有符号运算。
  • 助记符后缀的 u 表示进行无符号运算。
  • 助记符后缀的 f 表示进行有符号运算。

指令格式如下所示:

助记符操作码目的操作数源操作数源操作数操作子码
9 bit5 bit5 bit5 bit8 bit
add-i32dessrcsrc2
sub-i32dessrcsrc2
mul-i32dessrcsrc2
div-i32dessrcsrc2
mod-i32dessrcsrc2
add-u32dessrcsrc2
sub-u32dessrcsrc2
mul-u32dessrcsrc2
div-u32dessrcsrc2
mod-u32dessrcsrc2
add-i64dessrcsrc2
sub-i64dessrcsrc2
mul-i64dessrcsrc2
div-i64dessrcsrc2
mod-i64dessrcsrc2
add-u64dessrcsrc2
sub-u64dessrcsrc2
mul-u64dessrcsrc2
div-u64dessrcsrc2
mod-u64dessrcsrc2
add-f32dessrcsrc2
sub-f32dessrcsrc2
mul-f32dessrcsrc2
div-f32dessrcsrc2
add-f64dessrcsrc2
sub-f64dessrcsrc2
mul-f64dessrcsrc2
div-f64dessrcsrc2

3.2 位运算

位运算包括位相关的与、或、非、异或、移位、取反等运算。

支持的运算类型有 uint32、uint64。

  • 文本格式: op des,src,src2
  • 指令含义:des = src op src2
  • 子操作码:可以用于将运算结果进行截断、扩展。
  • i32:表示进行 32bit 的位运算。
  • i64:表示进行 64bit 的位运算。
  • 位运算都是看作无符号运算。

指令格式如下所示:

助记符操作码目的操作数源操作数源操作数操作子码
9 bit5 bit5 bit5 bit8 bit
sl-i32dessrcsrc2
sr-i32dessrcsrc2
sra-i32dessrcsrc2
and-i32dessrcsrc2
or-i32dessrcsrc2
xor-i32dessrcsrc2
andn-i32dessrcsrc2
orn-i32dessrcsrc2
xorn-i32dessrcsrc2
not-i32dessrcsrc2
sl-i64dessrcsrc2
sr-i64dessrcsrc2
sra-i64dessrcsrc2
and-i64dessrcsrc2
or-i64dessrcsrc2
xor-i64dessrcsrc2
andn-i64dessrcsrc2
orn-i64dessrcsrc2
xorn-i64dessrcsrc2
not-i64dessrcsrc2

3.3 逻辑比较

逻辑比较运算包括:<、>、<=、>=、==、!=、 ==0、!=0. 支持的运算类型有 int32、uint32、int64、uint64、flt32\flt64。

  • 文本格式: op des,src,src2
  • 指令含义:des = src op src2
  • 子操作码:可以用于标识比较的方法。
  • 比较的结果,存储在整数寄存器中,且使用位宽 64 bit,即des是整数寄存器。

指令格式如下所示:

助记符操作码目的操作数源操作数源操作数操作子码
9 bit5 bit5 bit5 bit8 bit
cmp-i32dessrcsrc2
cmp-u32dessrcsrc2
cmp-i64dessrcsrc2
cmp-u64dessrcsrc2
cmp-f32dessrcsrc2
cmp-f64dessrcsrc2

操作子码定义如下:

助记符操作码含义
lt<
le<=
gt>
ge>=
eq==
ne!=
ez==0,此时没有源操作数src2
nz!=0,此时没有源操作数src2

当不使用操作子码,而是使用下面方式运算:

  • src < src2,设置des寄存器为 -1。
  • src == src2,设置des寄存器为 0。
  • src > src2,设置des寄存器为 -1。

3.4 条件赋值

条件赋值指令使用比较指令的结果,对另外 2 个源操作数进行选择,传递个目标操作数。

指令格式如下所示:

助记符操作码目的操作数源操作数源操作数源操作数操作子码
9 bit5 bit5 bit5 bit5 bit3 bit
sel-i32dessrcsrc2cond
sel-u32dessrcsrc2cond
sel-i64dessrcsrc2cond
sel-u64dessrcsrc2cond
sel-f32dessrcsrc2cond
sel-f64dessrcsrc2cond

当比较系列指令使用操作子码方式时:

  • cond == 0 :des = src
  • cond != 0 :des = src2

当比较系列指令不使用操作子码方式时,本系列指令要求使用操作子码进行判断:

操作子码定义如下:

助记符操作码含义
lt< :des = cond == -1 ? src : src2
le<= :des = cond < 1 ? src : src2
gt> :des = cond == 1 ? src : src2
ge>= :des = cond > -1 ? src : src2
eq== :des = cond == 0 ? src : src2
ne!= :des = cond != 0 ? src : src2

3.5 赋值指令

此系列包括寄存器间赋值或类型转换。

助记符操作码目的操作数源操作数源操作数操作子码
9 bit5 bit5 bit5 bit8 bit
movdessrc

操作子码用于获取源操作数并转换到响应的类型。

操作子码定义如下:

助记符操作码含义
i8-i32
u8-i32
i8-i64
u8-u64
i16-i32
u16-i32
i16-i64
u16-i64
i32_i32
i32-i64
i32-f32
i32-f64
u32-u32
u32-u64
u32-f32
u32-f64
i64-i64
i64-f32
i64-f64
u64-u64
u64-f32
u64-f64
f32-i32
f32-u32
f32-i64
f32-u64
f32-f32
f32-f64
f64-i32
f64-u32
f64-i64
f64-u64
f64-f32
f64-f64
f32-bit-u32位转换
u32-bit-f32位转换
f64-bit-u64位转换
u64-bit-f64位转换

3.6 加载存储指令

此系列指令功能是从内存中读取、存储特定类型数据。

助记符操作码目的操作数源操作数源操作数操作子码注释
9 bit5 bit5 bit5 bit8 bit
loaddesbaseoffset从基址内存中获取数据
storedesbaseoffset
gloaddesbaseoffset从全局内存中获取数据
gstoredesbaseoffset

操作子码定义如下:

助记符操作码含义
i8
u8
i16
u16
i32
u32
i64
u64
f32
f64

3.7 出入栈指令

此系列指令用于将数据入栈,同时可以进行类型转换。 注意:入栈数据应当进行 32bit 对齐。以加快虚拟机执行速度数据

助记符操作码目的操作数源操作数源操作数操作子码
9 bit5 bit5 bit5 bit8 bit
pushdes
popdes
操作子码定义如下:
助记符操作码含义
i8
u8
i16
u16
i32
u32
i64
u64
f32
f64

3.8 栈内存分配释放

此系列指令用于栈内存分配释放。 注意:立即数是无符号整数。

助记符操作码目的操作数立即数注释
9 bit5 bit18 bit
growndesimm分配栈内存,将分配后的栈指针值传递到 des 寄存器
9 bit23 bit释放栈内存,
shrunkimm

3.9 跳转指令

  • 跳转的偏移量是无符号整数值;
  • 相对于函数代码的起始地址;
  • 偏移量是偏移的指令条数;
助记符操作码目的操作数立即数注释
9 bit23 bit
jmpimm直接跳转
9 bit5 bit18 bit
jmpxreg偏移量在 reg 寄存器中
9 bit5 bit18 bit
jtabregimmreg 表示偏移量索引,imm表示偏移量数组中偏移数据条数,指令后面接 32 bit 对齐的偏移量数组

3.10 分支指令

此系列指令用于条件分支跳转。

助记符操作码目的操作数源操作数源操作数操作子码偏移立即数
9 bit5 bit5 bit5 bit8 bit32 bit
jbr-i32srcsrc2condoffset
jbr-u32srcsrc2condoffset
jbr-i64srcsrc2condoffset
jbr-u64srcsrc2condoffset
jbr-f32srcsrc2condoffset
jbr-f64srcsrc2condoffset

操作子码定义如下:

助记符操作码含义
lt<
le<=
gt>
ge>=
eq==
ne!=
ez==0,此时没有源操作数src2
nz!=0,此时没有源操作数src2

3.11 函数指令

助记符操作码目的操作数立即数注释
9 bit23 bit32 bit
callimmimm表示函数的偏移量或者是编号,看虚拟机的具体实现
9 bit5 bit18 bit
callxregreg 寄存器中保存函数的偏移量或者是编号,看虚拟机的具体实现
9 bit23 bit
ret函数返回

4 寄存器与立即数–指令集

待续