smali语法中文版

作者:Gabor Paller    翻译: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型的值进行操作。

所有例子的字节序都采用高位存储格式,例:0F00 0A00的编译为0F, 00, 0A, 00 存储。

有一些指令没有说明和例子,因为我没有在正常使用中看到过这些指令,它们的存在是从这里知道的:Android opcode constant list


Opcode

操作码(hex)


Opcode name

操作码名称


Explanation

说明


Example

示例


00


nop


无操作


0000 - nop


01


move vx, vy


移动vy的内容到vx。两个寄存器都必须在最初的256寄存器范围以内。


0110 - move v0, v1

移动v1寄存器中的内容到v0。


02


move/from16 vx, vy


移动vy的内容到vx。vy可能在64K寄存器范围以内,而vx则是在最初的256寄存器范围以内。


0200 1900 - move/from16 v0, v25

移动v25寄存器中的内容到v0。


03


move/16


未知4

 

04


move-wide


未知4

 

05


move-wide/from16 vx, vy


移动一个long/double值,从vy到vx。vy可能在64K寄存器范围以内,而vx则是在最初的256寄存器范围以内。


0516 0000 - move-wide/from16 v22, v0

移动v0,v1寄存器中的内容到 v22,v23。


06


move-wide/16


未知4

 

07


move-object vx, vy


移动对象引用,从vy到vx。


0781 - move-object v1, v8

移动v8寄存器中的对象引用到v1。


08


move-object/from16 vx, vy


移动对象引用,从vy到vx。vy可以处理64K寄存器地址,vx可以处理256寄存器地址。


0801 1500 - move-object/from16 v1, v21

移动v21寄存器中的对象引用到v1。


09


move-object/16


未知4

 

0A


move-result vx


移动上一次方法调用的返回值到vx。


0A00 - move-result v0

移动上一次方法调用的返回值到v0。


0B


move-result-wide vx


移动上一次方法调用的long/double型返回值到vx,vx+1。


0B02 - move-result-wide v2

移动上一次方法调用的long/double型返回值到v2,v3。


0C


move-result-object vx


移动上一次方法调用的对象引用返回值到vx。


0C00 - move-result-object v0

移动上一次方法调用的对象引用返回值到v0。


0D


move-exception vx


当方法调用抛出异常时移动异常对象引用到vx。


0D19 - move-exception v25

当方法调用抛出异常时移动异常对象引用到v25。


0E


return-void


返回空值。


0E00 - return-void

返回值为void,即无返回值,并非返回null。


0F


return vx


返回在vx寄存器的值。


0F00 - return v0

返回v0寄存器中的值。


10


return-wide vx


返回在vx,vx+1寄存器的double/long值。


1000 - return-wide v0

返回v0,v1寄存器中的double/long值。


11


return-object vx


返回在vx寄存器的对象引用。


1100 - return-object v0

返回v0寄存器中的对象引用。


12


const/4 vx, lit4


存入4位常量到vx。


1221 - const/4 v1, #int 2

存入int型常量2到v1。目的寄存器在第二个字节的低4位,常量2在更高的4位。


13


const/16 vx, lit16


存入16位常量到vx。


1300 0A00 - const/16 v0, #int 10

存入int型常量10到v0。


14


const vx, lit32


存入int 型常量到vx。


1400 4E61 BC00 - const v0, #12345678 // #00BC614E

存入常量12345678到v0。


15


const/high16 v0, lit16


存入16位常量到最高位寄存器,用于初始化float值。


1500 2041 - const/high16 v0, #float 10.0 // #41200000

存入float常量10.0到v0。该指令最高支持16位浮点数。


16


const-wide/16 vx, lit16


存入int常量到vx,vx+1寄存器,扩展int型常量为long常量。


1600 0A00 - const-wide/16 v0, #long 10

存入long常量10到v0,v1寄存器。


17


const-wide/32 vx, lit32


存入32位常量到vx,vx+1寄存器,扩展int型常量到long常量。


1702 4e61 bc00 - const-wide/32 v2, #long 12345678 // #00bc614e

存入long常量12345678到v2,v3寄存器。


18


const-wide vx, lit64


存入64位常量到vx,vx+1寄存器。


1802 874b 6b5d 54dc 2b00- const-wide v2, #long 12345678901234567 // #002bdc545d6b4b87

存入long常量12345678901234567到v2,v3寄存器。


19


const-wide/high16 vx, lit16


存入16位常量到最高16位的vx,vx+1寄存器,用于初始化double 值。


1900 2440 - const-wide/high16 v0, #double 10.0 // #402400000

存入double常量10.0到v0,v1。


1A


const-string vx, 字符串ID


存入字符串常量引用到vx,通过字符串ID字符串


1A08 0000 - const-string v8, "" // [email protected]

