首先说明 Dalvik 虚拟机的基本约定 。
- Dalvik 寄存器都是 32 位的,64 位数据使用相邻两个寄存器来存储
- 下表中提到的寄存器对均指相邻两个寄存器。如寄存器对 vAA,指寄存器 vAA,vAA+1
- 常规类型的 32 位运算码未做任何标记
- 64 位操作码以
-wide
作为后缀 - 一般指令中目标寄存器在前,源寄存器在后
- 寄存器最大数量为
65536
个 - 一个大写字母表示 4 位。如 vA 表示前 16 个寄存器之内,vBB 表示前 256 个寄存器之内,vCCCC 表示前 65536 个寄存器之内
下面解释一下表格中的每项内容。
操作码 :十六进制,范围 00 - ff
格式码 :一般三个字符,前两个为数字,最后为字母。第一个数字表示指令有多少个 16 位的字组成。第二个数字表示指令最多使用的寄存器个数。第三个字母是类型码,表示指令所使用的额外数据的类型。
语法 :助记符,smali 语法中就这么表示
说明 : 指令解释
下表为 00 - ff
的所有 Dalvik 指令 :
操作码 | 格式码 | 语法 | 说明 |
00 | 10x | nop | 空指令 |
01 | 12x | move vA, vB | 将寄存器 vB 的内容赋给寄存器 vA |
02 | 22x | move/from16 vAA, vBBBB | 将寄存器 vBBBB 的内容赋给寄存器 vAA。vAA 范围是 0-255,vBBBB 范围是 0-65535 |
03 | 32x | move/16 vAAAA, vBBBB | 将寄存器 vBBBB 的内容赋给寄存器 vAAAA。两个寄存器范围都是 0-65535 |
04 | 12x | move-wide vA, vB | 将寄存器对 vB 的内容赋给寄存器对 vA |
05 | 22x | move-wide/from16 vAA, vBBBB | 将寄存器对 vBBBB 的内容赋给寄存器对 vAA |
06 | 32x | move-wide/16 vAAAA, vBBBB | 将寄存器对 vBBBB 的内容赋给寄存器对 vAAAA |
07 | 12x | move-object vA, vB | 将寄存器 vB 中的对象引用赋给寄存去 vA |
08 | 22x | move-object/from16 vAA, vBBBB | 将寄存器 vBBBB 中的对象引用赋给寄存对 vAA |
09 | 32x | move-object/16 vAAAA, vBBBB | 将寄存器 vBBBB 中的对象引用赋给寄存去 vAAAA |
0a | 11x | move-result vAA | 将上一个 invoke-kind 指令的单字非对象结果存入寄存器 vAA |
0b | 11x | move-result-wide vAA | 将上一个 invoke-kind 指令的双字非对象结果存入寄存器 vAA,vAA+1 |
0c | 11x | move-result-object vAA | 将上一个 invoke-kind 指令的对象结果存入寄存器 vAA |
0d | 11x | move-exception vAA | 将方法执行过程中抛出的异常存入寄存器 vAA |
0e | 10x | return-void | 返回 void |
0f | 11x | return vAA | 返回 32 位非对象值 |
10 | 11x | return-wide vAA | 返回 64 位非对象值 |
11 | 11x | return-object vAA | 返回对象引用 |
12 | 11n | const/4 vA, #+B | 将给定的 4 位字面值符号扩展为 32 位之后赋给寄存器 vA |
13 | 21s | const/16 vAA, #+BBBB | 将给定的 16 位字面值符号扩展为 32 位之后赋给寄存器 vAA |
14 | 31i | const vAA, #+BBBB | 将给定的字面值赋给寄存器 vAA |
15 | 21h | const/high16 vAA, #+BBBB0000 | 将给定的字面值右零扩展为 32 位之后赋给寄存器 vAA,vAA+1 |
16 | 21s | const-wide/16 vAA, #+BBBB | 将给定的 16 位字面值符号扩展为 64 位之后赋给寄存器 vAA,vAA+1 |
17 | 31i | const-wide/32 vAA, #+BBBBBBBB | 将给定的 32 位字面值符号扩展为 64 位之后赋给寄存器 vAA,vAA+1 |
18 | 51l | const-wide vAA, #+BBBBBBBBBBBBBBBB | 将给定的 64 位字面值赋给寄存器 vAA,vAA+1 |
19 | 21h | const-wide/high16 vAA, #+vBBBB000000000000 | 将给定的 16 位字面值右零扩展为 64 位之后赋给寄存器对 vAA |
1a | 21c | const-string vAA, string@BBBB | 将字符串索引 BBBB 指向的字符串引用赋给寄存器 vAA |
1b | 31c | const-string/jumbo vAA, string@BBBBBBBB | 将字符串索引 BBBBBBBB 指向的字符串引用赋给寄存器 vAA |
1c | 21c | const-class vAA, type@BBBB | 将类型索引 BBBB 指向的类引用赋给寄存器 vAA |
1d | 11x | monitor-enter vAA | 获取寄存器 vAA 中对象的监视锁 |
1e | 11x | monitor-exit vAA | 释放寄存器 vAA 中对象的监视锁 |
1f | 21c | check-cast vAA type@BBBB | 将寄存器 vAA 中的对象引用转化为 type@BBBB 指定的类型,若失败抛出 ClassCastException |
20 | 22c | instance-of vA, vB type@CCCC | 判断寄存器 vB 中的对象引用是否为类型 type@CCCC 的实例。如果是给寄存器 vA 赋值为 1,否则赋值为 0 |
21 | 12x | array-length vA, vB | 获取寄存器 vB 中的数组的长度并赋给寄存器 vA |
22 | 21c | new-instance vAA, type@vBBBB | 构建指定类型 type@BBBB 的实例对象,并将对象引用赋给寄存器 vAA |
23 | 22c | new-array vA, vB, type@CCCC | 构建指定类型 type@CCCC 和指定大小 vB 的数组,并将数组引用赋给寄存器 vA |
24 | 35c | filled-new-array {vC,vD,vE,vF,vG} type@vBBBB | 构建指定类型 type@BBBB 和指定大小的数组,并使用提供的内容 vC-vG 填充数组。由于数组内容是给定的,所以无需再使用一个寄存器 vA 指定数组大小 |
25 | 3rc | filled-new-array/range {vCCCC..vNNNN} type@BBBB | 同上,区别是使用一定范围内的寄存器内容来填充数组,数组大小为 N-C+1 |
26 | 31t | fill-array-data vAA, +BBBB | 使用给定数据 BBBB 填充寄存器 vAA 存储的数组,只能是基本类型数组。BBBB 有特定的格式 |
27 | 11x | throw vAA | 抛出寄存器 vAA 指定的异常 |
28 | 10t | goto +AA | 无条件跳转至指定偏移处,偏移量 AA 为 8 位 |
29 | 20t | goto/16 +AAAA | 无条件跳转至指定偏移处,偏移量 AAAA 为 16 位 |
2a | 30t | goto/32 +AAAAAAAA | 无条件跳转至指定偏移处,偏移量 AAAAAAAA 为 32 位 |
2b | 31t | packed-switch vAA, +BBBBBBBB | 寄存器 vAA 存储的是是希望跳转的偏移量,BBBBBBBB 是一个偏移量表。基于偏移量表查找匹配项,如果存在则跳转,不存在跳转到下一指令 |
2c | 31t | sparse-switch vAA, +BBBBBBBB | |
2d | 23x | cmpl-float vAA, vBB, vCC | 比较两个单精度浮点数。如果寄存器 vBB 的值大于寄存器 vCC 的值,结果为 -1;如果等于,结果为 0;如果小于,结果为 1。NaN 比较返回 -1。结果赋给寄存器 vAA |
2e | 23x | cmpg-float vAA, vBB, vCC | 比较两个单精度浮点数。如果寄存器 vBB 的值大于寄存器 vCC 的值,结果为 1;如果等于,结果为 0;如果小于,结果为 -1。NaN 比较返回 1。结果赋给寄存器 vAA |
2f | 23x | cmpl-double vAA, vBB, vCC | 比较两个双精度浮点数。如果寄存器 vBB 的值大于寄存器 vCC 的值,结果为 -1;如果等于,结果为 0;如果小于,结果为 1。NaN 比较返回 -1。结果赋给寄存器 vAA |
30 | 23x | cmpg-double vAA, vBB, vCC | 比较两个双精度浮点数。如果寄存器 vBB 的值大于寄存器 vCC 的值,结果为 1;如果等于,结果为 0;如果小于,结果为 -1。NaN 比较返回 1。结果赋给寄存器 vAA |
31 | 23x | cmp-long vAA, vBB, vCC | 比较两个长整型数。如果寄存器 vBB 的值大于寄存器 vCC 的值,结果为 1;如果等于,结果为 0;如果小于,结果为 -1。结果赋给寄存器 vAA |
32 | 22t | if-eq vA, vB, +CCCC | 如果寄存器 vA 的值等于 vB 的值,则跳转到指定偏移处,偏移量为 CCCC |
33 | 22t | if-ne vA, vB, +CCCC | 如果寄存器 vA 的值不等于 vB 的值,则跳转到指定偏移处,偏移量为 CCCC |
34 | 22t | if-lt vA, vB, +CCCC | 如果寄存器 vA 的值小于 vB 的值,则跳转到指定偏移处,偏移量为 CCCC |
35 | 22t | if-ge vA, vB, +CCCC | 如果寄存器 vA 的值大于等于 vB 的值,则跳转到指定偏移处,偏移量为 CCCC |
36 | 22t | if-gt vA, vB, +CCCC | 如果寄存器 vA 的值大于 vB 的值,则跳转到指定偏移处,偏移量为 CCCC |
37 | 22t | if-le vA, vB, +CCCC | 如果寄存器 vA 的值小于等于 vB 的值,则跳转到指定偏移处,偏移量为 CCCC |
38 | 21t | if-eqz vAA, +BBBB | 如果寄存器 vAA 的值等于 0,则跳转到指定偏移处,偏移量为 BBBB |
39 | 21t | if-nez vAA, +BBBB | 如果寄存器 vAA 的值不等于 0,则跳转到指定偏移处,偏移量为 BBBB |
3a | 21t | if-ltz vAA, +BBBB | 如果寄存器 vAA 的值小于 0,则跳转到指定偏移处,偏移量为 BBBB |
3b | 21t | if-gez vAA, +BBBB | 如果寄存器 vAA 的值大于等于 0,则跳转到指定偏移处,偏移量为 BBBB |
3c | 21t | if-gtz vAA, +BBBB | 如果寄存器 vAA 的值大于 0,则跳转到指定偏移处,偏移量为 BBBB |
3d | 21t | if-lez vAA, +BBBB | 如果寄存器 vAA 的值小于等于 0,则跳转到指定偏移处,偏移量为 BBBB |
3e | 10x | unused | |
3f | 10x | unused | |
40 | 10x | unused | |
41 | 10x | unused | |
42 | 10x | unused | |
43 | 10x | unused | |
44 | 23x | aget vAA, vBB, vCC | 获取寄存器 vBB 存储的数组指定索引处的元素并赋给寄存器 vAA。寄存器 vCC 的值为指定索引 |
45 | 23x | aget-wide vAA, vBB, vCC | 获取寄存器 vBB 存储的数组指定索引处的元素(64 位)并赋给寄存器对 vAA。寄存器 vCC 的值为指定索引 |
46 | 23x | aget-object vAA, vBB, vCC | 获取寄存器 vBB 存储的对象类型数组指定索引处的元素并赋给寄存器 vAA。寄存器 vCC 的值为指定索引 |
47 | 23x | aget-boolean vAA, vBB, vCC | 获取寄存器 vBB 存储的布尔类型数组指定索引处的元素并赋给寄存器 vAA。寄存器 vCC 的值为指定索引 |
48 | 23x | aget-byte vAA, vBB, vCC | 获取寄存器 vBB 存储的 byte 类型数组指定索引处的元素并赋给寄存器 vAA。寄存器 vCC 的值为指定索引 |
49 | 23x | aget-char vAA, vBB, vCC | 获取寄存器 vBB 存储的 char 类型数组指定索引处的元素并赋给寄存器 vAA。寄存器 vCC 的值为指定索引 |
4a | 23x | aget-short vAA, vBB, vCC | 获取寄存器 vBB 存储的 short 类型数组指定索引处的元素并赋给寄存器 vAA。寄存器 vCC 的值为指定索引 |
4b | 23x | aput vAA, vBB, vCC | 将寄存器 vAA 的值赋给寄存器 vBB 存储的数组的指定索引处。寄存器 vCC 存储的值为指定索引 |
4c | 23x | aput-wide vAA, vBB, vCC | 将寄存器对 vAA 的值(64 位)赋给寄存器 vBB 存储的数组的指定索引处。寄存器 vCC 存储的值为指定索引 |
4d | 23x | aput-object vAA, vBB, vCC | 将寄存器 vAA 存储的对象赋给寄存器 vBB 存储的数组的指定索引处。寄存器 vCC 存储的值为指定索引 |
4e | 23x | aput-boolean vAA, vBB, vCC | 将寄存器 vAA 存储的布尔值赋给寄存器 vBB 存储的数组的指定索引处。寄存器 vCC 存储的值为指定索引 |
4f | 23x | aput-byte vAA, vBB, vCC | 将寄存器 vAA 存储的 byte 值赋给寄存器 vBB 存储的数组的指定索引处。寄存器 vCC 存储的值为指定索引 |
50 | 23x | aput-char vAA, vBB, vCC | 将寄存器 vAA 存储的 char 值赋给寄存器 vBB 存储的数组的指定索引处。寄存器 vCC 存储的值为指定索引 |
51 | 23x | aput-short vAA, vBB, vCC | 将寄存器 vAA 存储的 short 值赋给寄存器 vBB 存储的数组的指定索引处。寄存器 vCC 存储的值为指定索引 |
52 | 22c | iget vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的字段,并存入寄存器 vA。字段类型是 CCCC |
53 | 22c | iget-wide vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的字段,并存入寄存器对 vA。字段类型是 CCCC |
54 | 22c | iget-object vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的对象类型字段,并存入寄存器 vA。字段类型是 CCCC |
55 | 22c | iget-boolean vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的 boolean 类型字段,并存入寄存器 vA。字段类型是 CCCC |
56 | 22c | iget-byte vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的 byte 类型字段,并存入寄存器 vA。字段类型是 CCCC |
57 | 22c | iget-char vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的 char 类型字段,并存入寄存器 vA。字段类型是 CCCC |
58 | 22c | iget-short vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的 short 类型字段,并存入寄存器 vA。字段类型是 CCCC |
59 | 22c | iput vA, vB, field@CCCC | 将寄存器 vA 存储的值赋给寄存器 vB 存储的实例的字段。字段类型是 CCCC |
5a | 22c | iput-wide vA, vB, field@CCCC | 将寄存器对 vA 存储的值(64位)赋给寄存器 vB 存储的实例的字段。字段类型是 CCCC |
5b | 22c | iput-object vA, vB, field@CCCC | 将寄存器 vA 存储的对象类型值赋给寄存器 vB 存储的实例的字段。字段类型是 CCCC |
5c | 22c | iput-boolean vA, vB, field@CCCC | 将寄存器 vA 存储的 boolean 类型值赋给寄存器 vB 存储的实例的字段。字段类型是 CCCC |
5d | 22c | iput-byte vA, vB, field@CCCC | 将寄存器 vA 存储的 byte 类型值赋给寄存器 vB 存储的实例的字段。字段类型是 CCCC |
5e | 22c | iput-char vA, vB, field@CCCC | 将寄存器 vA 存储的 char 类型值赋给寄存器 vB 存储的实例的字段。字段类型是 CCCC |
5f | 22c | iput-short vA, vB, field@CCCC | 将寄存器 vA 存储的 short 类型值赋给寄存器 vB 存储的实例的字段。字段类型是 CCCC |
60 | 21c | sget vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的静态字段,并存入寄存器 vA。字段类型是 CCCC |
61 | 21c | sget-wide vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的静态字段,并存入寄存器对 vA。字段类型是 CCCC |
62 | 21c | sget-object vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的对象类型静态字段,并存入寄存器 vA。字段类型是 CCCC |
63 | 21c | sget-boolean vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的 boolean 类型静态字段,并存入寄存器 vA。字段类型是 CCCC |
64 | 21c | sget-byte vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的 byte 类型静态字段,并存入寄存器 vA。字段类型是 CCCC |
65 | 21c | sget-char vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的 char 类型静态字段,并存入寄存器 vA。字段类型是 CCCC |
66 | 21c | sget-short vA, vB, field@CCCC | 获取寄存器 vB 存储的实例的 short 类型静态字段,并存入寄存器 vA。字段类型是 CCCC |
67 | 21c | sput vA, vB, field@CCCC | 将寄存器 vA 存储的值赋给寄存器 vB 存储的实例的静态字段。字段类型是 CCCC |
68 | 21c | sput-wide vA, vB, field@CCCC | 将寄存器对 vA 存储的值(64位)赋给寄存器 vB 存储的实例的静态字段。字段类型是 CCCC |
69 | 21c | sput-object vA, vB, field@CCCC | 将寄存器 vA 存储的对象类型值赋给寄存器 vB 存储的实例的静态字段。字段类型是 CCCC |
6a | 21c | sput-boolean vA, vB, field@CCCC | 将寄存器 vA 存储的 boolean 类型值赋给寄存器 vB 存储的实例的静态字段。字段类型是 CCCC |
6b | 21c | sput-byte vA, vB, field@CCCC | 将寄存器 vA 存储的 byte 类型值赋给寄存器 vB 存储的实例的静态字段。字段类型是 CCCC |
6c | 21c | sput-char vA, vB, field@CCCC | 将寄存器 vA 存储的 char 类型值赋给寄存器 vB 存储的实例的静态字段。字段类型是 CCCC |
6d | 21c | sput-short vA, vB, field@CCCC | 将寄存器 vA 存储的 short 类型值赋给寄存器 vB 存储的实例的静态字段。字段类型是 CCCC |
6e | 35c | invoke-virtual {vC,vD,vE,vF,vG} meth@BBBB | 调用实例的虚方法,C~G 是参数寄存器 |
6f | 35c | invoke-super {vC,vD,vE,vF,vG} meth@BBBB | 调用实例的父类方法,C~G 是参数寄存器 |
70 | 35c | invoke-direct {vC,vD,vE,vF,vG} meth@BBBB | 调用实例的 private 方法或者构造函数,C~G 是参数寄存器 |
71 | 35c | invoke-static {vC,vD,vE,vF,vG} meth@BBBB | 调用实例的 static 方法,C~G 是参数寄存器 |
72 | 35c | invoke-interface {vC,vD,vE,vF,vG} meth@BBBB | 调用实例的接口方法,C~G 是参数寄存器 |
73 | 10x | unused | |
74 | 3rc | invoke-virtual/range {vCCCC..vNNNN} meth@BBBB | 同上。只是参数寄存器表示方式不一样。这里直接使用 vCCCC 到 vNNNN 之间的寄存器,而不是单独指定每个寄存器 |
75 | 3rc | invoke-super/range {vCCCC..vNNNN} meth@BBBB | |
76 | 3rc | invoke-direct/range {vCCCC..vNNNN} meth@BBBB | |
77 | 3rc | invoke-static/range {vCCCC..vNNNN} meth@BBBB | |
78 | 3rc | invoke-interface/range {vCCCC..vNNNN} meth@BBBB | |
79 | 10x | unused | |
7a | 10x | unused | |
7b | 12x | neg-int vA, vB | 对寄存器 vB 存储的整型数求补并存入寄存器 vA |
7c | 12x | not-int vA, vB | 对寄存器 vB 存储的整型数求反并存入寄存器 vA |
7d | 12x | neg-long vA, vB | 对寄存器对 vB 存储的长整型数求补并存入寄存器对 vA |
7e | 12x | not-long vA, vB | 对寄存器对 vB 存储的长整型数求反并存入寄存器对 vA |
7f | 12x | neg-float vA, vB | 对寄存器 vB 存储的单精度浮点数求补并存入寄存器 vA |
80 | 12x | neg-double vA, vB | 对寄存器对 vB 存储的双精度浮点数求补并存入寄存器对 vA |
81 | 12x | int-to-long vA, vB | 将寄存器 vB 中的整型数转换为长整型数,并存入寄存器对 vA |
82 | 12x | int-to-float vA, vB | 将寄存器 vB 中的整型数转换为单精度浮点数,并存入寄存器 vA |
83 | 12x | int-to-double vA, vB | 将寄存器 vB 中的整型数转换为双精度浮点数,并存入寄存器对 vA |
84 | 12x | long-to-int vA, vB | 将寄存器对 vB 中的长整型数转换为整型数,并存入寄存器 vA |
85 | 12x | long-to-float vA, vB | 将寄存器对 vB 中的长整型数转换为单精度浮点数,并存入寄存器 vA |
86 | 12x | long-to-double vA, vB | 将寄存器对 vB 中的长整型数转换为双精度浮点数,并存入寄存器对 vA |
87 | 12x | float-to-int vA, vB | 将寄存器 vB 中的单精度浮点数转换为整型数,并存入寄存器 vA |
88 | 12x | float-to-long vA, vB | 将寄存器 vB 中的单精度浮点数转换为长整型数,并存入寄存器对 vA |
89 | 12x | float-to-double vA, vB | 将寄存器 vB 中的单精度浮点数转换为双精度浮点数,并存入寄存器 vA |
8a | 12x | double-to-int vA, vB | 将寄存器对 vB 中的双精度浮点数转换为整型数,并存入寄存器 vA |
8b | 12x | double-to-long vA, vB | 将寄存器对 vB 中的双精度浮点数转换为长整型数,并存入寄存器对 vA |
8c | 12x | double-to-float vA, vB | 将寄存器对 vB 中的双精度浮点数转换为单精度浮点数,并存入寄存器 vA |
8d | 12x | int-to-byte vA, vB | 将寄存器对 vB 中的整型数转换为 byte,并存入寄存器 vA |
8e | 12x | int-to-char vA, vB | 将寄存器对 vB 中的整型数转换为 char,并存入寄存器 vA |
8f | 12x | int-to-short vA, vB | 将寄存器对 vB 中的整型数转换为 short,并存入寄存器 vA |
90 | 23x | add-int vAA, vBB, vCC | 将寄存器 vBB 中的整型数加上寄存器 vCC 中的整型数,结果存入寄存器 vAA |
91 | 23x | sub-int vAA, vBB, vCC | 将寄存器 vBB 中的整型数减去寄存器 vCC 中的整型数,结果存入寄存器 vAA |
92 | 23x | mul-int vAA, vBB, vCC | 将寄存器 vBB 中的整型数乘以寄存器 vCC 中的整型数,结果存入寄存器 vAA |
93 | 23x | div-int vAA, vBB, vCC | 将寄存器 vBB 中的整型数除以寄存器 vCC 中的整型数,结果存入寄存器 vAA |
94 | 23x | rem-int vAA, vBB, vCC | 将寄存器 vBB 中的整型数和寄存器 vCC 中的整型数进行模运算,结果存入寄存器 vAA |
95 | 23x | and-int vAA, vBB, vCC | 将寄存器 vBB 中的整型数和寄存器 vCC 中的整型数进行与运算,结果存入寄存器 vAA |
96 | 23x | or-int vAA, vBB, vCC | 将寄存器 vBB 中的整型数和寄存器 vCC 中的整型数进行或运算,结果存入寄存器 vAA |
97 | 23x | xor-int vAA, vBB, vCC | 将寄存器 vBB 中的整型数和寄存器 vCC 中的整型数进行异或运算,结果存入寄存器 vAA |
98 | 23x | shl-int vAA, vBB, vCC | 将寄存器 vBB 中的有符号数左移 vCC 位,结果存入寄存器 vAA |
99 | 23x | shr-int vAA, vBB, vCC | 将寄存器 vBB 中的有符号数右移 vCC 位,结果存入寄存器 vAA |
9a | 23x | ushr-int vAA, vBB, vCC | 将寄存器 vBB 中的无符号数右移 vCC 位,结果存入寄存器 vAA |
9b | 23x | add-long vAA, vBB, vCC | 将寄存器对 vBB 中的长整型数加上寄存器对 vCC 中的长整型数,结果存入寄存器对 vAA |
9c | 23x | sub-long vAA, vBB, vCC | 将寄存器对 vBB 中的长整型数减去寄存器对 vCC 中的长整型数,结果存入寄存器对 vAA |
9d | 23x | mul-long vAA, vBB, vCC | 将寄存器对 vBB 中的长整型数乘以寄存器对 vCC 中的长整型数,结果存入寄存器对 vAA |
9e | 23x | div-long vAA, vBB, vCC | 将寄存器对 vBB 中的长整型数除以寄存器对 vCC 中的长整型数,结果存入寄存器对 vAA |
9f | 23x | rem-long vAA, vBB, vCC | 将寄存器对 vBB 中的长整型数和寄存器对 vCC 中的长整型数进行模运算,结果存入寄存器对 vAA |
a0 | 23x | and-long vAA, vBB, vCC | 将寄存器对 vBB 中的长整型数和寄存器对 vCC 中的长整型数进行与运算,结果存入寄存器对 vAA |
a1 | 23x | or-long vAA, vBB, vCC | 将寄存器对 vBB 中的长整型数和寄存器对 vCC 中的长整型数进行或运算,结果存入寄存器对 vAA |
a2 | 23x | xor-long vAA, vBB, vCC | 将寄存器对 vBB 中的长整型数和寄存器对 vCC 中的长整型数进行异或运算,结果存入寄存器对 vAA |
a3 | 23x | shl-long vAA, vBB, vCC | 将寄存器对 vBB 中的有符号长整型数左移 vCC 位,结果存入寄存器对 vAA |
a4 | 23x | shr-long vAA, vBB, vCC | 将寄存器对 vBB 中的有符号长整型数右移 vCC 位,结果存入寄存器对 vAA |
a5 | 23x | ushr-long vAA, vBB, vCC | 将寄存器对 vBB 中的无符号长整型数右移 vCC 位,结果存入寄存器对 vAA |
a6 | 23x | add-float vAA, vBB, vCC | 将寄存器 vBB 中的单精度浮点数加上寄存器 vCC 中的单精度浮点数,结果存入寄存器 vAA |
a7 | 23x | sub-float vAA, vBB, vCC | 将寄存器 vBB 中的单精度浮点数减去寄存器 vCC 中的单精度浮点数,结果存入寄存器 vAA |
a8 | 23x | mul-float vAA, vBB, vCC | 将寄存器 vBB 中的单精度浮点数乘以寄存器 vCC 中的单精度浮点数,结果存入寄存器 vAA |
a9 | 23x | div-float vAA, vBB, vCC | 将寄存器 vBB 中的单精度浮点数除以寄存器 vCC 中的单精度浮点数,结果存入寄存器 vAA |
aa | 23x | rem-float vAA, vBB, vCC | 将寄存器 vBB 中的单精度浮点数和寄存器 vCC 中的单精度浮点数进行模运算,结果存入寄存器 vAA |
ab | 23x | add-double vAA, vBB, vCC | 将寄存器对 vBB 中的双精度浮点数加上寄存器对 vCC 中的双精度浮点数,结果存入寄存器对 vAA |
ac | 23x | sub-double vAA, vBB, vCC | 将寄存器对 vBB 中的双精度浮点数减去寄存器对 vCC 中的双精度浮点数,结果存入寄存器对 vAA |
ad | 23x | mul-double vAA, vBB, vCC | 将寄存器对 vBB 中的双精度浮点数乘以寄存器对 vCC 中的双精度浮点数,结果存入寄存器对 vAA |
ae | 23x | div-double vAA, vBB, vCC | 将寄存器对 vBB 中的双精度浮点数除以寄存器对 vCC 中的双精度浮点数,结果存入寄存器对 vAA |
af | 23x | rem-double vAA, vBB, vCC | 将寄存器对 vBB 中的双精度浮点数和寄存器对 vCC 中的双精度浮点数进行模运算,结果存入寄存器对 vAA |
b0 | 12x | add-int/2addr vA, vB | 将寄存器 vA 中的整型数加上寄存器 vB 中的整型数,结果存入寄存器 vA |
b1 | 12x | sub-int/2addr vA, vB | 将寄存器 vA 中的整型数减去寄存器 vB 中的整型数,结果存入寄存器 vA |
b2 | 12x | mul-int/2addr vA, vB | 将寄存器 vA 中的整型数乘以寄存器 vB 中的整型数,结果存入寄存器 vA |
b3 | 12x | div-int/2addr vA, vB | 将寄存器 vA 中的整型数除以寄存器 vB 中的整型数,结果存入寄存器 vA |
b4 | 12x | rem-int/2addr vA, vB | 将寄存器 vA 中的整型数和寄存器 vB 中的整型数进行模运算,结果存入寄存器 vA |
b5 | 12x | and-int/2addr vA, vB | 将寄存器 vA 中的整型数和寄存器 vB 中的整型数进行与运算,结果存入寄存器 vA |
b6 | 12x | or-int/2addr vA, vB | 将寄存器 vA 中的整型数和寄存器 vB 中的整型数进行或运算,结果存入寄存器 vA |
b7 | 12x | xor-int/2addr vA, vB | 将寄存器 vA 中的整型数和寄存器 vB 中的整型数进行异或运算,结果存入寄存器 vA |
b8 | 12x | shl-int/2addr vA, vB | 将寄存器 vA 中的有符号数左移 vB 位,结果存入寄存器 vA |
b9 | 12x | shr-int/2addr vA, vB | 将寄存器 vA 中的有符号数右移 vB 位,结果存入寄存器 vA |
ba | 12x | ushr-int/2addr vA, vB | 将寄存器 vA 中的无符号数左移 vB 位,结果存入寄存器 vA |
bb | 12x | add-long/2addr vA, vB | 将寄存器对 vA 中的长整型数加上寄存器对 vB 中的长整型数,结果存入寄存器对 vA |
bc | 12x | sub-long/2addr vA, vB | 将寄存器对 vA 中的长整型数减去寄存器对 vB 中的长整型数,结果存入寄存器对 vA |
bd | 12x | mul-long/2addr vA, vB | 将寄存器对 vA 中的长整型数乘以寄存器对 vB 中的长整型数,结果存入寄存器对 vA |
be | 12x | div-long/2addr vA, vB | 将寄存器对 vA 中的长整型数除以寄存器对 vB 中的长整型数,结果存入寄存器对 vA |
bf | 12x | rem-long/2addr vA, vB | 将寄存器对 vA 中的长整型数和寄存器对 vB 中的长整型数进行模运算,结果存入寄存器对 vA |
c0 | 12x | and-long/2addr vA, vB | 将寄存器对 vA 中的长整型数和寄存器对 vB 中的长整型数进行与运算,结果存入寄存器对 vA |
c1 | 12x | or-long/2addr vA, vB | 将寄存器对 vA 中的长整型数和寄存器对 vB 中的长整型数进行或运算,结果存入寄存器对 vA |
c2 | 12x | xor-long/2addr vA, vB | 将寄存器对 vA 中的长整型数和寄存器对 vB 中的长整型数进异或运算,结果存入寄存器对 vA |
c3 | 12x | shl-long/2addr vA, vB | 将寄存器对 vA 中的有符号长整型数左移 vB 位,结果存入寄存器对 vA |
c4 | 12x | shr-long/2addr vA, vB | 将寄存器对 vA 中的有符号长整型数右移 vB 位,结果存入寄存器对 vA |
c5 | 12x | ushr-long/2addr vA, vB | 将寄存器对 vA 中的无符号长整型数左移 vB 位,结果存入寄存器对 vA |
c6 | 12x | add-float/2addr vA, vB | 将寄存器 vA 中的单精度浮点数加上寄存器 vB 中的单精度浮点数,结果存入寄存器 vA |
c7 | 12x | sub-float/2addr vA, vB | 将寄存器 vA 中的单精度浮点数减去寄存器 vB 中的单精度浮点数,结果存入寄存器 vA |
c8 | 12x | mul-float/2addr vA, vB | 将寄存器 vA 中的单精度浮点数乘以寄存器 vB 中的单精度浮点数,结果存入寄存器 vA |
c9 | 12x | div-float/2addr vA, vB | 将寄存器 vA 中的单精度浮点数除以寄存器 vB 中的单精度浮点数,结果存入寄存器 vA |
ca | 12x | rem-float/2addr vA, vB | 将寄存器 vA 中的单精度浮点数和寄存器 vB 中的单精度浮点数进行模运算,结果存入寄存器 vA |
cb | 12x | add-double/2addr vA, vB | 将寄存器对 vA 中的双精度浮点数加上寄存器对 vB 中的双精度浮点数,结果存入寄存器对 vA |
cc | 12x | sub-double/2addr vA, vB | 将寄存器对 vA 中的双精度浮点数减去寄存器对 vB 中的双精度浮点数,结果存入寄存器对 vA |
cd | 12x | mul-double/2addr vA, vB | 将寄存器对 vA 中的双精度浮点数乘以寄存器对 vB 中的双精度浮点数,结果存入寄存器对 vA |
ce | 12x | div-double/2addr vA, vB | 将寄存器对 vA 中的双精度浮点数除以寄存器对 vB 中的双精度浮点数,结果存入寄存器对 vA |
cf | 12x | rem-double/2addr vA, vB | 将寄存器对 vA 中的双精度浮点数和寄存器对 vB 中的双精度浮点数进行模运算,结果存入寄存器对 vA |
d0 | 22s | add-int/lit16 vA, vB, #+CCCC | 将寄存器 vB 中的整型数和 16 位字面量 CCCC 相加,结果存入寄存器 vA |
d1 | 22s | rsub-int vA, vB, #+CCCC | 将寄存器 vB 中的整型数和 16 位字面量 CCCC 相减,结果存入寄存器 vA |
d2 | 22s | mul-int/lit16 vA, vB, #+CCCC | 将寄存器 vB 中的整型数和 16 位字面量 CCCC 相乘,结果存入寄存器 vA |
d3 | 22s | div-int/lit16 vA, vB, #+CCCC | 将寄存器 vB 中的整型数和 16 位字面量 CCCC 相除,结果存入寄存器 vA |
d4 | 22s | rem-int/lit16 vA, vB, #+CCCC | 将寄存器 vB 中的整型数和 16 位字面量 CCCC 进行模运算,结果存入寄存器 vA |
d5 | 22s | and-int/lit16 vA, vB, #+CCCC | 将寄存器 vB 中的整型数和 16 位字面量 CCCC 进行与运算,结果存入寄存器 vA |
d6 | 22s | or-int/lit16 vA, vB, #+CCCC | 将寄存器 vB 中的整型数和 16 位字面量 CCCC 进行或运算,结果存入寄存器 vA |
d7 | 22s | xor-int/lit16 vA, vB, #+CCCC | 将寄存器 vB 中的整型数和 16 位字面量 CCCC 进行异或运算,结果存入寄存器 vA |
d8 | 22b | add-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的整型数和 8 位字面量 CC 相加,结果存入寄存器 vAA |
d9 | 22b | rsub-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的整型数和 8 位字面量 CC 相减,结果存入寄存器 vAA |
da | 22b | mul-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的整型数和 8 位字面量 CC 相乘,结果存入寄存器 vAA |
db | 22b | div-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的整型数和 8 位字面量 CC 相除,结果存入寄存器 vAA |
dc | 22b | rem-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的整型数和 8 位字面量 CC 进行模运算,结果存入寄存器 vAA |
dd | 22b | and-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的整型数和 8 位字面量 CC 进行与运算,结果存入寄存器 vAA |
de | 22b | or-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的整型数和 8 位字面量 CC 进行或运算,结果存入寄存器 vAA |
df | 22b | xor-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的整型数和 8 位字面量 CC 进行异或运算,结果存入寄存器 vAA |
e0 | 22b | shl-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的有符号数左移 CC 位,将结果存入寄存器 vAA |
e1 | 22b | shr-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的有符号数右移 CC 位,将结果存入寄存器 vAA |
e2 | 22b | ushr-int/lit8 vAA, vBB, #+CC | 将寄存器 vBB 中的无符号数右移 CC 位,将结果存入寄存器 vAA |
e3 | 10x | unused | |
e4 | 10x | unused | |
e5 | 10x | unused | |
e6 | 10x | unused | |
e7 | 10x | unused | |
e8 | 10x | unused | |
e9 | 10x | unused | |
ea | 10x | unused | |
eb | 10x | unused | |
ec | 10x | unused | |
ed | 10x | unused | |
ee | 10x | unused | |
ef | 10x | unused | |
f0 | 10x | unused | |
f1 | 10x | unused | |
f2 | 10x | unused | |
f3 | 10x | unused | |
f4 | 10x | unused | |
f5 | 10x | unused | |
f6 | 10x | unused | |
f7 | 10x | unused | |
f8 | 10x | unused | |
f9 | 10x | unused | |
fa | 45cc | invoke-polymorphic {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH | 调用指定的签名多态方法,存在于 038 和更高版本的 Dex 文件中 |
fb | 4rcc | invoke-polymorphic/range {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH | 调用指定的方法句柄,存在于版本 038 及更高版本的 Dex 文件中 |
fc | 35c | invoke-custom {vC, vD, vE, vF, vG}, call_site@BBBB | 解析并调用指定的调用点,存在于版本 038 及更高版本的 Dex 文件中 |
fd | 3rc | invoke-custom/range {vCCCC .. vNNNN}, call_site@BBBB | 解析并调用一个调用点,存在于版本 038 及更高版本的 Dex 文件中 |
fe | 21c | const-method-handle vAA, method_handle@BBBB | 将通过特定索引指定的方法句柄的引用移到指定的寄存器中,存在于版本 039 及更高版本的 Dex 文件中 |
ff | 21c | const-method-type vAA, proto@BBBB | 将通过特定索引指定的方法原型的引用移到指定的寄存器中。存在于版本 039 及更高版本的 Dex 文件中 |
最后的 fa-ff
由于 DEX 版本问题,其实很少见。