Dalvik虚拟机操作码.docx
《Dalvik虚拟机操作码.docx》由会员分享,可在线阅读,更多相关《Dalvik虚拟机操作码.docx(64页珍藏版)》请在冰豆网上搜索。
Dalvik虚拟机操作码
Dalvik虚拟机操作码
作者:
GaborPaller翻译:
YULIANGMAX
v1.0
表中的vx、vy、vz表示某个Dalvik寄存器。
根据不同指令可以访问16、256或64K寄存器。
表中lit4、lit8、lit16、lit32、lit64表示字面值(直接赋值),数字是值所占用位的长度。
long和double型的值占用两个寄存器,例:
一个在v0寄存器的double值实际占用v0,v1两个寄存器。
boolean值的存储实际是1和0,1为真、0为假;boolean型的值实际是转成int型的值进行操作。
所有例子的字节序都采用高位存储格式,例:
0F000A00的编译为0F,00,0A,00存储。
有一些指令没有说明和例子,因为我没有在正常使用中看到过这些指令,它们的存在是从这里知道的:
Androidopcodeconstantlist。
Opcode
操作码(hex)
Opcodename
操作码名称
Explanation
说明
Example
示例
00
nop
无操作
0000-nop
01
movevx,vy
移动vy的内容到vx。
两个寄存器都必须在最初的256寄存器范围以内。
0110-movev0,v1
移动v1寄存器中的内容到v0。
02
move/from16vx,vy
移动vy的内容到vx。
vy可能在64K寄存器范围以内,而vx则是在最初的256寄存器范围以内。
02001900-move/from16v0,v25
移动v25寄存器中的内容到v0。
03
move/16
未知注4
04
move-wide
未知注4
05
move-wide/from16vx,vy
移动一个long/double值,从vy到vx。
vy可能在64K寄存器范围以内,而vx则是在最初的256寄存器范围以内。
05160000-move-wide/from16v22,v0
移动v0,v1寄存器中的内容到v22,v23。
06
move-wide/16
未知注4
07
move-objectvx,vy
移动对象引用,从vy到vx。
0781-move-objectv1,v8
移动v8寄存器中的对象引用到v1。
08
move-object/from16vx,vy
移动对象引用,从vy到vx。
vy可以处理64K寄存器地址,vx可以处理256寄存器地址。
08011500-move-object/from16v1,v21
移动v21寄存器中的对象引用到v1。
09
move-object/16
未知注4
0A
move-resultvx
移动上一次方法调用的返回值到vx。
0A00-move-resultv0
移动上一次方法调用的返回值到v0。
0B
move-result-widevx
移动上一次方法调用的long/double型返回值到vx,vx+1。
0B02-move-result-widev2
移动上一次方法调用的long/double型返回值到v2,v3。
0C
move-result-objectvx
移动上一次方法调用的对象引用返回值到vx。
0C00-move-result-objectv0
移动上一次方法调用的对象引用返回值到v0。
0D
move-exceptionvx
当方法调用抛出异常时移动异常对象引用到vx。
0D19-move-exceptionv25
当方法调用抛出异常时移动异常对象引用到v25。
0E
return-void
返回空值。
0E00-return-void
返回值为void,即无返回值,并非返回null。
0F
returnvx
返回在vx寄存器的值。
0F00-returnv0
返回v0寄存器中的值。
10
return-widevx
返回在vx,vx+1寄存器的double/long值。
1000-return-widev0
返回v0,v1寄存器中的double/long值。
11
return-objectvx
返回在vx寄存器的对象引用。
1100-return-objectv0
返回v0寄存器中的对象引用。
12
const/4vx,lit4
存入4位常量到vx。
1221-const/4v1,#int2
存入int型常量2到v1。
目的寄存器在第二个字节的低4位,常量2在更高的4位。
13
const/16vx,lit16
存入16位常量到vx。
13000A00-const/16v0,#int10
存入int型常量10到v0。
14
constvx,lit32
存入int型常量到vx。
14004E61BC00-constv0,#12345678//#00BC614E
存入常量12345678到v0。
15
const/high16v0,lit16
存入16位常量到最高位寄存器,用于初始化float值。
15002041-const/high16v0,#float10.0//#41200000
存入float常量10.0到v0。
该指令最高支持16位浮点数。
16
const-wide/16vx,lit16
存入int常量到vx,vx+1寄存器,扩展int型常量为long常量。
16000A00-const-wide/16v0,#long10
存入long常量10到v0,v1寄存器。
17
const-wide/32vx,lit32
存入32位常量到vx,vx+1寄存器,扩展int型常量到long常量。
17024e61bc00-const-wide/32v2,#long12345678//#00bc614e
存入long常量12345678到v2,v3寄存器。
18
const-widevx,lit64
存入64位常量到vx,vx+1寄存器。
1802874b6b5d54dc2b00-const-widev2,#long12345678901234567//#002bdc545d6b4b87
存入long常量12345678901234567到v2,v3寄存器。
19
const-wide/high16vx,lit16
存入16位常量到最高16位的vx,vx+1寄存器,用于初始化double值。
19002440-const-wide/high16v0,#double10.0//#402400000
存入double常量10.0到v0,v1。
1A
const-stringvx,字符串ID
存入字符串常量引用到vx,通过字符串ID或字符串。
1A080000-const-stringv8,""//string@0000
存入string@0000(字符串表#0条目)的引用到v8。
1B
const-string-jumbo
未知注4
1C
const-classvx,类型ID
存入类对象常量到vx,通过类型ID或类型(如Object.class)。
1C000100-const-classv0,Test3//type@0001
存入Test3.class(类型ID表#1条目)的引用到v0。
1D
monitor-entervx
获得vx寄存器中的对象引用的监视器。
1D03-monitor-enterv3
获得v3寄存器中的对象引用的监视器。
1E
monitor-exit
释放vx寄存器中的对象引用的监视器。
1E03-monitor-exitv3
释放v3寄存器中的对象引用的监视器。
1F
check-castvx,类型ID
检查vx寄存器中的对象引用是否可以转换成类型ID对应类型的实例。
如不可转换,抛出ClassCastException异常,否则继续执行。
1F040100-check-castv4,Test3//type@0001
检查v4寄存器中的对象引用是否可以转换成Test3(类型ID表#1条目)的实例。
20
instance-ofvx,vy,类型ID
检查vy寄存器中的对象引用是否是类型ID对应类型的实例,如果是,vx存入非0值,否则vx存入0。
20400100-instance-ofv0,v4,Test3//type@0001
检查v4寄存器中的对象引用是否是Test3(类型ID表#1条目)的实例。
如果是,v0存入非0值,否则v0存入0。
21
array-lengthvx,vy
计算vy寄存器中数组引用的元素长度并将长度存入vx。
2111-array-lengthv0,v1
计算v1寄存器中数组引用的元素长度并将长度存入v0。
22
new-instancevx,类型ID
根据类型ID或类型新建一个对象实例,并将新建的对象的引用存入vx。
22001500-new-instancev0,java.io.FileInputStream//type@0015
实例化java.io.FileInputStream(类型ID表#15H条目)类型,并将其对象引用存入v0。
23
new-arrayvx,vy,类型ID
根据类型ID或类型新建一个数组,vy存入数组的长度,vx存入数组的引用。
23122500-new-arrayv2,v1,char[]//type@0025
新建一个char(类型ID表#25H条目)数组,v1存入数组的长度,v2存入数组的引用。
24
filled-new-array{参数},类型ID
根据类型ID或类型新建一个数组并通过参数填充注5。
新的数组引用可以得到一个move-result-object指令,前提是执行过filled-new-array指令。
2420530D0000-filled-new-array{v0,v0},[I//type@0D53
新建一个int(类型ID表#D53H条目)数组,长度将为2并且2个元素将填充到v0寄存器。
25
filled-new-array-range{vx..vy},类型ID
根据类型ID或类型新建一个数组并以寄存器范围为参数填充。
新的数组引用可以得到一个move-result-object指令,前提是执行过filled-new-array指令。
250306001300-filled-new-array/range{v19..v21},[B//type@0006
新建一个byte(类型ID表#6条目)数组,长度将为3并且3个元素将填充到v19,v20,v21寄存器注4。
26
fill-array-datavx,偏移量
用vx的静态数据填充数组引用。
静态数据的位址是当前指令位置加偏移量的和。
260625000000-fill-array-datav6,00e6//+0025
用当前指令位置+25H的静态数据填充v6寄存器的数组引用。
偏移量是32位的数字,静态数据的存储格式如下:
0003//表类型:
静态数组数据
0400//每个元素的字节数(这个例子是4字节的int型)
03000000//元素个数
01000000//元素#0:
int1
02000000//元素#1:
int2
03000000//元素#2:
int3
27
throwvx
抛出异常对象,异常对象的引用在vx寄存器。
2700-throwv0
抛出异常对象,异常对象的引用在v0寄存器。
28
goto目标
通过短偏移量注2无条件跳转到目标。
28F0-goto0005//-0010
跳转到当前位置-16(hex10)的位置,0005是目标指令标签。
29
goto/16目标
通过16位偏移量注2无条件跳转到目标。
29000FFE-goto/16002f//-01f1
跳转到当前位置-1F1H的位置,002f是目标指令标签。
2A
goto/32目标
通过32位偏移量注2无条件跳转到目标。
2B
packed-switchvx,索引表偏移量
实现一个switch语句,case常量是连续的。
这个指令使用索引表,vx是在表中找到具体case的指令偏移量的索引,如果无法在表中找到vx对应的索引将继续执行下一个指令(即defaultcase)。
2B020C000000-packed-switchv2,000c//+000c
根据v2寄存器中的值执行packedswitch,索引表的位置是当前指令位置+0CH,表如下所示:
0001//表类型:
packedswitch表
0300//元素个数
00000000//基础元素
050000000:
00000005//case0:
+00000005
070000001:
00000007//case1:
+00000007
090000002:
00000009//case2:
+00000009
2C
sparse-switchvx,查询表偏移量
实现一个switch语句,case常量是非连续的。
这个指令使用查询表,用于表示case常量和每个case常量的偏移量。
如果vx无法在表中匹配将继续执行下一个指令(即defaultcase)。
2C020c000000-sparse-switchv2,000c//+000c
根据v2寄存器中的值执行sparseswitch,查询表的位置是当前指令位置+0CH,表如下所示:
0002//表类型:
sparseswitch表
0300//元素个数
9cffffff//第一个case常量:
-100
fa000000//第二个case常量:
250
e8030000//第三个case常量:
1000
05000000//第一个case常量的偏移量:
+5
07000000//第二个case常量的偏移量:
+7
09000000//第三个case常量的偏移量:
+9
2D
cmpl-floatvx,vy,vz
比较vy和vz的float值并在vx存入int型返回值注3。
2D000607-cmpl-floatv0,v6,v7
比较v6和v7的float值并在v0存入int型返回值。
非数值默认为小于。
如果参数为非数值将返回-1。
2E
cmpg-floatvx,vy,vz
比较vy和vz的float值并在vx存入int型返回值注3。
2E000607-cmpg-floatv0,v6,v7
比较v6和v7的float值并在v0存入int型返回值。
非数值默认为大于。
如果参数为非数值将返回1。
2F
cmpl-doublevx,vy,vz
比较vy和vz注2的double值并在vx存入int型返回值注3。
2F190608-cmpl-doublev25,v6,v8
比较v6,v7和v8,v9的double值并在v25存入int型返回值。
非数值默认为小于。
如果参数为非数值将返回-1。
30
cmpg-doublevx,vy,vz
比较vy和vz注2的double值并在vx存入int型返回值注3。
3000080A-cmpg-doublev0,v8,v10
比较v8,v9和v10,v11的double值并在v0存入int型返回值。
非数值默认为大于。
如果参数为非数值将返回1。
31
cmp-longvx,vy,vz
比较vy和vz的long值并在vx存入int型返回值注3。
31000204-cmp-longv0,v2,v4
比较v2和v4的long值并在v0存入int型返回值。
32
if-eqvx,vy,目标
如果vx==vy注2,跳转到目标。
vx和vy是int型值。
32b36600-if-eqv3,v11,0080//+0066
如果v3==v11,跳转到当前位置+66H。
0080是目标指令标签。
33
if-nevx,vy,目标
如果vx!
=vy注2,跳转到目标。
vx和vy是int型值。
33A31000-if-nev3,v10,002c//+0010
如果v3!
=v10,跳转到当前位置+10H。
002c是目标指令标签。
34
if-ltvx,vy,目标
如果vxvx和vy是int型值。
3432CBFF-if-ltv2,v3,0023//-0035
如果v20023是目标指令标签。
35
if-gevx,vy,目标
如果vx>=vy注2,跳转到目标。
vx和vy是int型值。
35101B00-if-gev0,v1,002b//+001b
如果v0>=v1,跳转到当前位置+1BH。
002b是目标指令标签。
36
if-gtvx,vy,目标
如果vx>vy注2,跳转到目标。
vx和vy是int型值。
36101B00-if-gev0,v1,002b//+001b
如果v0>v1,跳转到当前位置+1BH。
002b是目标指令标签。
37
if-levx,vy,目标
如果vx<=vy注2,跳转到目标。
vx和vy是int型值。
37560B00-if-lev6,v5,0144//+000b
如果v6<=v5,跳转到当前位置+0BH。
0144是目标指令标签。
38
if-eqzvx,目标
如果vx==0注2,跳转到目标。
vx是int型值。
38021900-if-eqzv2,0038//+0019
如果v2==0,跳转到当前位置+19H。
0038是目标指令标签。
39
if-nezvx,目标
如果vx!
=0注2,跳转到目标。
39021200-if-nezv2,0014//+0012
如果v2!
=0,跳转到当前位置+18(hex12)。
0014是目标指令标签。
3A
if-ltzvx,目标
如果vx<0注2,跳转到目标。
3A001600-if-ltzv0,002d//+0016
如果v0<0,跳转到当前位置+16H。
002d是目标指令标签。
3B
if-gezvx,目标
如果vx>=0注2,跳转到目标。
3B001600-if-gezv0,002d//+0016
如果v0>=0,跳转到当前位置+16H。
002d是目标指令标签。
3C
if-gtzvx,目标
如果vx>0注2,跳转到目标。
3C001D00-if-gtzv0,004a//+001d
如果v0>0,跳转到当前位置+1DH。
004a是目标指令标签。
3D
if-lezvx,目标
如果vx<=0注2,跳转到目标。
3D001D00-if-lezv0,004a//+001d
如果v0<=0,跳转到当前位置+1DH。
004a是目标指令标签。
3E
unused_3E
未使用
3F
unused_3F
未使用
40
unused_40
未使用
41
unused_41
未使用
42
unused_42
未使用
43
unused_43
未使用
44
agetvx,vy,vz
从int数组获取一个int型值到vx,对象数组的引用位于vy,需获取的元素的索引位于vz。
44070306-agetv7,v3,v6
从数组获取一个int型值到v7,对象数组的引用位于v3,需获取的元素的索引位于v6。
45
aget-widevx,vy,vz
从long/double数组获取一个long/double值到vx,vx+1,数组的引用位于vy,需获取的元素的索引位于vz。
45050104-aget-widev5,v1,v4
从long/double数组获取一个long/double值到v5,vx6,数组的引用位于v1,需获取的元素的索引位于v4。
46
aget-objectvx,vy,vz
从对象引用数组获取一个对象引用到vx,对象数组的引用位于vy,需获取的元素的索引位于vz。
46020200-aget-objectv2,v2,v0
从对象引用数组获取一个对象引用到v2,对象数组的引用位于v2,需获取的元素的索引位于v0。
47
aget-booleanvx,vy,vz
从boolean数组获取一个boolean值到vx,数组的引用位于vy,需获取的元素的索引位于vz。
47000001-aget-booleanv0,v0,v1
从boolean数组获取一个boolean值到v0,数组的引用位于v0,需获取的元素的索引位于v1。
48
aget-bytevx,vy,vz
从byte数组获取一个byte值到vx,数组的引用位于vy,需获取的元素的索引位于vz。
48000001-aget-bytev0,v0,v1
从byte数组获取一个byte值到v0,数组的引用位于v0,需获取的元素的索引位于v1。
49
aget-charvx,vy,vz
从char数组获取一个char值到vx,数组的引用位于vy,需获取的元素的索引位于vz。
49050003-aget-charv5,v0,v3
从char数组获取一个char值到v5,数组的引用位于v0,需获取的元素的索引位于v3。
4A
aget-shortvx,vy,vz
从short数组获取一个short值到vx,数组的引用位于vy,需获取的元素的索引位于vz。
4A000001-aget-shortv0,v0,v1
从short数组获取一个short值到v0,数组的引用位于v0,需获取的元素的索引位于v1。
4B
aputvx,vy,vz
将vx的int值作为元素存入int数组,数组的引用位于vy,元素的索引位于vz。
4B000305-aputv0,v3,v5
将v0的int值作为元素存入int数组,数组的引用位于v3,元素的索引位于v5。
4C
aput-widevx,vy,vz
将vx,vx+1的double/long值作为元素存入double/long数组,数组的引用位于vy,元素的索引位于vz。
4C050104-aput-widev5,v1