存入[email protected](字符串表#0条目)的引用到v8。


1B


const-string-jumbo


未知4

 

1C


const-class vx, 类型ID


存入类对象常量到vx,通过类型ID类型(如Object.class)。


1C00 0100 - const-class v0, Test3 // [email protected]

存入Test3.class(类型ID表#1条目)的引用到v0。


1D


monitor-enter vx


获得vx寄存器中的对象引用的监视器。


1D03 - monitor-enter v3

获得v3寄存器中的对象引用的监视器。


1E


monitor-exit


释放vx寄存器中的对象引用的监视器。


1E03 - monitor-exit v3

释放v3寄存器中的对象引用的监视器。


1F


check-cast vx, 类型ID


检查vx寄存器中的对象引用是否可以转换成类型ID对应类型的实例。如不可转换,抛出ClassCastException 异常,否则继续执行。


1F04 0100 - check-cast v4, Test3 // [email protected]

检查v4寄存器中的对象引用是否可以转换成Test3(类型ID表#1条目)的实例。


20


instance-of vx, vy,类型ID


检查vy寄存器中的对象引用是否是类型ID对应类型的实例,如果是,vx存入非0值,否则vx存入0。


2040 0100 - instance-of v0, v4, Test3 // [email protected]

检查v4寄存器中的对象引用是否是Test3(类型ID表#1条目)的实例。如果是,v0存入非0值,否则v0存入0。


21


array-length vx, vy


计算vy寄存器中数组引用的元素长度并将长度存入vx。


2111 - array-length v0, v1

计算v1寄存器中数组引用的元素长度并将长度存入v0。


22


new-instance vx, 类型ID


根据类型ID类型新建一个对象实例,并将新建的对象的引用存入vx。


2200 1500 - new-instance v0, java.io.FileInputStream // [email protected]

实例化java.io.FileInputStream(类型ID表#15H条目)类型,并将其对象引用存入v0。


23


new-array vx, vy,类型ID


根据类型ID类型新建一个数组,vy存入数组的长度,vx存入数组的引用。


2312 2500 - new-array v2, v1, char[] // [email protected]

新建一个char(类型ID表#25H条目)数组,v1存入数组的长度,v2存入数组的引用。


24


filled-new-array {参数}, 类型ID


根据类型ID类型新建一个数组并通过参数填充5。新的数组引用可以得到一个move-result-object指令,前提是执行过filled-new-array 指令。


2420 530D 0000 - filled-new-array {v0,v0},[I // [email protected]

新建一个int(类型ID表#D53H条目)数组,长度将为2并且2个元素将填充到v0寄存器。


25


filled-new-array-range {vx..vy}, 类型ID


根据类型ID类型新建一个数组并以寄存器范围为参数填充。新的数组引用可以得到一个move-result-object指令,前提是执行过filled-new-array 指令。


2503 0600 1300 - filled-new-array/range {v19..v21}, [B // [email protected]

新建一个byte(类型ID表#6条目)数组,长度将为3并且3个元素将填充到v19,v20,v21寄存器4


26


fill-array-data vx, 偏移量


用vx的静态数据填充数组引用。静态数据的位址是当前指令位置加偏移量的和。


2606 2500 0000 - fill-array-data v6, 00e6 // +0025

用当前指令位置+25H的静态数据填充v6寄存器的数组引用。偏移量是32位的数字,静态数据的存储格式如下:

0003 // 表类型:静态数组数据

0400 // 每个元素的字节数(这个例子是4字节的int型)

0300 0000 // 元素个数

0100 0000 // 元素 #0:int 1

0200 0000 // 元素 #1:int 2

0300 0000 // 元素 #2:int 3


27


throw vx


抛出异常对象,异常对象的引用在vx寄存器。


2700 - throw v0

抛出异常对象,异常对象的引用在v0寄存器。


28


goto 目标


通过短偏移量2无条件跳转到目标


28F0 - goto 0005 // -0010

跳转到当前位置-16(hex 10)的位置,0005是目标指令标签。


29


goto/16目标


通过16位偏移量2无条件跳转到目标


2900 0FFE - goto/16 002f // -01f1

跳转到当前位置-1F1H的位置,002f是目标指令标签。


2A


goto/32目标


通过32位偏移量2无条件跳转到目标

 

2B


packed-switch vx, 索引表偏移量


实现一个switch 语句,case常量是连续的。这个指令使用索引表,vx是在表中找到具体case的指令偏移量的索引,如果无法在表中找到vx对应的索引将继续执行下一个指令(即default case)。


2B02 0C00 0000 - packed-switch v2, 000c // +000c

根据v2寄存器中的值执行packed switch,索引表的位置是当前指令位置+0CH,表如下所示:

0001 // 表类型:packed switch表

0300 // 元素个数

0000 0000 // 基础元素

0500 0000 0: 00000005 // case 0: +00000005

0700 0000 1: 00000007 // case 1: +00000007

0900 0000 2: 00000009 // case 2: +00000009


2C


sparse-switch vx, 查询表偏移量


实现一个switch 语句,case常量是非连续的。这个指令使用查询表,用于表示case常量和每个case常量的偏移量。如果vx无法在表中匹配将继续执行下一个指令(即default case)。


2C02 0c00 0000 - sparse-switch v2, 000c // +000c

根据v2寄存器中的值执行sparse switch ,查询表的位置是当前指令位置+0CH,表如下所示:

0002 // 表类型:sparse switch表

0300 // 元素个数

9cff ffff // 第一个case常量: -100

fa00 0000 // 第二个case常量: 250

e803 0000 // 第三个case常量: 1000

0500 0000 // 第一个case常量的偏移量: +5

0700 0000 // 第二个case常量的偏移量: +7

0900 0000 // 第三个case常量的偏移量: +9


2D


cmpl-float vx, vy, vz


比较vy和vz的float值并在vx存入int型返回值3


2D00 0607 - cmpl-float v0, v6, v7

比较v6和v7的float值并在v0存入int型返回值。非数值默认为小于。如果参数为非数值将返回-1。


2E


cmpg-float vx, vy, vz


比较vy和vz的float值并在vx存入int型返回值3


2E00 0607 - cmpg-float v0, v6, v7

比较v6和v7的float值并在v0存入int型返回值。非数值默认为大于。如果参数为非数值将返回1。


2F


cmpl-double vx, vy, vz


比较vy和vz2的double值并在vx存入int型返回值3


2F19 0608 - cmpl-double v25, v6, v8

比较v6,v7和v8,v9的double值并在v25存入int型返回值。非数值默认为小于。如果参数为非数值将返回-1。


30


cmpg-double vx, vy, vz


比较vy和vz2的double值并在vx存入int型返回值3


3000 080A - cmpg-double v0, v8, v10

比较v8,v9和v10,v11的double值并在v0存入int型返回值。非数值默认为大于。如果参数为非数值将返回1。


31


cmp-long vx, vy, vz


比较vy和vz的long值并在vx存入int型返回值3


3100 0204 - cmp-long v0, v2, v4

比较v2和v4的long值并在v0存入int型返回值。


32


if-eq vx,vy, 目标


如果vx == vy2,跳转到目标。vx和vy是int型值。


32b3 6600 - if-eq v3, v11, 0080 // +0066

如果v3 == v11,跳转到当前位置+66H。0080是目标指令标签。


33


if-ne vx,vy, 目标


如果vx != vy2,跳转到目标。vx和vy是int型值。


33A3 1000 - if-ne v3, v10, 002c // +0010

如果v3 != v10,跳转到当前位置+10H。002c是目标指令标签。


34


if-lt vx,vy, 目标


如果vx < vy2,跳转到目标。vx和vy是int型值。


3432 CBFF - if-lt v2, v3, 0023 // -0035

如果v2 < v3,跳转到当前位置-35H。0023是目标指令标签。


35


if-ge vx, vy, 目标


如果vx >= vy2,跳转到目标。vx和vy是int型值。


3510 1B00 - if-ge v0, v1, 002b // +001b

如果v0 >= v1,跳转到当前位置+1BH。002b是目标指令标签。


36


if-gt vx,vy, 目标


如果vx > vy2,跳转到目标。vx和vy是int型值。


3610 1B00 - if-ge v0, v1, 002b // +001b

如果v0 > v1,跳转到当前位置+1BH。002b是目标指令标签。


37


if-le vx,vy, 目标


如果vx <= vy2,跳转到目标。vx和vy是int型值。


3756 0B00 - if-le v6, v5, 0144 // +000b

如果v6 <= v5,跳转到当前位置+0BH。0144是目标指令标签。


38


if-eqz vx, 目标


如果vx == 02,跳转到目标。vx是int型值。


3802 1900 - if-eqz v2, 0038 // +0019

如果v2 == 0,跳转到当前位置+19H。0038是目标指令标签。


39


if-nez vx, 目标


如果vx != 02,跳转到目标


3902 1200 - if-nez v2, 0014 // +0012

如果v2 != 0,跳转到当前位置+18(hex 12)。0014是目标指令标签。


3A


if-ltz vx, 目标


如果vx < 02,跳转到目标


3A00 1600 - if-ltz v0, 002d // +0016

如果v0 < 0,跳转到当前位置+16H。002d是目标指令标签。


3B


if-gez vx, 目标


如果vx >= 02,跳转到目标


3B00 1600 - if-gez v0, 002d // +0016

如果v0 >= 0,跳转到当前位置+16H。002d是目标指令标签。


3C


if-gtz vx, 目标


如果vx > 02,跳转到目标


3C00 1D00 - if-gtz v0, 004a // +001d

如果v0 > 0,跳转到当前位置+1DH。004a是目标指令标签。


3D


if-lez vx, 目标


如果vx <= 02,跳转到目标


3D00 1D00 - if-lez v0, 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


aget vx, vy, vz


从int数组获取一个int型值到vx,对象数组的引用位于vy,需获取的元素的索引位于vz。


4407 0306 - aget v7, v3, v6

从数组获取一个int型值到v7,对象数组的引用位于v3,需获取的元素的索引位于v6。


45


aget-wide vx, vy, vz


从long/double数组获取一个long/double值到vx,vx+1,数组的引用位于vy,需获取的元素的索引位于vz。


4505 0104 - aget-wide v5, v1, v4

从long/double数组获取一个long/double值到v5,vx6,数组的引用位于v1,需获取的元素的索引位于v4。


46


aget-object vx, vy, vz


从对象引用数组获取一个对象引用到vx,对象数组的引用位于vy,需获取的元素的索引位于vz。


4602 0200 - aget-object v2, v2, v0

从对象引用数组获取一个对象引用到v2,对象数组的引用位于v2,需获取的元素的索引位于v0。


47


aget-boolean vx, vy, vz


从boolean数组获取一个boolean值到vx,数组的引用位于vy,需获取的元素的索引位于vz。


4700 0001 - aget-boolean v0, v0, v1

从boolean数组获取一个boolean值到v0,数组的引用位于v0,需获取的元素的索引位于v1。


48


aget-byte vx, vy, vz


从byte数组获取一个byte值到vx,数组的引用位于vy,需获取的元素的索引位于vz。


4800 0001 - aget-byte v0, v0, v1

从byte数组获取一个byte值到v0,数组的引用位于v0,需获取的元素的索引位于v1。


49


aget-char vx, vy, vz


从char数组获取一个char值到vx,数组的引用位于vy,需获取的元素的索引位于vz。


4905 0003 - aget-char v5, v0, v3

从char数组获取一个char值到v5,数组的引用位于v0,需获取的元素的索引位于v3。


4A


aget-short vx, vy, vz


从short数组获取一个short值到vx,数组的引用位于vy,需获取的元素的索引位于vz。


4A00 0001 - aget-short v0, v0, v1

从short数组获取一个short值到v0,数组的引用位于v0,需获取的元素的索引位于v1。


4B


aput vx, vy, vz


将vx的int值作为元素存入int数组,数组的引用位于vy,元素的索引位于vz。


4B00 0305 - aput v0, v3, v5

将v0的int值作为元素存入int数组,数组的引用位于v3,元素的索引位于v5。


4C


aput-wide vx, vy, vz


将vx,vx+1的double/long值作为元素存入double/long数组,数组的引用位于vy,元素的索引位于vz。


4C05 0104 - aput-wide v5, v1, v4

将v5,v6的double/long值作为元素存入double/long数组,数组的引用位于v1,元素的索引位于v4。


4D


aput-object vx, vy, vz


将vx的对象引用作为元素存入对象引用数组,数组的引用位于vy,元素的索引位于vz。


4D02 0100 - aput-object v2, v1, v0

将v2的对象引用作为元素存入对象引用数组,数组的引用位于v1,元素的索引位于v0。


4E


aput-boolean vx, vy, vz


将vx的boolean值作为元素存入boolean数组,数组的引用位于vy,元素的索引位于vz。


4E01 0002 - aput-boolean v1, v0, v2

将v1的boolean值作为元素存入boolean数组,数组的引用位于v0,元素的索引位于v2。


4F


aput-byte vx, vy, vz


将vx的byte值作为元素存入byte数组,数组的引用位于vy,元素的索引位于vz。


4F02 0001 - aput-byte v2, v0, v1

将v2的byte值作为元素存入byte数组,数组的引用位于v0,元素的索引位于v1。


50


aput-char vx, vy, vz


将vx的char值作为元素存入char数组,数组的引用位于vy,元素的索引位于vz。


5003 0001 - aput-char v3, v0, v1

将v3的char值作为元素存入char数组,数组的引用位于v0,元素的索引位于v1。


51


aput-short vx, vy, vz


将vx的short值作为元素存入short数组,数组的引用位于vy,元素的索引位于vz。


5102 0001 - aput-short v2, v0, v1

将v2的short值作为元素存入short数组,数组的引用位于v0,元素的索引位于v1。


52


iget vx, vy, 字段ID


根据字段ID读取实例的int型字段到vx,vy寄存器中是该实例的引用。


5210 0300 - iget v0, v1, Test2.i6:I // [email protected]

读取int型字段i6(字段表#3条目)到v0,v1寄存器中是Test2实例的引用。


53


iget-wide vx, vy, 字段ID


根据字段ID读取实例的double/long型字段到vx,vx+11,vy寄存器中是该实例的引用。


5320 0400 - iget-wide v0, v2, Test2.l0:J // [email protected]

读取long型字段l0(字段表#4条目)到v0,v1,v2寄存器中是Test2实例的引用。


54


iget-object vx, vy, 字段ID


根据字段ID读取一个实例的对象引用字段到vx,vy寄存器中是该实例的引用。


iget-object v1, v2, LineReader.fis:Ljava/io/FileInputStream; // [email protected]

读取FileInputStream对象引用字段fis(字段表#2条目)到v1,v2寄存器中是LineReader实例的引用。


55


iget-boolean vx, vy, 字段ID


根据字段ID读取实例的boolean型字段到vx,vy寄存器中是该实例的引用。


55FC 0000 - iget-boolean v12, v15, Test2.b0:Z // [email protected]

读取boolean型字段b0(字段表#0条目)到v12,v15寄存器中是Test2实例的引用。


56


iget-byte vx, vy, 字段ID


根据字段ID读取实例的byte型字段到vx,vy寄存器中是该实例的引用。


5632 0100 - iget-byte v2, v3, Test3.bi1:B // [email protected]

读取byte型字段bi1(字段表#1条目)到v2,v3寄存器中是Test2实例的引用。


57


iget-char vx, vy, 字段ID


根据字段ID读取实例的char型字段到vx,vy寄存器中是该实例的引用。


5720 0300 - iget-char v0, v2, Test3.ci1:C // [email protected]

读取char型字段bi1(字段表#3条目)到v0,v2寄存器中是Test2实例的引用。


58


iget-short vx, vy, 字段ID


根据字段ID读取实例的short型字段到vx,vy寄存器中是该实例的引用。


5830 0800 - iget-short v0, v3, Test3.si1:S // [email protected]

读取short型字段si1(字段表#8条目)到v0,v3寄存器中是Test2实例的引用。


59


iput vx, vy, 字段ID


根据字段ID将vx寄存器的值存入实例的int型字段,vy寄存器中是该实例的引用。


5920 0200 - iput v0, v2, Test2.i6:I // [email protected]

将v0寄存器的值存入实例的int型字段i6(字段表#2条目),v2寄存器中是Test2实例的引用。


5A


iput-wide vx, vy, 字段ID


根据字段ID将vx,vx+1寄存器的值存入实例的double/long型字段,vy寄存器中是该实例的引用。


5A20 0000 - iput-wide v0, v2, Test2.d0:D // [email protected]

将v0,v1寄存器的值存入实例的double型字段d0(字段表#0条目),v2寄存器中是Test2实例的引用。


5B


iput-object vx, vy, 字段ID


根据字段ID将vx寄存器的值存入实例的对象引用字段,vy寄存器中是该实例的引用。


5B20 0000 - iput-object v0, v2, LineReader.bis:Ljava/io/BufferedInputStream; // [email protected]

将v0寄存器的值存入实例的对象引用字段bis(字段表#0条目),v2寄存器中是BufferedInputStream实例的引用。


5C


iput-boolean vx, vy, 字段ID


根据字段ID将vx寄存器的值存入实例的boolean型字段,vy寄存器中是该实例的引用。


5C30 0000 - iput-boolean v0, v3, Test2.b0:Z // [email protected]

将v0寄存器的值存入实例的boolean型字段b0(字段表#0条目),v3寄存器中是Test2实例的引用。


5D


iput-byte vx, vy, 字段ID


根据字段ID将vx寄存器的值存入实例的byte型字段,vy寄存器中是该实例的引用。


5D20 0100 - iput-byte v0, v2, Test3.bi1:B // [email protected]

将v0寄存器的值存入实例的byte型字段bi1(字段表#1条目),v2寄存器中是Test2实例的引用。


5E


iput-char vx, vy, 字段ID


根据字段ID将vx寄存器的值存入实例的char型字段,vy寄存器中是该实例的引用。


5E20 0300 - iput-char v0, v2, Test3.ci1:C // [email protected]

将v0寄存器的值存入实例的char型字段ci1(字段表#3条目),v2寄存器中是Test2实例的引用。


5F


iput-short vx, vy, 字段ID


根据字段ID将vx寄存器的值存入实例的short型字段,vy寄存器中是该实例的引用。


5F21 0800 - iput-short v1, v2, Test3.si1:S // [email protected]

将v0寄存器的值存入实例的short型字段si1(字段表#8条目),v2寄存器中是Test2实例的引用。


60


sget vx, 字段ID


根据字段ID读取静态int型字段到vx。


6000 0700 - sget v0, Test3.is1:I // [email protected]

读取Test3的静态int型字段is1(字段表#7条目)到v0。


61


sget-wide vx, 字段ID


根据字段ID读取静态double/long型字段到vx,vx+1。


6100 0500 - sget-wide v0, Test2.l1:J // [email protected]

读取Test2的静态long型字段l1(字段表#5条目)到v0,v1。


62


sget-object vx, 字段ID


根据字段ID读取静态对象引用字段到vx。


6201 0C00 - sget-object v1, Test3.os1:Ljava/lang/Object; // [email protected]

读取Object的静态对象引用字段os1(字段表#CH条目)到v1。


63


sget-boolean vx, 字段ID


根据字段ID读取静态boolean型字段到vx。


6300 0C00 - sget-boolean v0, Test2.sb:Z // [email protected]

读取Test2的静态boolean型字段sb(字段表#CH条目)到v0。


64


sget-byte vx, 字段ID


根据字段ID读取静态byte型字段到vx。


6400 0200 - sget-byte v0, Test3.bs1:B // [email protected]

读取Test3的静态byte型字段bs1(字段表#2条目)到v0。


65


sget-char vx, 字段ID


根据字段ID读取静态char型字段到vx。


6500 0700 - sget-char v0, Test3.cs1:C // [email protected]

读取Test3的静态char型字段cs1(字段表#7条目)到v0。


66


sget-short vx, 字段ID


根据字段ID读取静态short型字段到vx。


6600 0B00 - sget-short v0, Test3.ss1:S // [email protected]

读取Test3的静态short型字段ss1(字段表#CH条目)到v0。


67


sput vx, 字段ID


根据字段ID将vx寄存器中的值赋值到int型静态字段。


6700 0100 - sput v0, Test2.i5:I // [email protected]

将v0寄存器中的值赋值到Test2的int型静态字段i5(字段表#1条目)。


68


sput-wide vx, 字段ID


根据字段ID将vx,vx+1寄存器中的值赋值到double/long型静态字段。


6800 0500 - sput-wide v0, Test2.l1:J // [email protected]

将v0,v1寄存器中的值赋值到Test2的long型静态字段l1(字段表#5条目)。


69


sput-object vx, 字段ID


根据字段ID将vx寄存器中的对象引用赋值到对象引用静态字段。


6900 0c00 - sput-object v0, Test3.os1:Ljava/lang/Object; // [email protected]

将v0寄存器中的对象引用赋值到Test3的对象引用静态字段os1(字段表#CH条目)。


6A


sput-boolean vx, 字段ID


根据字段ID将vx寄存器中的值赋值到boolean型静态字段。


6A00 0300 - sput-boolean v0, Test3.bls1:Z // [email protected]

将v0寄存器中的值赋值到Test3的boolean型静态字段bls1(字段表#3条目)。


6B


sput-byte vx, 字段ID


根据字段ID将vx寄存器中的值赋值到byte型静态字段。


6B00 0200 - sput-byte v0, Test3.bs1:B // [email protected]

将v0寄存器中的值赋值到Test3的byte型静态字段bs1(字段表#2条目)。


6C


sput-char vx, 字段ID


根据字段ID将vx寄存器中的值赋值到char型静态字段。


6C01 0700 - sput-char v1, Test3.cs1:C // [email protected]

将v1寄存器中的值赋值到Test3的char型静态字段cs1(字段表#7条目)。


6D


sput-short vx, 字段ID


根据字段ID将vx寄存器中的值赋值到short型静态字段。


6D00 0B00 - sput-short v0, Test3.ss1:S // [email protected]

将v0寄存器中的值赋值到Test3的short型静态字段ss1(字段表#BH条目)。


6E


invoke-virtual {参数}, 方法名


调用带参数的虚拟方法。


6E53 0600 0421 - invoke-virtual { v4, v0, v1, v2, v3}, Test2.method5:(IIII)V // [email protected]

调用Test2的method5(方法表#6条目)方法,该指令共有5个参数(操作码第二个字节的4个最高有效位5)5。参数v4是"this"实例,v0, v1, v2, v3是method5方法的参数,(IIII)V的4个I分表表示4个int型参数,V表示返回值为void。


6F


invoke-super {参数}, 方法名


调用带参数的直接父类的虚拟方法。


6F10 A601 0100 invoke-super {v1},java.io.FilterOutputStream.close:()V // [email protected]

调用java.io.FilterOutputStream的close(方法表#1A6条目)方法,参数v1是"this"实例。()V表示close方法没有参数,V表示返回值为void。


70


invoke-direct {参数}, 方法名


不解析直接调用带参数的方法。


7010 0800 0100 - invoke-direct {v1}, java.lang.Object.<init>:()V // [email protected]

调用java.lang.Object 的<init>(方法表#8条目)方法,参数v1是"this"实例5。()V表示<init>方法没有参数,V表示返回值为void。


71


invoke-static {参数}, 方法名


调用带参数的静态方法。


7110 3400 0400 - invoke-static {v4}, java.lang.Integer.parseInt:( Ljava/lang/String;)I // [email protected]

调用java.lang.Integer 的parseInt(方法表#34条目)静态方法,该指令只有1个参数v45,(Ljava/lang/String;)I中的Ljava/lang/String;表示parseInt方法需要String类型的参数,I表示返回值为int型。


72


invoke-interface {参数}, 方法名


调用带参数的接口方法。


7240 2102 3154 invoke-interface {v1, v3, v4, v5}, mwfw.IReceivingProtocolAdapter.receivePackage:(ILjava/lang/String;Ljava/io/InputStream;)Z // [email protected]

调用mwfw.IReceivingProtocolAdapter 接口的receivePackage方法(方法表#221条目),该指令共有4个参数5,参数v1是"this"实例,v3,v4,v5是receivePackage方法的参数,(ILjava/lang/String;Ljava/io/InputStream;)Z中的I表示int型参数,Ljava/lang/String;表示String类型参数,Ljava/io/InputStream;表示InputStream类型参数,Z表示返回值为boolean型。


73


unused_73


未使用

 

74


invoke-virtual/range {vx..vy}, 方法名


调用以寄存器范围为参数的虚拟方法。该指令第一个寄存器和寄存器的数量将传递给方法。


7403 0600 1300 - invoke-virtual {v19..v21}, Test2.method5:(IIII)V // [email protected]

调用Test2的method5(方法表#6条目)方法,该指令共有3个参数。参数v19是"this"实例,v20,v21是method5方法的参数,(IIII)V的4个I分表表示4个int型参数,V表示返回值为void。


75


invoke-super/range {vx..vy}, 方法名


调用以寄存器范围为参数的直接父类的虚拟方法。该指令第一个寄存器和寄存器的数量将会传递给方法。


7501 A601 0100 invoke-super {v1},java.io.FilterOutputStream.close:()V // [email protected]

调用java.io.FilterOutputStream的close(方法表#1A6条目)方法,参数v1是"this"实例。()V表示close方法没有参数,V表示返回值为void。


76


invoke-direct/range {vx..vy}, 方法名


不解析直接调用以寄存器范围为参数的方法。该指令第一个寄存器和寄存器的数量将会传递给方法。


7603 3A00 1300 - invoke-direct/range {v19..21},java.lang.Object.<init>:()V // [email protected]

调用java.lang.Object 的<init>(方法表#3A条目)方法,参数v19是"this"实例(操作码第五、第六字节表示范围从v19开始,第二个字节为03表示传入了3个参数),()V表示<init>方法没有参数,V表示返回值为void。


77


invoke-static/range {vx..vy}, 方法名


调用以寄存器范围为参数的静态方法。该指令第一个寄存器和寄存器的数量将会传递给方法。


7703 3A00 1300 - invoke-static/range {v19..21},java.lang.Integer.parseInt:(Ljava/lang/String;)I // [email protected]

调用java.lang.Integer 的parseInt(方法表#34条目)静态方法,参数v19是"this"实例(操作码第五、第六字节表示范围从v19开始,第二个字节为03表示传入了3个参数),(Ljava/lang/String;)I中的Ljava/lang/String;表示parseInt方法需要String类型的参数,I表示返回值为int型。


78


invoke-interface-range {vx..vy}, 方法名


调用以寄存器范围为参数的接口方法。该指令第一个寄存器和寄存器的数量将会传递给方法。


7840 2102 0100 invoke-interface {v1..v4}, mwfw.IReceivingProtocolAdapter.receivePackage:(ILjava/lang/String;Ljava/io/InputStream;)Z // [email protected]

调用mwfw.IReceivingProtocolAdapter 接口的receivePackage方法(方法表#221条目),该指令共有4个参数5,参数v1是"this"实例,v2,v3,v4是receivePackage方法的参数,(ILjava/lang/String;Ljava/io/InputStream;)Z中的I表示int型参数,Ljava/lang/String;表示String类型参数,Ljava/io/InputStream;表示InputStream类型参数,Z表示返回值为boolean型。


79


unused_79


未使用

 

7A


unused_7A


未使用

 

7B


neg-int vx, vy


计算vx = -vy并将结果存入vx。


7B01 - neg-int v1,v0

计算-v0并将结果存入v1。


7C


not-int vx, vy


未知4

 

7D


neg-long vx, vy


计算vx,vx+1 = -(vy,vy+1) 并将结果存入vx,vx+1。


7D02 - neg-long v2,v0

计算-(v0,v1) 并将结果存入(v2,v3)。


7E


not-long vx, vy


未知4

 

7F


neg-float vx, vy


计算vx = -vy并将结果存入vx。


7F01 - neg-float v1,v0

计算-v0并将结果存入v1。


80


neg-double vx, vy


计算vx,vx+1=-(vy,vy+1) 并将结果存入vx,vx+1。


8002 - neg-double v2,v0

计算-(v0,v1) 并将结果存入(v2,v3)。


81


int-to-long vx, vy


转换vy寄存器中的int型值为long型值存入vx,vx+1。


8106 - int-to-long v6, v0

转换v0寄存器中的int型值为long型值存入v6,v7。


82


int-to-float vx, vy


转换vy寄存器中的int型值为float型值存入vx。


8206 - int-to-float v6, v0

转换v0寄存器中的int型值为float型值存入v6。


83


int-to-double vx, vy


转换vy寄存器中的int型值为double型值存入vx,vx+1。


8306 - int-to-double v6, v0

转换v0寄存器中的int型值为double型值存入v6,v7。


84


long-to-int vx, vy


转换vy,vy+1寄存器中的long型值为int型值存入vx。


8424 - long-to-int v4, v2

转换v2,v3寄存器中的long型值为int型值存入v4。


85


long-to-float vx, vy


转换vy,vy+1寄存器中的long型值为float型值存入vx。


8510 - long-to-float v0, v1

转换v1,v2寄存器中的long型值为float型值存入v0。


86


long-to-double vx, vy


转换vy,vy+1寄存器中的long型值为double型值存入vx,vx+1。


8610 - long-to-double v0, v1

转换v1,vy2寄存器中的long型值为double型值存入v0,v1。


87


float-to-int vx, vy


转换vy寄存器中的float型值为int型值存入vx。


8730 - float-to-int v0, v3

转换v3寄存器中的float型值为int型值存入v0。


88


float-to-long vx, vy


转换vy寄存器中的float型值为long型值存入vx,vx+1。


8830 - float-to-long v0, v3

转换v3寄存器中的float型值为long型值存入v0,v1。


89


float-to-double vx, vy


转换vy寄存器中的float型值为double型值存入vx,vx+1。


8930 - float-to-double v0, v3

转换v3寄存器中的float型值为double型值存入v0,v1。


8A


double-to-int vx, vy


转换vy,vy+1寄存器中的double型值为int型值存入vx。


8A40 - double-to-int v0, v4

转换v4,v5寄存器中的double型值为int型值存入v0。


8B


double-to-long vx, vy


转换vy,vy+1寄存器中的double型值为long型值存入vx,vx+1。


8B40 - double-to-long v0, v4

转换v4,v5寄存器中的double型值为long型值存入v0,v1。


8C


double-to-float vx, vy


转换vy,vy+1寄存器中的double型值为float型值存入vx。


8C40 - double-to-float v0, v4

转换v4,v5寄存器中的double型值为float型值存入v0。


8D


int-to-byte vx, vy


转换vy寄存器中的int型值为byte型值存入vx。


8D00 - int-to-byte v0, v0

转换v0寄存器中的int型值为byte型值存入v0。


8E


int-to-char vx, vy


转换vy寄存器中的int型值为char型值存入vx。


8E33 - int-to-char v3, v3

转换v3寄存器中的int型值为char型值存入v3。


8F


int-to-short vx, vy


转换vy寄存器中的int型值为short型值存入vx。


8F00 - int-to-short v3, v0

转换v0寄存器中的int型值为short型值存入v0。


90


add-int vx, vy, vz


计算vy + vz并将结果存入vx。


9000 0203 - add-int v0, v2, v3

计算v2 + v3并将结果存入v04


91


sub-int vx, vy, vz


计算vy - vz并将结果存入vx。


9100 0203 - sub-int v0, v2, v3

计算v2 – v3并将结果存入v0。


92


mul-int vx, vy, vz


计算vy * vz并将结果存入vx。


9200 0203 - mul-int v0,v2,v3

计算v2 * w3并将结果存入v0。


93


div-int vx, vy, vz


计算vy / vz并将结果存入vx。


9303 0001 - div-int v3, v0, v1

计算v0 / v1并将结果存入v3。


94


rem-int vx, vy, vz


计算vy % vz并将结果存入vx。


9400 0203 - rem-int v0, v2, v3

计算v3 % v2并将结果存入v0。


95


and-int vx, vy, vz


计算vy 与 vz并将结果存入vx。


9503 0001 - and-int v3, v0, v1

计算v0 与 v1并将结果存入v3。


96


or-int vx, vy, vz


计算vy 或 vz并将结果存入vx。


9603 0001 - or-int v3, v0, v1

计算v0 或 v1并将结果存入v3。


97


xor-int vx, vy, vz


计算vy 异或 vz并将结果存入vx。


9703 0001 - xor-int v3, v0, v1

计算v0 异或 v1并将结果存入v3。


98


shl-int vx, vy, vz


左移vy,vz指定移动的位置,结果存入vx。


9802 0001 - shl-int v2, v0, v1

以v1指定的位置左移v0,结果存入v2。


99


shr-int vx, vy, vz


右移vy,vz指定移动的位置,结果存入vx。


9902 0001 - shr-int v2, v0, v1

以v1指定的位置右移v0,结果存入v2。


9A


ushr-int vx, vy, vz


无符号右移vy,vz指定移动的位置,结果存入vx。


9A02 0001 - ushr-int v2, v0, v1

以v1指定的位置无符号右移v0,结果存入v2。


9B


add-long vx, vy, vz


计算vy,vy+1 + vz,vz+1并将结果存入vx,vx+11


9B00 0305 - add-long v0, v3, v5

计算v3,v4 + v5,v6并将结果存入v0,v1。


9C


sub-long vx, vy, vz


计算vy,vy+1 - vz,vz+1并将结果存入vx,vx+11


9C00 0305 - sub-long v0, v3, v5

计算v3,v4 - v5,v6并将结果存入v0,v1。


9D


mul-long vx, vy, vz


计算vy,vy+1 * vz,vz+1并将结果存入vx,vx+11


9D00 0305 - mul-long v0, v3, v5

计算v3,v4 * v5,v6并将结果存入v0,v1。


9E


div-long vx, vy, vz


计算vy,vy+1 / vz,vz+1并将结果存入vx,vx+11


9E06 0002 - div-long v6, v0, v2

计算v0,v1 / v2,v3并将结果存入v6,v7。


9F


rem-long vx, vy, vz


计算vy,vy+1 % vz,vz+1并将结果存入vx,vx+11


9F06 0002 - rem-long v6, v0, v2

计算v0,v1 % v2,v3并将结果存入v6,v7。


A0


and-long vx, vy, vz


计算vy,vy+1 与 vz,vz+1并将结果存入vx,vx+11


A006 0002 - and-long v6, v0, v2

计算v0,v1 与 v2,v3并将结果存入v6,v7。


A1


or-long vx, vy, vz


计算vy,vy+1 或 vz,vz+1并将结果存入vx,vx+11


A106 0002 - or-long v6, v0, v2

计算v0,v1 或 v2,v3并将结果存入v6,v7。


A2


xor-long vx, vy, vz


计算vy,vy+1 异或 vz,vz+1并将结果存入vx,vx+11


A206 0002 - xor-long v6, v0, v2

计算v0,v1 异或 v2,v3并将结果存入v6,v7。


A3


shl-long vx, vy, vz


左移vy,vy+1,vz指定移动的位置,结果存入vx,vx+11


A302 0004 - shl-long v2, v0, v4

以v4指定的位置左移v0,v1,结果存入v2,v3。


A4


shr-long vx, vy, vz


右移vy,vy+1,vz指定移动的位置,结果存入vx,vx+11


A402 0004 - shr-long v2, v0, v4

以v4指定的位置右移v0,v1,结果存入v2,v3。


A5


ushr-long vx, vy, vz


无符号右移vy,vy+1,vz指定移动的位置,结果存入vx,vx+11


A502 0004 - ushr-long v2, v0, v4

以v4指定的位置无符号右移v0,v1,结果存入v2,v3。


A6


add-float vx, vy, vz


计算vy + vz并将结果存入vx。


A600 0203 - add-float v0, v2, v3

计算v2 + v3并将结果存入v0。


A7


sub-float vx, vy, vz


计算vy - vz并将结果存入vx。


A700 0203 - sub-float v0, v2, v3

计算v2 - v3并将结果存入v0。


A8


mul-float vx, vy, vz


计算vy * vz并将结果存入vx。


A803 0001 - mul-float v3, v0, v1

计算v0 * v1并将结果存入v3。


A9


div-float vx, vy, vz


计算vy / vz并将结果存入vx。


A903 0001 - div-float v3, v0, v1

计算v0 / v1并将结果存入v3。


AA


rem-float vx, vy, vz


计算vy % vz并将结果存入vx。


AA03 0001 - rem-float v3, v0, v1

计算v0 % v1并将结果存入v3。


AB


add-double vx, vy, vz


计算vy,vy+1 + vz,vz+1并将结果存入vx,vx+11


AB00 0305 - add-double v0, v3, v5

计算v3,v4 + v5,v6并将结果存入v0,v1。


AC


sub-double vx, vy, vz


计算vy,vy+1 - vz,vz+1并将结果存入vx,vx+11


AC00 0305 - sub-double v0, v3, v5

计算v3,v4 - v5,v6并将结果存入v0,v1。


AD


mul-double vx, vy, vz


计算vy,vy+1 * vz,vz+1并将结果存入vx,vx+11


AD06 0002 - mul-double v6, v0, v2

计算v0,v1 * v2,v3并将结果存入v6,v7。


AE


div-double vx, vy, vz


计算vy,vy+1 / vz,vz+1并将结果存入vx,vx+11


AE06 0002 - div-double v6, v0, v2

计算v0,v1 / v2,v3并将结果存入v6,v7。


AF


rem-double vx, vy, vz


计算vy,vy+1 % vz,vz+1并将结果存入vx,vx+11


AF06 0002 - rem-double v6, v0, v2

计算v0,v1 % v2,v3并将结果存入v6,v7。


B0


add-int/2addr vx, vy


计算vx + vy并将结果存入vx。


B010 - add-int/2addr v0,v1

计算v0 + v1并将结果存入v0。


B1


sub-int/2addr vx, vy


计算vx - vy并将结果存入vx。


B140 - sub-int/2addr v0, v4

计算v0 – v4并将结果存入v0。


B2


mul-int/2addr vx, vy


计算vx * vy并将结果存入vx。


B210 - mul-int/2addr v0, v1

计算v0 * v1并将结果存入v0。


B3


div-int/2addr vx, vy


计算vx / vy并将结果存入vx。


B310 - div-int/2addr v0, v1

计算v0 / v1并将结果存入v0。


B4


rem-int/2addr vx, vy


计算vx % vy并将结果存入vx。


B410 - rem-int/2addr v0, v1

计算v0 % v1并将结果存入v0。


B5


and-int/2addr vx, vy


计算vx 与 vy并将结果存入vx。


B510 - and-int/2addr v0, v1

计算v0 与 v1并将结果存入v0。


B6


or-int/2addr vx, vy


计算vx 或 vy并将结果存入vx。


B610 - or-int/2addr v0, v1

计算v0 或 v1并将结果存入v0。


B7


xor-int/2addr vx, vy


计算vx 异或 vy并将结果存入vx。


B710 - xor-int/2addr v0, v1

计算v0 异或 v1并将结果存入v0。


B8


shl-int/2addr vx, vy


左移vx,vy指定移动的位置,并将结果存入vx。


B810 - shl-int/2addr v0, v1

以v1指定的位置左移v0,结果存入v0。


B9


shr-int/2addr vx, vy


右移vx,vy指定移动的位置,并将结果存入vx。


B910 - shr-int/2addr v0, v1

以v1指定的位置右移v0,结果存入v0。


BA


ushr-int/2addr vx, vy


无符号右移vx,vy指定移动的位置,并将结果存入vx。


BA10 - ushr-int/2addr v0, v1

以v1指定的位置无符号右移v0,结果存入v0。


BB


add-long/2addr vx, vy


计算vx,vx+1 + vy,vy+1并将结果存入vx,vx+11


BB20 - add-long/2addr v0, v2

计算v0,v1 + v2,v3并将结果存入v0,v1。


BC


sub-long/2addr vx, vy


计算vx,vx+1 - vy,vy+1并将结果存入vx,vx+11


BC70 - sub-long/2addr v0, v7

计算v0,v1 - v7,v8并将结果存入v0,v1。


BD


mul-long/2addr vx, vy


计算vx,vx+1 * vy,vy+1并将结果存入vx,vx+11


BD70 - mul-long/2addr v0, v7

计算v0,v1 * v7,v8并将结果存入v0,v1。


BE


div-long/2addr vx, vy


计算vx,vx+1 / vy,vy+1并将结果存入vx,vx+11


BE20 - div-long/2addr v0, v2

计算v0,v1 / v2,v3并将结果存入v0,v1。


BF


rem-long/2addr vx, vy


计算vx,vx+1 % vy,vy+1并将结果存入vx,vx+11


BF20 - rem-long/2addr v0, v2

计算v0,v1 % v2,v3并将结果存入v0,v1。


C0


and-long/2addr vx, vy


计算vx,vx+1 与 vy,vy+1并将结果存入vx,vx+11


C020 - and-long/2addr v0, v2

计算v0,v1 与 v2,v3并将结果存入v0,v1。


C1


or-long/2addr vx, vy


计算vx,vx+1 或 vy,vy+1并将结果存入vx,vx+11


C120 - or-long/2addr v0, v2

计算v0,v1 或 v2,v3并将结果存入v0,v1。


C2


xor-long/2addr vx, vy


计算vx,vx+1 异或 vy,vy+1并将结果存入vx,vx+11


C220 - xor-long/2addr v0, v2

计算v0,v1 异或 v2,v3并将结果存入v0,v1。


C3


shl-long/2addr vx, vy


左移vx,vx+1,vy指定移动的位置,并将结果存入vx,vx+1。


C320 - shl-long/2addr v0, v2

以v2指定的位置左移v0,v1,结果存入v0,v1。


C4


shr-long/2addr vx, vy


右移vx,vx+1,vy指定移动的位置,并将结果存入vx,vx+1。


C420 - shr-long/2addr v0, v2

以v2指定的位置右移v0,v1,结果存入v0,v1。


C5


ushr-long/2addr vx, vy


无符号右移vx,vx+1,vy指定移动的位置,并将结果存入vx,vx+1。


C520 - ushr-long/2addr v0, v2

以v2指定的位置无符号右移v0,v1,结果存入v0,v1。


C6


add-float/2addr vx, vy


计算vx + vy并将结果存入vx。


C640 - add-float/2addr v0,v4

计算v0 + v4并将结果存入v0。


C7


sub-float/2addr vx, vy


计算vx - vy并将结果存入vx。


C740 - sub-float/2addr v0,v4

计算v0 - v4并将结果存入v0。


C8


mul-float/2addr vx, vy


计算vx * vy并将结果存入vx。


C810 - mul-float/2addr v0, v1

计算v0 * v1并将结果存入v0。


C9


div-float/2addr vx, vy


计算vx / vy并将结果存入vx。


C910 - div-float/2addr v0, v1

计算v0 / v1并将结果存入v0。


CA


rem-float/2addr vx, vy


计算vx % vy并将结果存入vx。


CA10 - rem-float/2addr v0, v1

计算v0 % v1并将结果存入v0。


CB


add-double/2addr vx, vy


计算vx,vx+1 + vy,vy+1并将结果存入vx,vx+11


CB70 - add-double/2addr v0, v7

计算v0,v1 + v7,v8并将结果存入v0,v1。


CC


sub-double/2addr vx, vy


计算vx,vx+1 - vy,vy+1并将结果存入vx,vx+11


CC70 - sub-double/2addr v0, v7

计算v0,v1 - v7,v8并将结果存入v0,v1。


CD


mul-double/2addr vx, vy


计算vx,vx+1 * vy,vy+1并将结果存入vx,vx+11


CD20 - mul-double/2addr v0, v2

计算v0,v1 * v2,v3并将结果存入v0,v1。


CE


div-double/2addr vx, vy


计算vx,vx+1 / vy,vy+1并将结果存入vx,vx+11


CE20 - div-double/2addr v0, v2

计算v0,v1 / v2,v3并将结果存入v0,v1。


CF


rem-double/2addr vx, vy


计算vx,vx+1 % vy,vy+1并将结果存入vx,vx+11


CF20 - rem-double/2addr v0, v2

计算v0,v1 % v2,v3并将结果存入v0,v1。


D0


add-int/lit16 vx, vy, lit16


计算vy + lit16并将结果存入vx。


D001 D204 - add-int/lit16 v1, v0, #int 1234 // #04d2

计算v0 + 1234并将结果存入v1。


D1


sub-int/lit16 vx, vy, lit16


计算vy - lit16并将结果存入vx。


D101 D204 - sub-int/lit16 v1, v0, #int 1234 // #04d2

计算v0 - 1234并将结果存入v1。


D2


mul-int/lit16 vx, vy, lit16


计算vy * lit16并将结果存入vx。


D201 D204 - mul-int/lit16 v1, v0, #int 1234 // #04d2

计算v0 * 1234并将结果存入v1。


D3


div-int/lit16 vx, vy, lit16


计算vy / lit16并将结果存入vx。


D301 D204 - div-int/lit16 v1, v0, #int 1234 // #04d2

计算v0 / 1234并将结果存入v1。


D4


rem-int/lit16 vx, vy, lit16


计算vy % lit16并将结果存入vx。


D401 D204 - rem-int/lit16 v1, v0, #int 1234 // #04d2

计算v0 % 1234并将结果存入v1。


D5


and-int/lit16 vx, vy, lit16


计算vy 与 lit16并将结果存入vx。


D501 D204 - and-int/lit16 v1, v0, #int 1234 // #04d2

计算v0 与 1234并将结果存入v1。


D6


or-int/lit16 vx, vy, lit16


计算vy 或 lit16并将结果存入vx。


D601 D204 - or-int/lit16 v1, v0, #int 1234 // #04d2

计算v0 或 1234并将结果存入v1。


D7


xor-int/lit16 vx, vy, lit16


计算vy 异或 lit16并将结果存入vx。


D701 D204 - xor-int/lit16 v1, v0, #int 1234 // #04d2

计算v0 异或 1234并将结果存入v1。


D8


add-int/lit8 vx, vy, lit8


计算vy + lit8并将结果存入vx。


D800 0201 - add-int/lit8 v0,v2, #int1

计算v2 + 1并将结果存入v0。


D9


sub-int/lit8 vx, vy, lit8


计算vy - lit8并将结果存入vx。


D900 0201 - sub-int/lit8 v0,v2, #int1

计算v2 - 1并将结果存入v0。


DA


mul-int/lit8 vx, vy, lit8


计算vy * lit8并将结果存入vx。


DA00 0002 - mul-int/lit8 v0,v0, #int2

计算v0 * 2并将结果存入v0。


DB


div-int/lit8 vx, vy, lit8


计算vy / lit8并将结果存入vx。


DB00 0203 - mul-int/lit8 v0,v2, #int3

计算v2 / 3并将结果存入v0。


DC


rem-int/lit8 vx, vy, lit8


计算vy % lit8并将结果存入vx。


DC00 0203 - rem-int/lit8 v0,v2, #int3

计算v2 % 3并将结果存入v0。


DD


and-int/lit8 vx, vy, lit8


计算vy 与 lit8并将结果存入vx。


DD00 0203 - and-int/lit8 v0,v2, #int3

计算v2 与 3并将结果存入v0。


DE


or-int/lit8 vx, vy, lit8


计算vy 或 lit8并将结果存入vx。


DE00 0203 - or-int/lit8 v0, v2, #int 3

计算v2 或 3并将结果存入v0。


DF


xor-int/lit8 vx, vy, lit8


计算vy异或lit8并将结果存入vx。


DF00 0203 | 0008: xor-int/lit8 v0, v2, #int 3

计算v2 异或 3并将结果存入v0。


E0


shl-int/lit8 vx, vy, lit8


左移vy,lit8指定移动的位置,并将结果存入vx。


E001 0001 - shl-int/lit8 v1, v0, #int 1

将v0左移1位,结果存入v1。


E1


shr-int/lit8 vx, vy, lit8


右移vy,lit8指定移动的位置,并将结果存入vx。


E101 0001 - shr-int/lit8 v1, v0, #int 1

将v0右移1位,结果存入v1。


E2


ushr-int/lit8 vx, vy, lit8


无符号右移vy,lit8指定移动的位置,并将结果存入vx。


E201 0001 - ushr-int/lit8 v1, v0, #int 1

将v0无符号右移1位,结果存入v1。


E3


unused_E3


未使用

 

E4


unused_E4


未使用

 

E5


unused_E5


未使用

 

E6


unused_E6


未使用

 

E7


unused_E7


未使用

 

E8


unused_E8


未使用

 

E9


unused_E9


未使用

 

EA


unused_EA


未使用

 

EB


unused_EB


未使用

 

EC


unused_EC


未使用

 

ED


unused_ED


未使用

 

EE


execute-inline {参数}, 内联ID


根据内联ID6执行内联方法。


EE20 0300 0100 - execute-inline {v1, v0}, inline #0003

执行内联方法#3,参数v1,v0,其中参数v1为"this"的实例,v0是方法的参数。


EF


unused_EF


未使用

 

F0


invoke-direct-empty


用于空方法的占位符,如Object.<init>。这相当于正常执行了nop指令6


F010 F608 0000 - invoke-direct-empty {v0}, Ljava/lang/Object;.<init>:()V // [email protected]

替代空方法java/lang/Object;<init>。


F1


unused_F1


未使用

 

F2


iget-quick vx, vy, 偏移量


获取vy寄存器中实例指向+偏移位置的数据区的值,存入vx6


F221 1000 - iget-quick v1, v2, [obj+0010]

获取v2寄存器中的实例指向+10H位置的数据区的值,存入v1。


F3


iget-wide-quick vx, vy, 偏移量


获取vy寄存器中实例指向+偏移位置的数据区的值,存入vx,vx+16


F364 3001 - iget-wide-quick v4, v6, [obj+0130]

获取v6寄存器中的实例指向+130H位置的数据区的值,存入v4,v5。


F4


iget-object-quick vx, vy, 偏移量


获取vy寄存器中实例指向+偏移位置的数据区的对象引用,存入vx6


F431 0C00 - iget-object-quick v1, v3, [obj+000c]

获取v3寄存器中的实例指向+0CH位置的数据区的对象引用,存入v1。


F5


iput-quick vx, vy, 偏移量


将vx寄存器中的值存入vy寄存器中的实例指向+偏移位置的数据区6


F521 1000 - iput-quick v1, v2, [obj+0010]

将v1寄存器中的值存入v2寄存器中的实例指向+10H位置的数据区。


F6


iput-wide-quick vx, vy, 偏移量


将vx,vx+1寄存器中的值存入vy寄存器中的实例指向+偏移位置的数据区6


F652 7001 - iput-wide-quick v2, v5, [obj+0170]

将v2,v3寄存器中的值存入v5寄存器中的实例指向+170H位置的数据区。


F7


iput-object-quick vx, vy, 偏移量


将vx寄存器中的对象引用存入vy寄存器中的实例指向+偏移位置的数据区6


F701 4C00 - iput-object-quick v1, v0, [obj+004c]

将v1寄存器中的对象引用存入v0寄存器中的实例指向+4CH位置的数据区。


F8


invoke-virtual-quick {参数}, 虚拟表偏移量


调用虚拟方法,使用目标对象虚拟表6


F820 B800 CF00 - invoke-virtual-quick {v15, v12}, vtable #00b8

调用虚拟方法,目标对象的实例指向位于v15寄存器,方法位于虚拟表#B8条目,方法所需的参数位于v12。


F9


invoke-virtual-quick/range {参数范围}, 虚拟表偏移量


调用虚拟方法,使用目标对象虚拟表6


F906 1800 0000 - invoke-virtual-quick/range {v0..v5},vtable #0018

调用虚拟方法,目标对象的实例指向位于v0寄存器,方法位于虚拟表#18H条目,方法所需的参数位于v1..v5。


FA


invoke-super-quick {参数}, 虚拟表偏移量


调用父类虚拟方法,使用目标对象的直接父类的虚拟表6


FA40 8100 3254 - invoke-super-quick {v2, v3, v4, v5}, vtable #0081

调用父类虚拟方法,目标对象的实例指向位于v2寄存器,方法位于虚拟表#81H条目,方法所需的参数位于v3,v4,v5。


FB


invoke-super-quick/range {参数范围}, 虚拟表偏移量


调用父类虚拟方法,使用目标对象的直接父类的虚拟表6


F906 1B00 0000 - invoke-super-quick/range {v0..v5}, vtable #001b

调用父类虚拟方法,目标对象的实例指向位于v0寄存器,方法位于虚拟表#1B条目,方法所需的参数位于v1..v5。


FC


unused_FC


未使用

 

FD


unused_FD


未使用

 

FE


unused_FE


未使用

 

FF


unused_FF


未使用

 

注1:   Double和long值占用两个寄存器。(例:在vy地址上的值位于vy,vy+1寄存器)

注2:   偏移量可以是正或负,从指令起始字节起计算偏移量。偏移量在(2字节每1偏移量递增/递减)时解释执行。负偏移量用二进制补码格式存储。偏移量当前位置是指令起始字节。

注3:   比较操作,如果第一个操作数大于第二个操作数返回正值;如果两者相等,返回0;如果第一个操作数小于第二个操作数,返回负值。

注4:   正常使用没见到过的,从Android opcode constant list引入。

注5:   调用参数表的编译比较诡异。如果参数的数量大于4并且%4=1,第5(第9或其他%4=1的)个参数将编译在指令字节的下一个字节的4个最低位。奇怪的是,有一种情况不使用这种编译:方法有4个参数但用于编译单一参数,指令字节的下一个字节的4个最低位空置,将会编译为40而不是04。

注6:   这是一个不安全的指令,仅适用于ODEX文件。

时间: 2024-11-06 16:05:36

smali语法中文版的相关文章

Smali语法简单介绍

Smali语言其实就是Davlik的寄存器语言: Smali语言就是android的应用程序.apk通过apktool反编译出来的都有一个smali文件夹,里面都是以.smali结尾的文件,文件的展示语言. Smali语法简单介绍如下: Davlik字节码中,寄存器都是32位的,能够支持任何类型,64位类型(Long/Double)用2个寄存器表示: Dalvik字节码有两种类型:原始类型:引用类型(包括对象和数组)   原始类型:v   void  只能用于返回值类型 Z   boolean

smali语法小结

smali语言是Davlik的寄存器语言,语法上和汇编语言相似,Dalvik VM与JVM的最大的区别之一就是Dalvik VM是基于寄存器的.基于寄存器的意思是,在smali里的所有操作都必须经过寄存器来进行.Link Smali-数据类型 Davlik字节码中,寄存器都是32位的,能够支持任何类型,64位类型(Long/Double)用2个寄存器表示.Dalvik字节码有两种类型:原始类型:引用类型(包括对象和数组)@link. M1.基本数据类型 V void Z boolean B by

apk反汇编之smali语法

类型 Dalvik的字节码中拥有两个主要的类型:基类和引用类型.引用类型 引用类型是对象和数组,其他的一切都是基类   基类被一个简单的字符描述.我没有提出这些缩写词———他们实际以字符串的形式存储于dex文件中 他们被定义与dex格式网页文档中(在AOSP库中的路径是dalvik/docs/dex-format.html) V  空类型---仅仅可以用来作为返回类型 Z  Boolean 布尔型 B  Byte字节型 S  Short短整型(16位) C  Char字符型 I  Int 整形

Smali语法

看阿里巴巴的<深入探索Android热修复>,里面的代码看不懂,一查才知道是Smali语法,百度了语法,转载如下 转载自smali 语言语法 1.smali apk文件通过apktool反编译出来的都有一个smali文件夹,里面都是以.smali结尾的文件.smali语言是Davlik的寄存器语言,语法上和汇编语言相似,Dalvik VM与JVM的最大的区别之一就是Dalvik VM是基于寄存器的.基于寄存器的意思是,在smali里的所有操作都必须经过寄存器来进行. 2.基本数据类型 B-by

安卓破解软件需懂的Smali语法

Smali中语法: 类型 v   void  只能用于返回值类型 Z   boolean B   byte S   short C   char I    int J    long 2个寄存器 F   float D   double  2个寄存器 对象类型:Lpackage/name/ObjectName;  相当于java中的package.name.ObjectName;解释如下: L:表示这是一个对象类型 package/name:该对象所在的包 ::表示对象名称的结束 数组的表示形式

Markdown语法 (中文版)

 Markdown语法  Markdown是一种可以使用普通文本编辑器编写的标记语言,通过类似HTML的标记语法,它可以使普通文本内容具有一定的格式. Markdown具有一系列衍生版本,用于扩展Markdown的功能(如表格.脚注.内嵌HTML等等),这些功能原初的Markdown尚不具备,它们能让Markdown转换成更多的格式,例如LaTeX,Docbook.Markdown增强版中比较有名的有Markdown Extra.MultiMarkdown. Maruku等.这些衍生版本要么基于

smali语法积累记录

1.constructor 我们知道运行一个类的时候会先调用static方法中的内容,比如: static { System.loadLibrary("qihooTest"); } 为什么呢? 上面这段代码用smali语言写出来是这样的: .method static constructor <clinit>()V #不带参数的构造方法 .locals 1 .prologue .line 64 const-string v0, "qihooTest" i

Markdown语法中文版

文章翻译自Markdown创始人JOHN GRUBER的 个人博客, 英文原文请参见 Markdown Syntax; 原文是用Markdown格式写的, 但是cnblogs不支持Markdown(或者是我不知道), 只能重新排版了, Github原文可以参见这里; 个人水平有限, 如有发现错误, 欢迎通过Github 或者 @乔的果园 联系我修改, 谢谢! 如果您不介意, 欢迎关注我的 微信公众号; 文章是直译的, 难免会有一些晦涩, 望见谅, 对于一些专有名词直译过程中我们约定如下: Bol

smali语法(二)

一.smali的包中信息 .class public Lcom/aaaaa; .super Lcom/bbbbb; .source "ccccc.java" 1.它是com.aaaaa这个package下的类 2.继承自com.bbbbb 3.由ccccc.java编译得到的smali文件 二.smali中的声明 # annotations .annotation system Ldalvik/annotation/MemberClasses; value = {Lcom/aaa$qq