• 安卓逆向——smali语法


    Dalvik虚拟机操作码

    作者:Gabor Paller    翻译:YULIANGMAX

    v1.0

    表中的vxvyvz表示某个Dalvik寄存器。根据不同指令可以访问1625664K寄存器。

    表中lit4lit8lit16lit32lit64表示字面值(直接赋值),数字是值所占用位的长度。

    longdouble型的值占用两个寄存器,例:一个在v0寄存器的double值实际占用v0,v1两个寄存器。

    boolean值的存储实际是101为真、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的内容到vxvy可能在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值,从vyvxvy可能在64K寄存器范围以内,而vx则是在最初的256寄存器范围以内。

    0516 0000 - move-wide/from16 v22, v0

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

    06

    move-wide/16

    未知4

     

    07

    move-object vx, vy

    移动对象引用,从vyvx

    0781 - move-object v1, v8

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

    08

    move-object/from16 vx, vy

    移动对象引用,从vyvxvy可以处理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型常量2v1目的寄存器在第二个字节的低4位,常量2在更高的4位。

    13

    const/16 vx, lit16

    存入16位常量到vx

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

    存入int型常量10v0

    14

    const vx, lit32

    存入int 型常量到vx

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

    存入常量12345678v0

    15

    const/high16 v0, lit16

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

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

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

    16

    const-wide/16 vx, lit16

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

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

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

    17

    const-wide/32 vx, lit32

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

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

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

    18

    const-wide vx, lit64

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

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

    存入long常量12345678901234567v2,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.0v0,v1

    1A

    const-string vx, 字符串ID

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

    1A08 0000 - const-string v8, "" // string@0000

    存入string@0000(字符串表#0条目)的引用到v8

    1B

    const-string-jumbo

    未知4

     

    1C

    const-class vx, 类型ID

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

    1C00 0100 - const-class v0, Test3 // type@0001

    存入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 // type@0001

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

    20

    instance-of vx, vy,类型ID

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

    2040 0100 - instance-of v0, v4, Test3 // type@0001

    检查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 // type@0015

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

    23

    new-array vx, vy,类型ID

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

    2312 2500 - new-array v2, v1, char[] // type@0025

    新建一个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 // type@0D53

    新建一个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 // type@0006

    新建一个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 // 元素 #0int 1

    0200 0000 // 元素 #1int 2

    0300 0000 // 元素 #2int 3

    27

    throw vx

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

    2700 - throw v0

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

    28

    goto 目标

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

    28F0 - goto 0005 // -0010

    跳转到当前位置-16hex 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

    比较vyvzfloat值并在vx存入int型返回值3

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

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

    2E

    cmpg-float vx, vy, vz

    比较vyvzfloat值并在vx存入int型返回值3

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

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

    2F

    cmpl-double vx, vy, vz

    比较vyvz2double值并在vx存入int型返回值3

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

    比较v6,v7v8,v9double值并在v25存入int型返回值。非数值默认为小于。如果参数为非数值将返回-1

    30

    cmpg-double vx, vy, vz

    比较vyvz2double值并在vx存入int型返回值3

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

    比较v8,v9v10,v11double值并在v0存入int型返回值。非数值默认为大于。如果参数为非数值将返回1

    31

    cmp-long vx, vy, vz

    比较vyvzlong值并在vx存入int型返回值3

    3100 0204 - cmp-long v0, v2, v4

    比较v2v4long值并在v0存入int型返回值。

    32

    if-eq vx,vy, 目标

    如果vx == vy2,跳转到目标vxvyint型值。

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

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

    33

    if-ne vx,vy, 目标

    如果vx != vy2,跳转到目标vxvyint型值。

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

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

    34

    if-lt vx,vy, 目标

    如果vx < vy2,跳转到目标vxvyint型值。

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

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

    35

    if-ge vx, vy, 目标

    如果vx >= vy2,跳转到目标vxvyint型值。

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

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

    36

    if-gt vx,vy, 目标

    如果vx > vy2,跳转到目标vxvyint型值。

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

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

    37

    if-le vx,vy, 目标

    如果vx <= vy2,跳转到目标vxvyint型值。

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

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

    38

    if-eqz vx, 目标

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

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

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

    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,跳转到当前位置+16H002d是目标指令标签。

    3B

    if-gez vx, 目标

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

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

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

    3C

    if-gtz vx, 目标

    如果vx > 02,跳转到目标

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

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

    3D

    if-lez vx, 目标

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

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

    如果v0 <= 0,跳转到当前位置+1DH004a是目标指令标签。

    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

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

    4B00 0305 - aput v0, v3, v5

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

    4C

    aput-wide vx, vy, vz

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

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

    v5,v6double/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

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

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

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

    4F

    aput-byte vx, vy, vz

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

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

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

    50

    aput-char vx, vy, vz

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

    5003 0001 - aput-char v3, v0, v1

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

    51

    aput-short vx, vy, vz

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

    5102 0001 - aput-short v2, v0, v1

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

    52

    iget vx, vy, 字段ID

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

    5210 0300 - iget v0, v1, Test2.i6:I // field@0003

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

    53

    iget-wide vx, vy, 字段ID

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

    5320 0400 - iget-wide v0, v2, Test2.l0:J // field@0004

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

    54

    iget-object vx, vy, 字段ID

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

    iget-object v1, v2, LineReader.fis:Ljava/io/FileInputStream; // field@0002

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

    55

    iget-boolean vx, vy, 字段ID

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

    55FC 0000 - iget-boolean v12, v15, Test2.b0:Z // field@0000

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

    56

    iget-byte vx, vy, 字段ID

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

    5632 0100 - iget-byte v2, v3, Test3.bi1:B // field@0001

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

    57

    iget-char vx, vy, 字段ID

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

    5720 0300 - iget-char v0, v2, Test3.ci1:C // field@0003

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

    58

    iget-short vx, vy, 字段ID

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

    5830 0800 - iget-short v0, v3, Test3.si1:S // field@0008

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

    59

    iput vx, vy, 字段ID

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

    5920 0200 - iput v0, v2, Test2.i6:I // field@0002

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

    5A

    iput-wide vx, vy, 字段ID

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

    5A20 0000 - iput-wide v0, v2, Test2.d0:D // field@0000

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

    5B

    iput-object vx, vy, 字段ID

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

    5B20 0000 - iput-object v0, v2, LineReader.bis:Ljava/io/BufferedInputStream; // field@0000

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

    5C

    iput-boolean vx, vy, 字段ID

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

    5C30 0000 - iput-boolean v0, v3, Test2.b0:Z // field@0000

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

    5D

    iput-byte vx, vy, 字段ID

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

    5D20 0100 - iput-byte v0, v2, Test3.bi1:B // field@0001

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

    5E

    iput-char vx, vy, 字段ID

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

    5E20 0300 - iput-char v0, v2, Test3.ci1:C // field@0003

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

    5F

    iput-short vx, vy, 字段ID

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

    5F21 0800 - iput-short v1, v2, Test3.si1:S // field@0008

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

    60

    sget vx, 字段ID

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

    6000 0700 - sget v0, Test3.is1:I // field@0007

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

    61

    sget-wide vx, 字段ID

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

    6100 0500 - sget-wide v0, Test2.l1:J // field@0005

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

    62

    sget-object vx, 字段ID

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

    6201 0C00 - sget-object v1, Test3.os1:Ljava/lang/Object; // field@000c

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

    63

    sget-boolean vx, 字段ID

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

    6300 0C00 - sget-boolean v0, Test2.sb:Z // field@000c

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

    64

    sget-byte vx, 字段ID

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

    6400 0200 - sget-byte v0, Test3.bs1:B // field@0002

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

    65

    sget-char vx, 字段ID

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

    6500 0700 - sget-char v0, Test3.cs1:C // field@0007

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

    66

    sget-short vx, 字段ID

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

    6600 0B00 - sget-short v0, Test3.ss1:S // field@000b

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

    67

    sput vx, 字段ID

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

    6700 0100 - sput v0, Test2.i5:I // field@0001

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

    68

    sput-wide vx, 字段ID

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

    6800 0500 - sput-wide v0, Test2.l1:J // field@0005

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

    69

    sput-object vx, 字段ID

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

    6900 0c00 - sput-object v0, Test3.os1:Ljava/lang/Object; // field@000c

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

    6A

    sput-boolean vx, 字段ID

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

    6A00 0300 - sput-boolean v0, Test3.bls1:Z // field@0003

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

    6B

    sput-byte vx, 字段ID

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

    6B00 0200 - sput-byte v0, Test3.bs1:B // field@0002

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

    6C

    sput-char vx, 字段ID

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

    6C01 0700 - sput-char v1, Test3.cs1:C // field@0007

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

    6D

    sput-short vx, 字段ID

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

    6D00 0B00 - sput-short v0, Test3.ss1:S // field@000b

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

    6E

    invoke-virtual {参数}, 方法名

    调用带参数的虚拟方法。

    6E53 0600 0421 - invoke-virtual { v4, v0, v1, v2, v3}, Test2.method5:(IIII)V // method@0006

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

    6F

    invoke-super {参数}, 方法名

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

    6F10 A601 0100 invoke-super {v1},java.io.FilterOutputStream.close:()V // method@01a6

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

    70

    invoke-direct {参数}, 方法名

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

    7010 0800 0100 - invoke-direct {v1}, java.lang.Object.<init>:()V // method@0008

    调用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 // method@0034

    调用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 // method@0221

    调用mwfw.IReceivingProtocolAdapter 接口的receivePackage方法(方法表#221条目),该指令共有4个参数5,参数v1"this"实例,v3,v4,v5receivePackage方法的参数,(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 // method@0006

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

    75

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

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

    7501 A601 0100 invoke-super {v1},java.io.FilterOutputStream.close:()V // method@01a6

    调用java.io.FilterOutputStreamclose(方法表#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 // method@003a

    调用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 // method@0034

    调用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 // method@0221

    调用mwfw.IReceivingProtocolAdapter 接口的receivePackage方法(方法表#221条目),该指令共有4个参数5,参数v1"this"实例,v2,v3,v4receivePackage方法的参数,(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

    左移vyvz指定移动的位置,结果存入vx

    9802 0001 - shl-int v2, v0, v1

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

    99

    shr-int vx, vy, vz

    右移vyvz指定移动的位置,结果存入vx

    9902 0001 - shr-int v2, v0, v1

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

    9A

    ushr-int vx, vy, vz

    无符号右移vyvz指定移动的位置,结果存入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+1vz指定移动的位置,结果存入vx,vx+11

    A302 0004 - shl-long v2, v0, v4

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

    A4

    shr-long vx, vy, vz

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

    A402 0004 - shr-long v2, v0, v4

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

    A5

    ushr-long vx, vy, vz

    无符号右移vy,vy+1vz指定移动的位置,结果存入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

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

    B810 - shl-int/2addr v0, v1

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

    B9

    shr-int/2addr vx, vy

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

    B910 - shr-int/2addr v0, v1

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

    BA

    ushr-int/2addr vx, vy

    无符号右移vxvy指定移动的位置,并将结果存入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+1vy指定移动的位置,并将结果存入vx,vx+1

    C320 - shl-long/2addr v0, v2

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

    C4

    shr-long/2addr vx, vy

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

    C420 - shr-long/2addr v0, v2

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

    C5

    ushr-long/2addr vx, vy

    无符号右移vx,vx+1vy指定移动的位置,并将结果存入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

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

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

    v0左移1位,结果存入v1

    E1

    shr-int/lit8 vx, vy, lit8

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

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

    v0右移1位,结果存入v1

    E2

    ushr-int/lit8 vx, vy, lit8

    无符号右移vylit8指定移动的位置,并将结果存入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 // method@08f6

    替代空方法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:   Doublelong值占用两个寄存器。(例:在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文件。





  • 相关阅读:
    前端 一——介绍
    python知识点拾遗
    python 五——自定义线程池
    python 四——线程、进程、协程
    python 三——列表、字典、元祖、字符串、set
    动态规划法求解0-1背包
    贪心法求解背包问题
    学生成绩管理系统
    [C语言练习]学生学籍管理系统
    [C语言练习]万年历加强版
  • 原文地址:https://www.cnblogs.com/xiao-zhang/p/4691289.html
Copyright © 2020-2023  润新知