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 bit | 16 | [ 0, 15 ] |
8 bit | 256 | [ 0, 255 ] |
16 bit | 65536 | [ 0, 65535 ] |
空指令
文本格式: nop
助记符 | 操作码 | 对齐 | 注解 |
---|
格式 | 8 bit | 8bit | 指令宽度:16 bit |
| | | |
nop | 0 | | 空操作,用于对齐 |
常量赋值指令
文本格式: op des, imm
助记符 | 操作码 | 目的寄存器 | 立即数 | 注解 |
---|
| 8 bit | 4 bit | 4 bit | 4 bit 立即数,指令宽度:16 bit |
const-w32-I4-i4 | | des | imm | imm 为有符号整数,有符号扩展至 32 bit。 |
const-w64-I4-i4 | | des | imm | imm 为有符号整数,有符号扩展至 32 bit。 |
const-w32-I4-u4 | | des | imm | imm 为无符号整数,无符号扩展至 32 bit。 |
const-w64-I4-u4 | | des | imm | imm 为无符号整数,无符号扩展至 32 bit。 |
| | | | |
| 8 bit | 8 bit | 16 bit | 16 bit 立即数,指令宽度:32 bit |
const-w32-I8-i16 | | des | imm | imm 为有符号整数,有符号扩展至 32 bit。 |
const-w64-I8-i16 | | des | imm | imm 为有符号整数,有符号扩展至 64 bit。 |
const-w32-I8-u16 | | des | imm | imm 为无符号整数,无符号扩展至 32 bit。 |
const-w64-I8-u16 | | des | imm | imm 为无符号整数,无符号扩展至 64 bit。 |
const-w32-I8-L16 | | des | imm | imm 为无符号整数。imm 存放在寄存器的低 16 bit,不改变高 16 bit。 |
const-w32-I8-H16 | | des | imm | imm 为无符号整数。imm 存放在寄存器的高 16 bit,不改变低 16 bit。 |
| | | | |
| 8 bit | 8 bit | 32 bit | 32 bit 立即数,指令宽度:48 bit |
const-w32-I8 | | des | imm | 原样拷贝,支持32 bit 整数和浮点。 |
const-w64-I8-i32 | | des | imm | imm 为有符号整数,有符号扩展至 64 bit。 |
const-w64-I8-u32 | | des | imm | imm 为无符号整数,无符号扩展至 64 bit。 |
| | | | |
| 8 bit | 8 bit | 64 bit | 64 bit 立即数,指令宽度:80 bit |
const-w64-I8 | | des | imm | 原样拷贝,支持64 bit整数和浮点。 |
文本格式:op.sub des,imm
助记符 | 操作码 | 操作子码 | 目的寄存器 | 立即数 | 注解 |
---|
| 8 bit | 8 bit | 8 bit | 8 bit | 指令宽度:32 bit |
const-w32-I8 | | subop | des | imm | imm 为无符号整数 |
操作子码定义
助记符 | 操作子码 | 注解 |
---|
B0 | | imm存放在寄存器的第 1 个字节,不改变其他字节。 |
B1 | | imm存放在寄存器的第 2 个字节,不改变其他字节。 |
B2 | | imm存放在寄存器的第 3 个字节,不改变其他字节。 |
B3 | | imm存放在寄存器的第 4 个字节,不改变其他字节。 |
寄存器赋值指令
文本格式:op des,src
文本格式:op des,src
助记符 | 操作码 | 目的寄存器 | 源寄存器 | 注解 |
---|
| 8 bit | 4 bit | 4 bit | 指令宽度:16 bit |
move-w32-I4 | | des | src | 32 位寄存器值传递 |
move-w64-I4 | | des | src | 64 位寄存器值传递 |
| | | | |
| 8 bit | 8 bit | 16 bit | 指令宽度:32 bit |
move-w32-I8I16 | | des | src | 32 位寄存器值传递 |
move-w64-I8I16 | | des | src | 64 位寄存器值传递 |
文本格式:op.sub des,src
助记符 | 操作码 | 操作子码 | 目的寄存器 | 源寄存器 | 注解 |
---|
| 8 bit | 8 bit | 8 bit | 8 bit | 指令宽度:32 bit |
mov-I8 | sub | des | src | | |
| | | | | |
| 8 bit | 8 bit | 16 bit | 16 bit | 指令宽度:48 bit |
mov-I16 | sub | des | src | | |
操作子码定义
助记符含义:
目标位宽-源数据获取转换位宽
- i:符号扩展。
- u:零扩展。
- 只有目标位宽时,表示源位宽直接拷贝传递。
目标类型-源类型
助记符 | 操作子码 | 注解 |
---|
w32-B0-i8 | 0 | 获取寄存器的第 1 个字节,进行符号扩展到 32 位 |
w32-B0-u8 | 1 | 获取寄存器的第 1 个字节,进行零扩展到 32 位 |
w32-B1-i8 | 2 | 获取寄存器的第 2 个字节,进行符号扩展到 32 位 |
w32-B1-u8 | 3 | 获取寄存器的第 2 个字节,进行零扩展到 32 位 |
w32-B2-i8 | 4 | 获取寄存器的第 3 个字节,进行符号扩展到 32 位 |
w32-B2-u8 | 5 | 获取寄存器的第 3 个字节,进行零扩展到 32 位 |
w32-B3-i8 | 6 | 获取寄存器的第 4 个字节,进行符号扩展到 32 位 |
w32-B3-u8 | 7 | 获取寄存器的第 4 个字节,进行零扩展到 32 位 |
| | |
w32-L16-i16 | 8 | 获取寄存器的低 16 位,进行符号扩展到 32 位 |
w32-L16-u16 | 9 | 获取寄存器的低 16 位,进行零扩展到 32 位 |
w32-H16-i16 | 10 | 获取寄存器的高 16 位,进行符号扩展到 32 位 |
w32-H16-u16 | 11 | 获取寄存器的高 16 位,进行零扩展到 32 位 |
w32 | 12 | 32 位原值拷贝传递 |
| | |
w64-B0-i8 | 13 | 获取寄存器的第 1 个字节,进行符号扩展到 64 位 |
w64-B0-u8 | 14 | 获取寄存器的第 1 个字节,进行零扩展到 64 位 |
w64-B1-i8 | 15 | 获取寄存器的第 2 个字节,进行符号扩展到 64 位 |
w64-B1-u8 | 16 | 获取寄存器的第 2 个字节,进行零扩展到 64 位 |
w64-B2-i8 | 17 | 获取寄存器的第 3 个字节,进行符号扩展到 64 位 |
w64-B2-u8 | 18 | 获取寄存器的第 3 个字节,进行零扩展到 64 位 |
w64-B3-i8 | 19 | 获取寄存器的第 4 个字节,进行符号扩展到 64 位 |
w64-B3-u8 | 20 | 获取寄存器的第 4 个字节,进行零扩展到 64 位 |
| | |
w64-L16-i16 | 21 | 获取寄存器的低 16 位,进行符号扩展到 32 位 |
w64-L16-u16 | 22 | 获取寄存器的低 16 位,进行零扩展到 32 位 |
w64-H16-i16 | 23 | 获取寄存器的高 16 位,进行符号扩展到 32 位 |
w64-H16-u16 | 24 | 获取寄存器的高 16 位,进行零扩展到 32 位 |
w64-i32 | 25 | 获取寄存器的 32 位,进行符号扩展到 64 位 |
w64-u32 | 26 | 获取寄存器的 32 位,进行零扩展到 64 位 |
w64 | 27 | 64 位原值拷贝传递 |
| | |
i32-f32 | 28 | 32 位有符号整数转 32 位浮点数 |
i32-f64 | 29 | 32 位有符号整数转 64 位浮点数 |
u32-f32 | 30 | 32 位无符号整数转 32 位浮点数 |
u32-f64 | 31 | 32 位无符号整数转 64 位浮点数 |
| | |
i64-f32 | 32 | 64 位有符号整数转 32 位浮点数 |
i64-f64 | 33 | 64 位有符号整数转 32 位浮点数 |
u64-f32 | 34 | 64 位无符号整数转 32 位浮点数 |
u64-f64 | 35 | 64 位无符号整数转 64 位浮点数 |
| | |
f32-i32 | 36 | 32 位浮点数转 32 位有符号 |
f32-i64 | 37 | 32 位浮点数转 64 位有符号 |
f32-u32 | 38 | 32 位浮点数转 32 位无符号 |
f32-u64 | 39 | 32 位浮点数转 64 位无符号 |
f32-f64 | 49 | 32 位浮点数转 64 位浮点数 |
| | |
f64-i32 | 41 | 64 位浮点数转 32 位有符号 |
f64-i64 | 42 | 64 位浮点数转 64 位有符号 |
f64-u32 | 43 | 64 位浮点数转 32 位无符号 |
f64-u64 | 44 | 64 位浮点数转 64 位无符号 |
f64-f32 | 45 | 64 位浮点数转 32 位浮点数 |
数学运算指令
三地址操作
三地址文本格式: op.sub des,src,src2
助记符 | 操作码 | 操作子码 | 目的寄存器 | 源寄存器 | 源操作数 | 注解 |
---|
| 8 bit | 8 bit | 8 bit | 4 bit | 4 bit | 指令宽度:32 bit |
math-I4 | | sub | des | src | src2 | |
| 8 bit | 8 bit | 16 bit | 8 bit | 8 bit | 指令宽度:48 bit |
math-I16I8 | | sub | des | src | src2 | |
| 8 bit | 8 bit | 16 bit | 16 bit | 16 bit | 指令宽度:64 bit |
math-I16 | | sub | des | src | src2 | |
子码定义
助记符 | 操作子码 | 注解 |
---|
add-int32 | 0 | 32 位有符号 加 + |
sub-int32 | 1 | 32 位有符号 减 - |
mul-int32 | 2 | 32 位有符号 乘 * |
div-int32 | 3 | 32 位有符号 除 / |
mod-int32 | 4 | 32 位有符号 模 % |
| | |
add-uint32 | 5 | 32 位无符号 加 + |
sub-uint32 | 6 | 32 位无符号 减 - |
mul-uint32 | 7 | 32 位无符号 乘 * |
div-uint32 | 8 | 32 位无符号 除 / |
mod-uint32 | 9 | 32 位无符号 模 % |
| | |
add-int64 | 10 | 64 位有符号 加 + |
sub-int64 | 11 | 64 位有符号 减 - |
mul-int64 | 12 | 64 位有符号 乘 * |
div-int64 | 13 | 64 位有符号 除 / |
mod-int64 | 14 | 64 位有符号 |
| | |
add-uint64 | 15 | 64 位无符号 加 + |
sub-uint64 | 16 | 64 位无符号 减 - |
mul-uint64 | 17 | 64 位无符号 乘 * |
div-uint64 | 18 | 64 位无符号 除 / |
mod-uint64 | 19 | 64 位无符号 模 % |
| | |
add-flt32 | 20 | 32 位浮点 加 + |
sub-flt32 | 21 | 32 位浮点 减 - |
mul-flt32 | 22 | 32 位浮点 乘 * |
div-flt32 | 23 | 32 位浮点 除 / |
mod-flt32 | 24 | 32 位浮点 模 % |
| | |
add-flt64 | 25 | 64 位浮点 加 + |
sub-flt64 | 26 | 64 位浮点 减 - |
mul-flt64 | 27 | 64 位浮点 乘 * |
div-flt64 | 28 | 64 位浮点 除 / |
mod-flt64 | 29 | 64 位浮点 模 % |
| | |
sl-w32 | 30 | 32 位 左移 |
sr-w32 | 31 | 32 位 右移 |
sra-w32 | 32 | 32 位 算术右移 |
rol-w32 | 33 | 32 位 循环左移 |
ror-w32 | 34 | 32 位 循环右移 |
and-w32 | 35 | 32 位 位与 |
or-w32 | 36 | 32 位 位或 |
xor-w32 | 37 | 32 位 位异或 |
| | |
sl-w64 | 38 | 64 位 左移 |
sr-w64 | 39 | 64 位 右移 |
sra-w64 | 40 | 64 位 算术右移 |
rol-w32 | 41 | 64 位 循环左移 |
ror-w32 | 42 | 64 位 循环右移 |
and-w64 | 43 | 64 位 位与 |
or-w64 | 44 | 64 位 位或 |
xor-w64 | 45 | 64 位 位异或 |
| | |
andl-w32 | 46 | 32 位 逻辑与 |
orl-w32 | 47 | 32 位 逻辑或 |
| | |
cmp-int32 | 48 | src < src2 : des=-1 |
cmp-uint32 | 49 | src == src2 : des=0 |
cmp-int64 | 50 | src > src2 : des=1 |
cmp-uint64 | 51 | |
cmp-flt32 | 52 | |
cmp-flt64 | 53 | |
| | |
二地址操作
二地址文本格式: op.sub des,src
助记符 | 操作码 | 操作子码 | 目的寄存器 | 源寄存器 | 源操作数 | 注解 |
---|
| 8 bit | 8 bit | 8 bit | 8 bit | 指令宽度:32 bit | |
math-I8 | | sub | des | src | | |
| 8 bit | 8 bit | 16 bit | 16 bit | 指令宽度:48 bit | |
math-I16 | | sub | des | src | | |
子码定义
助记符 | 操作子码 | 注解 |
---|
not-w32 | 0 | 32 位 按位取反 |
not-w64 | 1 | 64 位 按位取反 |
| | |
inv-w32 | 2 | 32 位 逻辑取反 |
inv-w64 | 3 | 64 位 逻辑取反 |
| | |
neg-int32 | 4 | 32 位 符号取反 |
neg-int64 | 5 | 64 位 符号取反 |
neg-flt32 | 6 | 32 位 符号取反 |
neg-flt64 | 7 | 64 位 符号取反 |
| | |
abs-int32 | 8 | 32 位 取绝对值 |
abs-int64 | 9 | 64 位 取绝对值 |
abs-flt32 | 10 | 32 位 取绝对值 |
abs-flt64 | 11 | 64 位 取绝对值 |
| | |
sin-flt32 | 12 | 三角函数 |
cos-flt32 | 13 | 三角函数 |
tan-flt32 | 14 | 三角函数 |
asin-flt32 | 15 | 三角函数 |
acos-flt32 | 16 | 三角函数 |
atan-flt32 | 17 | 三角函数 |
| | |
sin-flt64 | 18 | 三角函数 |
cos-flt64 | 19 | 三角函数 |
tan-flt64 | 20 | 三角函数 |
asin-flt64 | 21 | 三角函数 |
acos-flt64 | 22 | 三角函数 |
atan-flt64 | 23 | 三角函数 |
跳转指令
直接跳转指令
文本格式: goto imm
助记符 | 操作码 | 对齐 | 立即数 | 注解 |
---|
| 8 bit | | 8 bit | 指令宽度: 16 bit |
goto8 | | | imm | 8 bit有符号偏移 |
| 8 bit | 8 bit | 16 bit | 指令宽度: 32 bit |
goto16 | | | imm | |
| 8 bit | 8 bit | 32 bit | 指令宽度: 48 bit |
goto32 | | | imm | |
分支跳转指令
文本格式
jbr src,src2,imm
jbr src,imm
- 类型编码:标识操作数的类型。
- 操作子码:标识比较方法。
- 和 0 比较时,无源操作数 src2。
助记符 | 操作码 | 操作子码 | 类型码 | 源操作数 | 源操作数 | 立即数 | 注解 |
---|
| 8 bit | 4 bit | 4 bit | | | | |
| | | | 8 bit | 8 bit | 16 bit | 指令宽度: 32 bit |
| | | | 8 bit | 8 bit | 32 bit | 指令宽度: 32 bit |
| | | | 16 bit | 16 bit | 16 bit | 指令宽度: 32 bit |
| | | | 16 bit | 16 bit | 32 bit | 指令宽度: 32 bit |
| | | | src | src2 | imm | |
操作子码
助记符 | 操作子码 | 注解 |
---|
eq | 0 | if( src == src2 ) goto imm |
ne | 1 | if( src != src2 ) goto imm |
lt | 2 | if( src < src2 ) goto imm |
le | 3 | if( src <= src2 ) goto imm |
gt | 4 | if( src > src2 ) goto imm |
ge | 5 | if( src >= src2 ) goto imm |
eqz | 6 | if( src == 0 ) goto imm |
nez | 7 | if( src != 0 ) goto imm |
ltz | 8 | if( src < 0 ) goto imm |
lez | 9 | if( src <= 0 ) goto imm |
gtz | 10 | if( src > 0 ) goto imm |
gez | 11 | if( src >= 0 ) goto imm |
注意: 和 0 比较时,无源操作数 src2。
类型码
助记符 | 操作子码 | 注解 |
---|
int32 | 0 | 32 位有符号比较 |
uint32 | 1 | 32 位无符号比较 |
int64 | 2 | 64 位有符号比较 |
uint64 | 3 | 64 位无符号比较 |
flt32 | 4 | 32 位浮点数比较 |
flt64 | 5 | 64 位浮点数比较 |
返回指令
文本格式: op src
op imm
助记符 | 操作码 | 操作子码 | 立即数码 | 源操作数 | 注解 |
---|
| 8 bit | | | 8 bit | 指令宽度: 16 bit |
return-void | | | | | 无参数返回 |
return-w32-I8 | | | | | 返回 32 bit 值 |
return-w64-I8 | | | | | 返回 64 bit 值 |
| | | | | |
| 8 bit | 4 bit | 4 bit | 16/32/64 bit | |
操作子码
助记符 | 操作子码 | 注解 |
---|
I16 | 0 | 寄存器索引16位 |
int32 | 1 | 立即数转换到32位有符号整数 |
uint32 | 2 | 立即数转换到32位有符号整数 |
int64 | 3 | 立即数转换到32位有符号整数 |
uint64 | 4 | 立即数转换到32位有符号整数 |
flt32 | 5 | 立即数转换到32位有符号整数 |
flt64 | 6 | 立即数转换到32位有符号整数 |
立即数码
助记符 | 操作子码 | 注解 |
---|
B16 | 0 | 16 位立即数 |
B32 | 1 | 32 位立即数 |
B64 | 2 | 64 位立即数 |
函数调用指令
不固定参数调用
文本格式:op argcnt, arg,arg2,…,func
助记符 | 操作码 | 参数个数 | 参数寄存器 | 函数 | 注解 |
---|
| 8 bit | 8 bit | 16 bit | 32 bit | |
invoke-virtual-nofix | | argcnt | arg… | func | 调用虚函数 |
invoke-direct-nofix | | argcnt | arg… | func | 直接调用函数 |
invoke-static-nofix | | argcnt | arg… | func | 调用静态函数 |
invoke-interface-nofix | | argcnt | arg… | func | 调用接口函数 |
invoke-native-nofix | | argcnt | arg… | func | 调用C语言函数 |
范围参数调用
文本格式:op argcnt,start, end,func
助记符 | 操作码 | 参数个数 | 起始寄存器 | 结束寄存器索引 | 函数 | 注解 |
---|
| 8 bit | 8 bit | 16 bit | 16 bit | 32 bit | |
invoke-virtual-range | | argcnt | arg… | func | 调用虚函数 | |
invoke-direct-range | | argcnt | arg… | func | 直接调用函数 | |
invoke-static-range | | argcnt | arg… | func | 调用静态函数 | |
invoke-interface-range | | argcnt | arg… | func | 调用接口函数 | |
invoke-native-range | | argcnt | arg… | func | 调用C语言函数 | |
获取返回值指令
文本格式:op des
助记符 | 操作码 | 对齐 | 源寄存器 | 注解 |
---|
| 8 bit | | 8 bit | 指令宽度: 16 bit |
get-result-w32-I8 | | | des | 获取32位返回值 |
get-result-w64-I8 | | | des | 获取64位返回值 |
get-result-obj-I8 | | | des | 获取对象返回值 |
| 8 bit | 8 bit | 16 bit | 指令宽度: 32 bit |
get-result-w32-I16 | | | des | 获取32位返回值 |
get-result-w64-I16 | | | des | 获取64位返回值 |
get-result-obj-I16 | | | des | 获取对象返回值 |
异常处理指令
文本格式:op des
助记符 | 操作码 | 对齐 | 源寄存器 | 注解 |
---|
| 8 bit | | 8 bit | 指令宽度: 16 bit |
get-exception-I8 | | | des | 获取异常对象 |
throw-I8 | | src | 抛出异常对象 | |
| 8 bit | 8 bit | 16 bit | 指令宽度: 32 bit |
get-exception-I16 | | | des | 获取异常对象 |
throw-I16 | | src | 抛出异常对象 | |