zoukankan      html  css  js  c++  java
  • (3)Smali系列学习之Smali语法详解

    数据类型

    Dalvik字节码只有两种格式:基本类型和引用类型。对象和数组属于引用类型

    语法含义
    V void,只用于返回值类型
    Z boolean
    B byte
    S short
    C char
    I int
    J long
    F flot
    D double
    L Java类 类型
    [ 数组类型

    Ljava/lang/String; 相当于java.lang.String 
    [I 相当于一维int数组,int[] 
    [[I 相当于int[][]

    方法

    它使用方法名,参数类型和返回值来描述一个方法 
    package/name/ObjectName;->methodName(III)Z

    package/name/ObjectName:一个类 
    methodName:方法名 
    III:参数类型 
    Z:返回值

    (III)Z:方法签名

    BakSmali生成的方法代码以.method指令开始,以.end method指令结束,根据方法的类型不同,可以会在方法前加#表示方法类型

    # vitual methods:虚方法,如:

     1 # virtual methods
     2 .method public get(Ljava/lang/String;)Lcn/woblog/markdowndiary/domain/Note;
     3     .locals 2
     4     .param p1, "noteId"    # Ljava/lang/String;
     5 
     6     .prologue
     7     .line 50
     8     iget-object v0, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->orm:Lcom/litesuits/orm/LiteOrm;
     9 
    10     const-class v1, Lcn/woblog/markdowndiary/domain/Note;
    11 
    12     invoke-virtual {v0, p1, v1}, Lcom/litesuits/orm/LiteOrm;->queryById(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
    13 
    14     move-result-object v0
    15 
    16     check-cast v0, Lcn/woblog/markdowndiary/domain/Note;
    17 
    18     return-object v0
    19 .end method

    # direct methods:直接方法,如:

     1 # direct methods
     2 .method public constructor <init>(Landroid/content/Context;)V
     3     .locals 2
     4     .param p1, "context"    # Landroid/content/Context;
     5 
     6     .prologue
     7     .line 22
     8     invoke-direct {p0}, Ljava/lang/Object;-><init>()V
     9 
    10     .line 23
    11     iput-object p1, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->context:Landroid/content/Context;
    12 
    13     .line 24
    14     const-string v0, "note.db"
    15 
    16     invoke-static {p1, v0}, Lcom/litesuits/orm/LiteOrm;->newSingleInstance(Landroid/content/Context;Ljava/lang/String;)Lcom/litesuits/orm/LiteOrm;
    17 
    18     move-result-object v0
    19 
    20     iput-object v0, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->orm:Lcom/litesuits/orm/LiteOrm;
    21 
    22     .line 25
    23     iget-object v0, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->orm:Lcom/litesuits/orm/LiteOrm;
    24 
    25     const/4 v1, 0x1
    26 
    27     invoke-virtual {v0, v1}, Lcom/litesuits/orm/LiteOrm;->setDebugged(Z)V
    28 
    29     .line 26
    30     return-void
    31 .end method

    有些方法没有这样的注释

     1 .method public save(Lcn/woblog/markdowndiary/domain/Note;)V
     2     .locals 1
     3     .param p1, "note"    # Lcn/woblog/markdowndiary/domain/Note;
     4 
     5     .prologue
     6     .line 37
     7     iget-object v0, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->orm:Lcom/litesuits/orm/LiteOrm;
     8 
     9     invoke-virtual {v0, p1}, Lcom/litesuits/orm/LiteOrm;->save(Ljava/lang/Object;)J
    10 
    11     .line 38
    12     return-void
    13 .end method

    静态方法:

     1 .method public static formatTime(J)Ljava/lang/String;
     2     .locals 4
     3     .param p0, "date"    # J
     4 
     5     .prologue
     6     .line 11
     7     new-instance v0, Ljava/text/SimpleDateFormat;
     8 
     9     const-string v1, "yyyyu5e74MMu6708ddu65e5 EEEE"
    10 
    11     sget-object v2, Ljava/util/Locale;->CHINESE:Ljava/util/Locale;
    12 
    13     invoke-direct {v0, v1, v2}, Ljava/text/SimpleDateFormat;-><init>(Ljava/lang/String;Ljava/util/Locale;)V
    14 
    15     .line 13
    16     .local v0, "simpleDateFormat":Ljava/text/SimpleDateFormat;
    17     invoke-static {p0, p1}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
    18 
    19     move-result-object v1
    20 
    21     invoke-virtual {v0, v1}, Ljava/text/SimpleDateFormat;->format(Ljava/lang/Object;)Ljava/lang/String;
    22 
    23     move-result-object v1
    24 
    25     return-object v1
    26 .end method

    字段

    与方法表示很相似,只是字段没有方法签名和返回值,取而代之的是字段类型 
    Lpackage/name/ObjectName;->FiedlName:Ljava/lang/String;

    其中字段名与字段类型用冒号“:”分割

    1 # static fields
    2 .field private static instance:Lcn/woblog/markdowndiary/repository/LocalNoteRepository;
    3 
    4 
    5 # instance fields
    6 .field private final context:Landroid/content/Context;

    其中: 
    # static fields:静态字段 
    # instance fields:实例字段

    Dalvik指令集

    他在调用格式上模仿了C语言的调用约定,官方地址,指令语法与助词有如下特点:

    1. 采用采用从目标(destination)到源(source)的方法
    2. 根据字节码的大小与类型不同,一些字节码添加了名称后缀已消除歧义 
      2.1 32位常规类型的字节码未添加任何后缀 
      2.2 64位常规类型的字节码添加 -wide后缀 
      3.3 特殊类型的字节码根据具体类型添加后缀,-boolean,-byte,-char,-short,-int,-long,-float,-double,-object,-string,-class,-void之一
    3. 根据字节码的布局和选项不同,一些字节码添加了字节后缀消除歧义,后缀与字节码直接用/分割
    4. 在指令集的描述中,宽度值中每个字母表示宽度为4位

    如: 
    move-wide/from16 vAA, vBBBB 
    move-wide/from16 v18, v0

    move:基础字节码(base opcode),标示是基本操作 
    wide:标示指令操作的数据宽度为64位宽度 
    from16:字节码后缀(opcode suffix),标示源(vBBBB)为一个16的寄存器引用变量 
    vAA:目的寄存器,v0~v255 
    vBBBB:源寄存器,v0~v65535

    指令

    nop

    空操作,被用来做对齐代码

    数据定义

    用来定义程序中用到的常量,字符串,类等数据 
    const/4 vA, #+B :将数组扩展为32位后赋给寄存器vA 
    const/16 vAA, #+BBBB 
    const vAA, #+BBBBBBBB:将数组赋值给寄存器vAA 
    const-wide/16 vAA, #+BBBBB :将数值扩展为64位后赋给寄存器vAA 
    const-string vAA, string@BBBB:将字符串索引构造一个字符串并赋给vAA 
    const-class vAA, type@BBBB:通过类型索引获取一个类的引用并赋给寄存器vAA

     1 private void testConst() {
     2     int a = 1;
     3     int b = 7;
     4     int c = 254;
     5     int d = 2345;
     6     int d1 = 65538;
     7 
     8     long e = 12435465657677L;
     9     float f = 123235409234.09097945F;
    10     double g = 111343333454999999999.912384375;
    11 }
     1 //-8到7用4,大于255小于等于65535用16
     2 const/4 v0, 0x1
     3 
     4 .line 25
     5 .local v0, "a":I
     6 const/4 v1, 0x7
     7 
     8 .line 26
     9 .local v1, "b":I
    10 const/16 v2, 0xfe
    11 
    12 .line 27
    13 .local v2, "c":I
    14 const/16 v3, 0x929
    15 
    16 .line 28
    17 .local v3, "d":I
    18 const v4, 0x10002 //65538,大于65535用const v4
    19 
    20 //long用const-wide
    21 .line 30
    22 .local v4, "d1":I
    23 const-wide v6, 0xb4f5b835d4dL
    24 
    25 .line 31
    26 .local v6, "e":J
    27 const v5, 0x51e58b39
    28 
    29 .line 32
    30 .local v5, "f":F
    31 const-wide v8, 0x441824cbef6b9491L    # 1.11343333455E20

    数据操作指令

    move destination, source 
    根据字节码大小和类型不同,后面回天津不同的后缀 
    move vA, vB:vB寄存器值赋值给vA寄存器,都为4位 
    move-object vA,vB 
    move-result vAA:将上一个invoke类型的指令操作的单字非对象结果负责vAA寄存器 
    move-result-object vAA:将上一个invoke类型指令操作的对象赋值给vAA 
    move-exception vAA:保存一个运行时发生的异常vAA寄存器,必须是异常发生时的异常处理的第一条指令

     1 private void testMove() {
     2     int a = 100;
     3     long b = 100000000000000000L;
     4 
     5     int c = a;
     6     long d = b;
     7 
     8     Log.d(TAG,c+"");
     9     Log.d(TAG,d+"");
    10 
    11 
    12     int e = getIntResult();
    13     Log.d(TAG,e+"");
    14 
    15     try {
    16         int f = e/c;
    17     } catch (ArithmeticException e1) {
    18         e1.printStackTrace();
    19     }catch (Exception e1) {
    20         e1.printStackTrace();
    21     }finally {
    22 
    23     }
    24 }
     1 //move-result-object
     2 invoke-direct {v7}, Ljava/lang/StringBuilder;-><init>()V
     3 
     4 invoke-virtual {v7, v1}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
     5 
     6 move-result-object v7
     7 
     8 const-string v8, ""
     9 
    10 invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    11 
    12 move-result-object v7
    13 
    14 //move-result
    15 invoke-direct {p0}, Lcom/woblog/testsmali/MainActivity;->getIntResult()I
    16 
    17 move-result v6
    18 
    19 //move exception
    20 .line 35
    21 :try_start_0
    22 div-int v8, v6, v1
    23 :try_end_0
    24 .catch Ljava/lang/ArithmeticException; {:try_start_0 .. :try_end_0} :catch_0
    25 .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_1
    26 .catchall {:try_start_0 .. :try_end_0} :catchall_0
    27 
    28 .line 43
    29 :goto_0
    30 return-void
    31 
    32 .line 36
    33 :catch_0
    34 move-exception v7
    35 
    36 .line 37
    37 .local v7, "e1":Ljava/lang/ArithmeticException;
    38 :try_start_1
    39 invoke-virtual {v7}, Ljava/lang/ArithmeticException;->printStackTrace()V
    40 :try_end_1
    41 .catchall {:try_start_1 .. :try_end_1} :catchall_0
    42 
    43 goto :goto_0
    44 
    45 .line 40
    46 .end local v7    # "e1":Ljava/lang/ArithmeticException;
    47 :catchall_0
    48 move-exception v8
    49 
    50 throw v8
    51 
    52 .line 38
    53 :catch_1
    54 move-exception v7
    55 
    56 .line 39
    57 .local v7, "e1":Ljava/lang/Exception;
    58 :try_start_2
    59 invoke-virtual {v7}, Ljava/lang/Exception;->printStackTrace()V
    60 :try_end_2
    61 .catchall {:try_start_2 .. :try_end_2} :catchall_0
    62 
    63 goto :goto_0

    返回指令

    return-void :返回一个void 
    return vAA:返回一个32位非对象类型的值,返回寄存器为8位 
    return-wide vAA:返回一个64位非对象类型的值,返回寄存器为8位 
    return-object vAA:返回一个对象类型

     1 private String returnObject() {
     2     return new String("");
     3 }
     4 
     5 private float returnFloat() {
     6     return 12333334.00234345F;
     7 }
     8 
     9 private double returnDouble() {
    10     return 3425465767.9345865;
    11 }
    12 
    13 private long returnLong() {
    14     return 12445657999999L;
    15 }
    16 
    17 private int returnInt() {
    18     return 1024;
    19 }
    20 
    21 private void returnVoid() {
    22     int a = 3;
    23 }
     1 .method private returnDouble()D
     2     .locals 2
     3 
     4     .prologue
     5     .line 40
     6     const-wide v0, 0x41e9858eb4fde822L    # 3.4254657679345865E9
     7 
     8     return-wide v0
     9 .end method
    10 
    11 .method private returnFloat()F
    12     .locals 1
    13 
    14     .prologue
    15     .line 36
    16     const v0, 0x4b3c3116    # 1.2333334E7f
    17 
    18     return v0
    19 .end method
    20 
    21 .method private returnInt()I
    22     .locals 1
    23 
    24     .prologue
    25     .line 48
    26     const/16 v0, 0x400
    27 
    28     return v0
    29 .end method
    30 
    31 .method private returnLong()J
    32     .locals 2
    33 
    34     .prologue
    35     .line 44
    36     const-wide v0, 0xb51bb062a7fL
    37 
    38     return-wide v0
    39 .end method
    40 
    41 .method private returnObject()Ljava/lang/String;
    42     .locals 2
    43 
    44     .prologue
    45     .line 32
    46     new-instance v0, Ljava/lang/String;
    47 
    48     const-string v1, ""
    49 
    50     invoke-direct {v0, v1}, Ljava/lang/String;-><init>(Ljava/lang/String;)V
    51 
    52     return-object v0
    53 .end method
    54 
    55 .method private returnVoid()V
    56     .locals 1
    57 
    58     .prologue
    59     .line 52
    60     const/4 v0, 0x3
    61 
    62     .line 53
    63     .local v0, "a":I
    64     return-void
    65 .end method

    锁指令

    锁指令多用在多线程程序中对同一对象的操作 
    monitor-enter vAA 为指定的对象获取锁 
    monitor-exit vAA 释放指定的对象的锁

     1 private void callSynchronizeClassMethod() {
     2     synchronized (MainActivity.class) {
     3         Log.d("TAG","synchronized class");
     4     }
     5 }
     6 
     7 private void callSynchronizeMethod() {
     8     synchronized (this) {
     9         Log.d("TAG","synchronized this");
    10     }
    11 }
    12 
    13 private synchronized void callLockMethod() {
    14     Log.d("TAG","synchronized method");
    15 }
     1 .method private declared-synchronized callLockMethod()V
     2     .locals 2
     3 
     4     .prologue
     5     .line 43
     6     monitor-enter p0
     7 
     8     :try_start_0
     9     const-string v0, "TAG"
    10 
    11     const-string v1, "synchronized method"
    12 
    13     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    14     :try_end_0
    15     .catchall {:try_start_0 .. :try_end_0} :catchall_0
    16 
    17     .line 44
    18     monitor-exit p0
    19 
    20     return-void
    21 
    22     .line 43
    23     :catchall_0
    24     move-exception v0
    25 
    26     monitor-exit p0
    27 
    28     throw v0
    29 .end method
    30 
    31 .method private callSynchronizeClassMethod()V
    32     .locals 3
    33 
    34     .prologue
    35     .line 31
    36     const-class v1, Lcom/woblog/testsmali/MainActivity;
    37 
    38     monitor-enter v1
    39 
    40     .line 32
    41     :try_start_0
    42     const-string v0, "TAG"
    43 
    44     const-string v2, "synchronized class"
    45 
    46     invoke-static {v0, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    47 
    48     .line 33
    49     monitor-exit v1
    50 
    51     .line 34
    52     return-void
    53 
    54     .line 33
    55     :catchall_0
    56     move-exception v0
    57 
    58     monitor-exit v1
    59     :try_end_0
    60     .catchall {:try_start_0 .. :try_end_0} :catchall_0
    61 
    62     throw v0
    63 .end method
    64 
    65 .method private callSynchronizeMethod()V
    66     .locals 2
    67 
    68     .prologue
    69     .line 37
    70     monitor-enter p0
    71 
    72     .line 38
    73     :try_start_0
    74     const-string v0, "TAG"
    75 
    76     const-string v1, "synchronized this"
    77 
    78     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    79 
    80     .line 39
    81     monitor-exit p0
    82 
    83     .line 40
    84     return-void
    85 
    86     .line 39
    87     :catchall_0
    88     move-exception v0
    89 
    90     monitor-exit p0
    91     :try_end_0
    92     .catchall {:try_start_0 .. :try_end_0} :catchall_0
    93 
    94     throw v0
    95 .end method

    实例操作

    包括类型转换,检查和创建新实例 
    check-cast vAA, type@BBBB:将vAA中的对象转为指定类型,如果失败会抛出ClassCastException异常,如果类型B是基本类型,对于分基本类型的A来说运行始终是失败的 
    instance-of vA, vB, type@CCCC:判断vB寄存器的对象是否可以转为指定类型,如果可以vA为1,否则为0 
    new-instance vAA, type@BBBB:构造一个指定类型的对象,并赋值给vAA寄存器,不能是数组类型

     1 CharSequence cs = new String();
     2 Object o = cs;
     3 
     4 String s = (String) cs;
     5 
     6 //实例检测
     7 if (s instanceof CharSequence) {
     8     Log.d("TAG", "ok");
     9 } else {
    10     Log.d("TAG","no");
    11 }
    12 
    13 
    14 //创建实例
    15 StringBuilder sb = new StringBuilder();
    16 sb.append("Ok");
    17 
    18 String s1 = new String("new string");
    19 String s2 = "string";
     1 new-instance v1, Ljava/lang/String;
     2 
     3 invoke-direct {v1}, Ljava/lang/String;-><init>()V
     4 
     5 .line 33
     6 .local v1, "cs":Ljava/lang/CharSequence;
     7 move-object v7, v1
     8 
     9 .local v7, "o":Ljava/lang/CharSequence;
    10 move-object v8, v1
    11 
    12 .line 35
    13 check-cast v8, Ljava/lang/String;
    14 
    15 .line 38
    16 .local v8, "s":Ljava/lang/String;
    17 instance-of v12, v8, Ljava/lang/CharSequence;
    18 
    19 if-eqz v12, :cond_0
    20 
    21 .line 39
    22 const-string v12, "TAG"
    23 
    24 const-string v13, "ok"
    25 
    26 invoke-static {v12, v13}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    27 
    28 .line 46
    29 :goto_0
    30 new-instance v11, Ljava/lang/StringBuilder;
    31 
    32 invoke-direct {v11}, Ljava/lang/StringBuilder;-><init>()V
    33 
    34 .line 47
    35 .local v11, "sb":Ljava/lang/StringBuilder;
    36 const-string v12, "Ok"
    37 
    38 invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    39 
    40 .line 49
    41 new-instance v9, Ljava/lang/String;
    42 
    43 const-string v12, "new string"
    44 
    45 invoke-direct {v9, v12}, Ljava/lang/String;-><init>(Ljava/lang/String;)V
    46 
    47 .line 50
    48 .local v9, "s1":Ljava/lang/String;
    49 const-string v10, "string"
    50 
    51 .line 51
    52 .local v10, "s2":Ljava/lang/String;
    53 return-void
    54 
    55 .line 41
    56 .end local v9    # "s1":Ljava/lang/String;
    57 .end local v10    # "s2":Ljava/lang/String;
    58 .end local v11    # "sb":Ljava/lang/StringBuilder;
    59 :cond_0
    60 const-string v12, "TAG"
    61 
    62 const-string v13, "no"
    63 
    64 invoke-static {v12, v13}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    65 
    66 goto :goto_0

    数组操作

    包括获取数组长度,新建数组,数组赋值,数组元素取值与赋值等 
    array-length vA, vB:获取vB寄存器中数组的长度并赋值给vA寄存器 
    new-array vA, vB, type@CCCC:构造指定类型(type@CCCC)与大小(vB)的数组,并赋值给vA寄存器 
    filled-new-array {vC,vD,vE,vF,vG}, type@BBBB:构造指定类型(type@BBBB)与大小vA的数组并填充数组内容,除了指定数组的大小还指定了参数个数 
    filled-new-array/range {vCCCC .. vNNNN}, type@BBBB:与上一条类似,只是参数使用取值范围,vC是第一个参数寄存器,N=A+C-1 
    fill-array-data vAA, +BBBBBBBB:vAA为寄存器数组引用,后面跟一个数据表 
    arrayop vAA, vBB, vCC:对vBB寄存器指定的数组元素进入取值或赋值。vCC指定数组元素索引,vAA寄存器用来存放读取的或需要设置的值。读取元素使用age类指令,赋值使用aput类指令,根据数组中存储的类指令后面会跟不同的后缀: 
    aget,aget-wide,aget-object,aget-boolean,aget-byte,aget-char,aget-short 
    aput,aput-wide,aput-object,aput-boolean,aput-byte,aput-char,aput-short

     1 private void testArray() {
     2     int[] ints = new int[2];
     3     int[] ints1 = null;
     4     int[] ints2 = {1,2,3};
     5 
     6     Integer[] integers = new Integer[]{1,2,4};
     7 
     8     int[] strings = {1,2,3,4,5,6,5,6,6,6,6,6,6,7,7,8,8,8,8,8,1,1,1,3,3,5,6,54,5,6,56,567,67,6,34,45,45,6,56,57,45,45,5,56,56,7,34,543,543,6,56,56,45,4,54,5,45,56};
     9 
    10     //数组长度
    11     int length = ints.length;
    12     int length1 = ints2.length;
    13     int length2 = strings.length;
    14 
    15     //获取数组元素
    16     int string = strings[30];
    17     int string1 = ints2[1];
    18 
    19     //赋值
    20     strings[30] =  length;
    21     ints2[1] =  length2;
    22 }
      1 .method private testArray()V
      2     .locals 15
      3 
      4     .prologue
      5     const/16 v14, 0x1e
      6 
      7     const/4 v10, 0x3
      8 
      9     const/4 v13, 0x2
     10 
     11     const/4 v12, 0x1
     12 
     13     .line 27
     14     new-array v1, v13, [I
     15 
     16     .line 28
     17     .local v1, "ints":[I
     18     const/4 v2, 0x0
     19 
     20     .line 29
     21     .local v2, "ints1":[I
     22     new-array v3, v10, [I
     23 
     24     fill-array-data v3, :array_0
     25 
     26     .line 31
     27     .local v3, "ints2":[I
     28     new-array v0, v10, [Ljava/lang/Integer;
     29 
     30     const/4 v10, 0x0
     31 
     32     invoke-static {v12}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
     33 
     34     move-result-object v11
     35 
     36     aput-object v11, v0, v10
     37 
     38     invoke-static {v13}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
     39 
     40     move-result-object v10
     41 
     42     aput-object v10, v0, v12
     43 
     44     const/4 v10, 0x4
     45 
     46     invoke-static {v10}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
     47 
     48     move-result-object v10
     49 
     50     aput-object v10, v0, v13
     51 
     52     .line 33
     53     .local v0, "integers":[Ljava/lang/Integer;
     54     const/16 v10, 0x3a
     55 
     56     new-array v9, v10, [I
     57 
     58     fill-array-data v9, :array_1
     59 
     60     .line 36
     61     .local v9, "strings":[I
     62     array-length v4, v1
     63 
     64     .line 37
     65     .local v4, "length":I
     66     array-length v5, v3
     67 
     68     .line 38
     69     .local v5, "length1":I
     70     array-length v6, v9
     71 
     72     .line 41
     73     .local v6, "length2":I
     74     aget v7, v9, v14
     75 
     76     .line 42
     77     .local v7, "string":I
     78     aget v8, v3, v12
     79 
     80     .line 45
     81     .local v8, "string1":I
     82     aput v4, v9, v14
     83 
     84     .line 46
     85     aput v6, v3, v12
     86 
     87     .line 47
     88     return-void
     89 
     90     .line 29
     91     :array_0
     92     .array-data 4
     93         0x1
     94         0x2
     95         0x3
     96     .end array-data
     97 
     98     .line 33
     99     :array_1
    100     .array-data 4
    101         0x1
    102         0x2
    103         0x3
    104         0x4
    105         0x5
    106         0x6
    107         0x5
    108         0x6
    109         0x6
    110         0x6
    111         0x6
    112         0x6
    113         0x6
    114         0x7
    115         0x7
    116         0x8
    117         0x8
    118         0x8
    119         0x8
    120         0x8
    121         0x1
    122         0x1
    123         0x1
    124         0x3
    125         0x3
    126         0x5
    127         0x6
    128         0x36
    129         0x5
    130         0x6
    131         0x38
    132         0x237
    133         0x43
    134         0x6
    135         0x22
    136         0x2d
    137         0x2d
    138         0x6
    139         0x38
    140         0x39
    141         0x2d
    142         0x2d
    143         0x5
    144         0x38
    145         0x38
    146         0x7
    147         0x22
    148         0x21f
    149         0x21f
    150         0x6
    151         0x38
    152         0x38
    153         0x2d
    154         0x4
    155         0x36
    156         0x5
    157         0x2d
    158         0x38
    159     .end array-data
    160 .end method

    异常指令

    throw vAA:抛出vAA寄存器中指定类型的异常

     1 private void throw2() {
     2     try {
     3         throw new Exception("test throw runtime exception");
     4     } catch (Exception e) {
     5         e.printStackTrace();
     6     }
     7 }
     8 
     9 private void throw1() {
    10     throw new RuntimeException("test throw runtime exception");
    11 }
     1 .method private throw1()V
     2     .locals 2
     3 
     4     .prologue
     5     .line 38
     6     new-instance v0, Ljava/lang/RuntimeException;
     7 
     8     const-string v1, "test throw runtime exception"
     9 
    10     invoke-direct {v0, v1}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
    11 
    12     throw v0
    13 .end method
    14 
    15 .method private throw2()V
    16     .locals 3
    17 
    18     .prologue
    19     .line 31
    20     :try_start_0
    21     new-instance v1, Ljava/lang/Exception;
    22 
    23     const-string v2, "test throw runtime exception"
    24 
    25     invoke-direct {v1, v2}, Ljava/lang/Exception;-><init>(Ljava/lang/String;)V
    26 
    27     throw v1
    28     :try_end_0
    29     .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
    30 
    31     .line 32
    32     :catch_0
    33     move-exception v0
    34 
    35     .line 33
    36     .local v0, "e":Ljava/lang/Exception;
    37     invoke-virtual {v0}, Ljava/lang/Exception;->printStackTrace()V
    38 
    39     .line 35
    40     return-void
    41 .end method

    跳转指令

    用于从当前地址跳转到指定的偏移处,提供了三种指令:无条件(goto),分支跳转(switch),条件跳转(if) 
    goto +AA:无条件跳转到指定偏移处,AA不能为0 
    goto/16 +AAAA 
    goto/32 +AAAAAAAA

    packed-switch vAA, +BBBBBBBB:分支跳转,vAA寄存器为switch分支需要判断的值

    if-test vA, vB, +CCCC 条件跳转指令,比较vA寄存器与vB寄存器的值,如果比较结果满足就跳转到CCCC指定的偏移处,不能为0,有以下几条:

    if-eq:if(vA==vB) 
    if-ne:vA!=vB 
    if-lt:vA

     1 private void testIfz() {
     2     int a = 3;
     3     if (a == 0) {
     4 
     5     } else {
     6 
     7     }
     8     if (a != 0) {
     9 
    10     } else {
    11 
    12     }
    13     if (a < 0) {
    14 
    15     } else {
    16 
    17     }
    18     if (a > 0) {
    19 
    20     } else {
    21 
    22     }
    23     if (a <= 0) {
    24 
    25     } else {
    26 
    27     }
    28     if (a >= 0) {
    29 
    30     } else {
    31 
    32     }
    33 
    34     if (a < 5) {
    35         Log.d("TAG", "<5");
    36     } else if (a > 5) {
    37         Log.d("TAG", ">5");
    38     } else {
    39         Log.d("TAG", "=5");
    40     }
    41 }
    42 
    43 private void testIf() {
    44     int a = 2;
    45     int b = 3;
    46     if (a == b) {
    47 
    48     } else {
    49 
    50     }
    51     if (a != b) {
    52 
    53     } else {
    54 
    55     }
    56     if (a < b) {
    57 
    58     } else {
    59 
    60     }
    61     if (a > b) {
    62 
    63     } else {
    64 
    65     }
    66     if (a <= b) {
    67 
    68     } else {
    69 
    70     }
    71     if (a >= b) {
    72 
    73     } else {
    74 
    75     }
    76 
    77 }
      1 .method private testIf()V
      2     .locals 2
      3 
      4     .prologue
      5     .line 69
      6     const/4 v0, 0x2
      7 
      8     .line 70
      9     .local v0, "a":I
     10     const/4 v1, 0x3
     11 
     12     .line 71
     13     .local v1, "b":I
     14     if-ne v0, v1, :cond_0
     15 
     16     .line 76
     17     :cond_0
     18     if-eq v0, v1, :cond_1
     19 
     20     .line 81
     21     :cond_1
     22     if-ge v0, v1, :cond_2
     23 
     24     .line 86
     25     :cond_2
     26     if-le v0, v1, :cond_3
     27 
     28     .line 91
     29     :cond_3
     30     if-gt v0, v1, :cond_4
     31 
     32     .line 96
     33     :cond_4
     34     if-lt v0, v1, :cond_5
     35 
     36     .line 102
     37     :cond_5
     38     return-void
     39 .end method
     40 
     41 .method private testIfz()V
     42     .locals 3
     43 
     44     .prologue
     45     const/4 v1, 0x5
     46 
     47     .line 27
     48     const/4 v0, 0x3
     49 
     50     .line 28
     51     .local v0, "a":I
     52     if-nez v0, :cond_0
     53 
     54     .line 33
     55     :cond_0
     56     if-eqz v0, :cond_1
     57 
     58     .line 38
     59     :cond_1
     60     if-gez v0, :cond_2
     61 
     62     .line 43
     63     :cond_2
     64     if-lez v0, :cond_3
     65 
     66     .line 48
     67     :cond_3
     68     if-gtz v0, :cond_4
     69 
     70     .line 53
     71     :cond_4
     72     if-ltz v0, :cond_5
     73 
     74     .line 59
     75     :cond_5
     76     if-ge v0, v1, :cond_6
     77 
     78     .line 60
     79     const-string v1, "TAG"
     80 
     81     const-string v2, "<5"
     82 
     83     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     84 
     85     .line 66
     86     :goto_0
     87     return-void
     88 
     89     .line 61
     90     :cond_6
     91     if-le v0, v1, :cond_7
     92 
     93     .line 62
     94     const-string v1, "TAG"
     95 
     96     const-string v2, ">5"
     97 
     98     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     99 
    100     goto :goto_0
    101 
    102     .line 64
    103     :cond_7
    104     const-string v1, "TAG"
    105 
    106     const-string v2, "=5"
    107 
    108     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    109 
    110     goto :goto_0
    111 .end method

    比较指令

    用于对两个寄存器的值比较 
    cmpkind vAA, vBB, vCC:vBB和vCC为要比较的值,结果放到vAA中 
    cmpl-float:单精度,vBB大于vCC,vAA=-1,等于vAA=0,小于vAA=1 
    cmpg-float:单精度,vBB大于vCC,vAA=1,等于vAA=0,小于vAA=-1 
    cmpl-double:双精度 
    cmpg-double:双精度 
    cmp-long:长整形

     1 private void testCmpLong() {
     2     long a = 13;
     3     long b = 12;
     4     if (a < b) {
     5         Log.d("TAG", "<");
     6     } else if (a > b) {
     7         Log.d("TAG", ">");
     8     } else {
     9         Log.d("TAG", "=");
    10     }
    11 }
    12 
    13 private void testCmpDouble() {
    14     double a = 13.4;
    15     double b = 11.4;
    16     if (a < b) {
    17         Log.d("TAG", "<");
    18     } else if (a > b) {
    19         Log.d("TAG", ">");
    20     } else {
    21         Log.d("TAG", "=");
    22     }
    23 }
    24 
    25 private void testCmpFloat() {
    26     float a = 13.4F;
    27     float b = 10.4F;
    28     if (a < b) {
    29         Log.d("TAG", "<");
    30     } else if (a > b) {
    31         Log.d("TAG", ">");
    32     } else {
    33         Log.d("TAG", "=");
    34     }
    35 }
      1 .method private testCmpDouble()V
      2     .locals 6
      3 
      4     .prologue
      5     .line 46
      6     const-wide v0, 0x402acccccccccccdL    # 13.4
      7 
      8     .line 47
      9     .local v0, "a":D
     10     const-wide v2, 0x4026cccccccccccdL    # 11.4
     11 
     12     .line 48
     13     .local v2, "b":D
     14     cmpg-double v4, v0, v2
     15 
     16     if-gez v4, :cond_0
     17 
     18     .line 49
     19     const-string v4, "TAG"
     20 
     21     const-string v5, "<"
     22 
     23     invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     24 
     25     .line 55
     26     :goto_0
     27     return-void
     28 
     29     .line 50
     30     :cond_0
     31     cmpl-double v4, v0, v2
     32 
     33     if-lez v4, :cond_1
     34 
     35     .line 51
     36     const-string v4, "TAG"
     37 
     38     const-string v5, ">"
     39 
     40     invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     41 
     42     goto :goto_0
     43 
     44     .line 53
     45     :cond_1
     46     const-string v4, "TAG"
     47 
     48     const-string v5, "="
     49 
     50     invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     51 
     52     goto :goto_0
     53 .end method
     54 
     55 .method private testCmpFloat()V
     56     .locals 4
     57 
     58     .prologue
     59     .line 58
     60     const v0, 0x41566666    # 13.4f
     61 
     62     .line 59
     63     .local v0, "a":F
     64     const v1, 0x41266666    # 10.4f
     65 
     66     .line 60
     67     .local v1, "b":F
     68     cmpg-float v2, v0, v1
     69 
     70     if-gez v2, :cond_0 #>=
     71 
     72     .line 61
     73     const-string v2, "TAG"
     74 
     75     const-string v3, "<"
     76 
     77     invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     78 
     79     .line 67
     80     :goto_0
     81     return-void
     82 
     83     .line 62
     84     :cond_0
     85     cmpl-float v2, v0, v1
     86 
     87     if-lez v2, :cond_1 #<=
     88 
     89     .line 63
     90     const-string v2, "TAG"
     91 
     92     const-string v3, ">"
     93 
     94     invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     95 
     96     goto :goto_0
     97 
     98     .line 65
     99     :cond_1
    100     const-string v2, "TAG"
    101 
    102     const-string v3, "="
    103 
    104     invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    105 
    106     goto :goto_0
    107 .end method
    108 
    109 .method private testCmpLong()V
    110     .locals 6
    111 
    112     .prologue
    113     .line 34
    114     const-wide/16 v0, 0xd
    115 
    116     .line 35
    117     .local v0, "a":J
    118     const-wide/16 v2, 0xc
    119 
    120     .line 36
    121     .local v2, "b":J
    122     cmp-long v4, v0, v2
    123 
    124     if-gez v4, :cond_0
    125 
    126     .line 37
    127     const-string v4, "TAG"
    128 
    129     const-string v5, "<"
    130 
    131     invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    132 
    133     .line 43
    134     :goto_0
    135     return-void
    136 
    137     .line 38
    138     :cond_0
    139     cmp-long v4, v0, v2
    140 
    141     if-lez v4, :cond_1
    142 
    143     .line 39
    144     const-string v4, "TAG"
    145 
    146     const-string v5, ">"
    147 
    148     invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    149 
    150     goto :goto_0
    151 
    152     .line 41
    153     :cond_1
    154     const-string v4, "TAG"
    155 
    156     const-string v5, "="
    157 
    158     invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    159 
    160     goto :goto_0
    161 .end method

    字段操作指令

    用来对 对象实例的字段进行读写操作。字段类型可以是Java中有效的类型,对于实例字段和静态字段有两类指令: 
    iget,iput对实例字段进行读,写 
    sget,sput对静态字段

    会根据类型不同添加不同的后缀 
    iget,iget-wide,iget-object,iget-boolean,iget-byte,iget-char,iget-short 
    iput,iput-wide,iput-object,iput-boolean,iput-byte,iput-char,iput-short

    sget,sget-wide,sget-object,sget-boolean,sget-byte,sget-char,sget-short 

     1 private void testInstanceFieldOperator() {
     2     //write
     3     InstanceObject instanceObject = new InstanceObject();
     4     instanceObject.aInt=1;
     5     instanceObject.aLong=12454L;
     6     instanceObject.aFloat=12344.45F;
     7     instanceObject.aDouble=123546.2;
     8     instanceObject.object=new Object();
     9     instanceObject.aBoolean=true;
    10     instanceObject.aByte=3;
    11     instanceObject.aChar='c';
    12     instanceObject.aShort=1;
    13 
    14     Log.d("TAG",String.valueOf(instanceObject.aInt));
    15     Log.d("TAG",String.valueOf(instanceObject.aLong));
    16     Log.d("TAG",String.valueOf(instanceObject.aFloat));
    17     Log.d("TAG",String.valueOf(instanceObject.aDouble));
    18     Log.d("TAG",String.valueOf(instanceObject.object));
    19     Log.d("TAG",String.valueOf(instanceObject.aBoolean));
    20     Log.d("TAG",String.valueOf(instanceObject.aByte));
    21     Log.d("TAG",String.valueOf(instanceObject.aChar));
    22     Log.d("TAG",String.valueOf(instanceObject.aShort));
    23 }
    24 
    25 private void testStatusFieldOperator() {
    26     //write
    27     StatusObject.aInt=1;
    28     StatusObject.aLong=12454L;
    29     StatusObject.aFloat=12344.45F;
    30     StatusObject.aDouble=123546.2;
    31     StatusObject.object=new Object();
    32     StatusObject.aBoolean=true;
    33     StatusObject.aByte=3;
    34     StatusObject.aChar='c';
    35     StatusObject.aShort=1;
    36 
    37     Log.d("TAG",String.valueOf(StatusObject.aInt));
    38     Log.d("TAG",String.valueOf(StatusObject.aLong));
    39     Log.d("TAG",String.valueOf(StatusObject.aFloat));
    40     Log.d("TAG",String.valueOf(StatusObject.aDouble));
    41     Log.d("TAG",String.valueOf(StatusObject.object));
    42     Log.d("TAG",String.valueOf(StatusObject.aBoolean));
    43     Log.d("TAG",String.valueOf(StatusObject.aByte));
    44     Log.d("TAG",String.valueOf(StatusObject.aChar));
    45     Log.d("TAG",String.valueOf(StatusObject.aShort));
    46 }
      1 .method private testInstanceFieldOperator()V
      2     .locals 5
      3 
      4     .prologue
      5     const/4 v4, 0x1
      6 
      7     .line 30
      8     new-instance v0, Lcom/woblog/testsmali/InstanceObject;
      9 
     10     invoke-direct {v0}, Lcom/woblog/testsmali/InstanceObject;-><init>()V
     11 
     12     .line 31
     13     .local v0, "instanceObject":Lcom/woblog/testsmali/InstanceObject;
     14     iput v4, v0, Lcom/woblog/testsmali/InstanceObject;->aInt:I
     15 
     16     .line 32
     17     const-wide/16 v2, 0x30a6
     18 
     19     iput-wide v2, v0, Lcom/woblog/testsmali/InstanceObject;->aLong:J
     20 
     21     .line 33
     22     const v1, 0x4640e1cd
     23 
     24     iput v1, v0, Lcom/woblog/testsmali/InstanceObject;->aFloat:F
     25 
     26     .line 34
     27     const-wide v2, 0x40fe29a333333333L    # 123546.2
     28 
     29     iput-wide v2, v0, Lcom/woblog/testsmali/InstanceObject;->aDouble:D
     30 
     31     .line 35
     32     new-instance v1, Ljava/lang/Object;
     33 
     34     invoke-direct {v1}, Ljava/lang/Object;-><init>()V
     35 
     36     iput-object v1, v0, Lcom/woblog/testsmali/InstanceObject;->object:Ljava/lang/Object;
     37 
     38     .line 36
     39     iput-boolean v4, v0, Lcom/woblog/testsmali/InstanceObject;->aBoolean:Z
     40 
     41     .line 37
     42     const/4 v1, 0x3
     43 
     44     iput-byte v1, v0, Lcom/woblog/testsmali/InstanceObject;->aByte:B
     45 
     46     .line 38
     47     const/16 v1, 0x63
     48 
     49     iput-char v1, v0, Lcom/woblog/testsmali/InstanceObject;->aChar:C
     50 
     51     .line 39
     52     iput-short v4, v0, Lcom/woblog/testsmali/InstanceObject;->aShort:S
     53 
     54     .line 41
     55     const-string v1, "TAG"
     56 
     57     iget v2, v0, Lcom/woblog/testsmali/InstanceObject;->aInt:I
     58 
     59     invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
     60 
     61     move-result-object v2
     62 
     63     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     64 
     65     .line 42
     66     const-string v1, "TAG"
     67 
     68     iget-wide v2, v0, Lcom/woblog/testsmali/InstanceObject;->aLong:J
     69 
     70     invoke-static {v2, v3}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;
     71 
     72     move-result-object v2
     73 
     74     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     75 
     76     .line 43
     77     const-string v1, "TAG"
     78 
     79     iget v2, v0, Lcom/woblog/testsmali/InstanceObject;->aFloat:F
     80 
     81     invoke-static {v2}, Ljava/lang/String;->valueOf(F)Ljava/lang/String;
     82 
     83     move-result-object v2
     84 
     85     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     86 
     87     .line 44
     88     const-string v1, "TAG"
     89 
     90     iget-wide v2, v0, Lcom/woblog/testsmali/InstanceObject;->aDouble:D
     91 
     92     invoke-static {v2, v3}, Ljava/lang/String;->valueOf(D)Ljava/lang/String;
     93 
     94     move-result-object v2
     95 
     96     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
     97 
     98     .line 45
     99     const-string v1, "TAG"
    100 
    101     iget-object v2, v0, Lcom/woblog/testsmali/InstanceObject;->object:Ljava/lang/Object;
    102 
    103     invoke-static {v2}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
    104 
    105     move-result-object v2
    106 
    107     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    108 
    109     .line 46
    110     const-string v1, "TAG"
    111 
    112     iget-boolean v2, v0, Lcom/woblog/testsmali/InstanceObject;->aBoolean:Z
    113 
    114     invoke-static {v2}, Ljava/lang/String;->valueOf(Z)Ljava/lang/String;
    115 
    116     move-result-object v2
    117 
    118     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    119 
    120     .line 47
    121     const-string v1, "TAG"
    122 
    123     iget-byte v2, v0, Lcom/woblog/testsmali/InstanceObject;->aByte:B
    124 
    125     invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
    126 
    127     move-result-object v2
    128 
    129     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    130 
    131     .line 48
    132     const-string v1, "TAG"
    133 
    134     iget-char v2, v0, Lcom/woblog/testsmali/InstanceObject;->aChar:C
    135 
    136     invoke-static {v2}, Ljava/lang/String;->valueOf(C)Ljava/lang/String;
    137 
    138     move-result-object v2
    139 
    140     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    141 
    142     .line 49
    143     const-string v1, "TAG"
    144 
    145     iget-short v2, v0, Lcom/woblog/testsmali/InstanceObject;->aShort:S
    146 
    147     invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
    148 
    149     move-result-object v2
    150 
    151     invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    152 
    153     .line 50
    154     return-void
    155 .end method
    156 
    157 .method private testStatusFieldOperator()V
    158     .locals 4
    159 
    160     .prologue
    161     const/4 v2, 0x1
    162 
    163     .line 54
    164     sput v2, Lcom/woblog/testsmali/StatusObject;->aInt:I
    165 
    166     .line 55
    167     const-wide/16 v0, 0x30a6
    168 
    169     sput-wide v0, Lcom/woblog/testsmali/StatusObject;->aLong:J
    170 
    171     .line 56
    172     const v0, 0x4640e1cd
    173 
    174     sput v0, Lcom/woblog/testsmali/StatusObject;->aFloat:F
    175 
    176     .line 57
    177     const-wide v0, 0x40fe29a333333333L    # 123546.2
    178 
    179     sput-wide v0, Lcom/woblog/testsmali/StatusObject;->aDouble:D
    180 
    181     .line 58
    182     new-instance v0, Ljava/lang/Object;
    183 
    184     invoke-direct {v0}, Ljava/lang/Object;-><init>()V
    185 
    186     sput-object v0, Lcom/woblog/testsmali/StatusObject;->object:Ljava/lang/Object;
    187 
    188     .line 59
    189     sput-boolean v2, Lcom/woblog/testsmali/StatusObject;->aBoolean:Z
    190 
    191     .line 60
    192     const/4 v0, 0x3
    193 
    194     sput-byte v0, Lcom/woblog/testsmali/StatusObject;->aByte:B
    195 
    196     .line 61
    197     const/16 v0, 0x63
    198 
    199     sput-char v0, Lcom/woblog/testsmali/StatusObject;->aChar:C
    200 
    201     .line 62
    202     sput-short v2, Lcom/woblog/testsmali/StatusObject;->aShort:S
    203 
    204     .line 64
    205     const-string v0, "TAG"
    206 
    207     sget v1, Lcom/woblog/testsmali/StatusObject;->aInt:I
    208 
    209     invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
    210 
    211     move-result-object v1
    212 
    213     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    214 
    215     .line 65
    216     const-string v0, "TAG"
    217 
    218     sget-wide v2, Lcom/woblog/testsmali/StatusObject;->aLong:J
    219 
    220     invoke-static {v2, v3}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;
    221 
    222     move-result-object v1
    223 
    224     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    225 
    226     .line 66
    227     const-string v0, "TAG"
    228 
    229     sget v1, Lcom/woblog/testsmali/StatusObject;->aFloat:F
    230 
    231     invoke-static {v1}, Ljava/lang/String;->valueOf(F)Ljava/lang/String;
    232 
    233     move-result-object v1
    234 
    235     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    236 
    237     .line 67
    238     const-string v0, "TAG"
    239 
    240     sget-wide v2, Lcom/woblog/testsmali/StatusObject;->aDouble:D
    241 
    242     invoke-static {v2, v3}, Ljava/lang/String;->valueOf(D)Ljava/lang/String;
    243 
    244     move-result-object v1
    245 
    246     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    247 
    248     .line 68
    249     const-string v0, "TAG"
    250 
    251     sget-object v1, Lcom/woblog/testsmali/StatusObject;->object:Ljava/lang/Object;
    252 
    253     invoke-static {v1}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
    254 
    255     move-result-object v1
    256 
    257     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    258 
    259     .line 69
    260     const-string v0, "TAG"
    261 
    262     sget-boolean v1, Lcom/woblog/testsmali/StatusObject;->aBoolean:Z
    263 
    264     invoke-static {v1}, Ljava/lang/String;->valueOf(Z)Ljava/lang/String;
    265 
    266     move-result-object v1
    267 
    268     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    269 
    270     .line 70
    271     const-string v0, "TAG"
    272 
    273     sget-byte v1, Lcom/woblog/testsmali/StatusObject;->aByte:B
    274 
    275     invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
    276 
    277     move-result-object v1
    278 
    279     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    280 
    281     .line 71
    282     const-string v0, "TAG"
    283 
    284     sget-char v1, Lcom/woblog/testsmali/StatusObject;->aChar:C
    285 
    286     invoke-static {v1}, Ljava/lang/String;->valueOf(C)Ljava/lang/String;
    287 
    288     move-result-object v1
    289 
    290     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    291 
    292     .line 72
    293     const-string v0, "TAG"
    294 
    295     sget-short v1, Lcom/woblog/testsmali/StatusObject;->aShort:S
    296 
    297     invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
    298 
    299     move-result-object v1
    300 
    301     invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    302 
    303     .line 73
    304     return-void
    305 .end method

    方法调用

    在方法调用者我们可以看到有:

    1 invoke-super {p0, p1}, Lcom/woblog/testsmali/BaseActivity;->onCreate(Landroid/os/Bundle;)V
    2 
    3 invoke-virtual {p0, v0}, Lcom/woblog/testsmali/MainActivity;->setContentView(I)V
    4 
    5 invoke-direct {p0}, Lcom/woblog/testsmali/MainActivity;->initMove()V
    6 
    7 invoke-static {}, Lcom/woblog/testsmali/TimeUtil;->getCurrentTime()J
    8 
    9 invoke-interface {v0}, Lcom/woblog/testsmali/ICallback;->onSuccess()V

    数据转换

    数据转换指令用于将一种数据类型转换为另一个类型,unop vA, vB:寄存器存储要转换的数据,vA存储转换后的数据 
    neg-int:整形求补 
    not-int:整形求反 
    neg-long:长整型求补 
    not-long:长整型求反 
    neg-float:单精度求补 
    not-float: 
    neg-double: 
    not-double:

    int-to-long:整型转为长整型 
    int-to-float:整型转单精度浮点型 
    int-to-double:整型转双精度浮点型

    int-to-byte:整型转字节型 
    int-to-char:整型转字符串 
    int-to-short:整型转短整型

    long-to-int 
    long-to-float 
    long-to-double

    float-to-int 
    float-to-long 
    float-to-double

    double-to-int 
    double-to-long 
    double-to-float

     1 private void testConvert() {
     2     int i1=13;
     3 
     4     //int 转其他类型
     5     long l1 = i1;
     6     float f1 = i1;
     7     double d1 = i1;
     8 
     9     byte b1 = (byte) i1;
    10     char c1 = (char) i1;
    11     short s1 = (short) i1;
    12 
    13     //long 转其他类型
    14     long l2 = 234444556576L;
    15     int i2 = (int) l2;
    16     float f2 = l2;
    17     double d2 = l2;
    18 
    19     //float 转其他类型
    20     float f10 =234399.9F;
    21     int i10 = (int) f10;
    22     long l10 = (long) f10;
    23     double d10 = f10;
    24 
    25     //double 转其他类型
    26     double d20 = 123344445.324;
    27     int i20 = (int) d20;
    28     long l20 = (long) d20;
    29     float f20 = (float) d20;
    30 }
      1 .method private testConvert()V
      2     .locals 29
      3 
      4     .prologue
      5     .line 30
      6     const/16 v16, 0xd
      7 
      8     .line 33
      9     .local v16, "i1":I
     10     move/from16 v0, v16
     11 
     12     int-to-long v0, v0
     13 
     14     move-wide/from16 v20, v0
     15 
     16     .line 34
     17     .local v20, "l1":J
     18     move/from16 v0, v16
     19 
     20     int-to-float v12, v0
     21 
     22     .line 35
     23     .local v12, "f1":F
     24     move/from16 v0, v16
     25 
     26     int-to-double v4, v0
     27 
     28     .line 37
     29     .local v4, "d1":D
     30     move/from16 v0, v16
     31 
     32     int-to-byte v2, v0
     33 
     34     .line 38
     35     .local v2, "b1":B
     36     move/from16 v0, v16
     37 
     38     int-to-char v3, v0
     39 
     40     .line 39
     41     .local v3, "c1":C
     42     move/from16 v0, v16
     43 
     44     int-to-short v0, v0
     45 
     46     move/from16 v28, v0
     47 
     48     .line 42
     49     .local v28, "s1":S
     50     const-wide v24, 0x3695fc0920L
     51 
     52     .line 43
     53     .local v24, "l2":J
     54     move-wide/from16 v0, v24
     55 
     56     long-to-int v0, v0
     57 
     58     move/from16 v18, v0
     59 
     60     .line 44
     61     .local v18, "i2":I
     62     move-wide/from16 v0, v24
     63 
     64     long-to-float v14, v0
     65 
     66     .line 45
     67     .local v14, "f2":F
     68     move-wide/from16 v0, v24
     69 
     70     long-to-double v8, v0
     71 
     72     .line 48
     73     .local v8, "d2":D
     74     const v13, 0x4864e7fa    # 234399.9f
     75 
     76     .line 49
     77     .local v13, "f10":F
     78     float-to-int v0, v13
     79 
     80     move/from16 v17, v0
     81 
     82     .line 50
     83     .local v17, "i10":I
     84     float-to-long v0, v13
     85 
     86     move-wide/from16 v22, v0
     87 
     88     .line 51
     89     .local v22, "l10":J
     90     float-to-double v6, v13
     91 
     92     .line 54
     93     .local v6, "d10":D
     94     const-wide v10, 0x419d6858f54bc6a8L    # 1.23344445324E8
     95 
     96     .line 55
     97     .local v10, "d20":D
     98     double-to-int v0, v10
     99 
    100     move/from16 v19, v0
    101 
    102     .line 56
    103     .local v19, "i20":I
    104     double-to-long v0, v10
    105 
    106     move-wide/from16 v26, v0
    107 
    108     .line 57
    109     .local v26, "l20":J
    110     double-to-float v15, v10
    111 
    112     .line 58
    113     .local v15, "f20":F
    114     return-void
    115 .end method

    数据运行指令

    算术运算:加,减,乘,除,模,移位等 
    逻辑运算:与,或,非,异或等

    binop vAA, vBB, vCC:将vBB寄存器与vCC寄存器进行运算,结果保存到vAA

    上面的指令会根据数据类型的不同在基础后面添加数据类型后缀,如:-int或-long 
    add-type vBB:vBB寄存器与vCC寄存器值进行加法运算,+ 
    sub-type vBB:- 
    mul-type vBB:* 
    div-type vBB:/ 
    rem-type vBB:% 
    and-type vBB:and 
    or-type vBB:or 
    xor-type vBB:xor 
    shl-type vBB:左移vCC位,<< 
    shr-type vBB:右移vCC位,>> 
    ushr-type vBB:无符号>>

    其中type可以为int,long,float,double

    binop/2addr vA, vB:将vA寄存器与vB寄存器进行运算,结果保存到vA 
    binop/lit16 vA, vB, #+CCCC:将vB寄存器与常量CCCC进行运算,结果保存到vA 
    binop/lit8 vAA, vBB, #+CC:将vBB寄存器与常量CC进行运行,结果保存到vAA

    Dalvik hello world

    首先写一个基本框架

     1 .class public LHelloWorld; #定义类名
     2 .super Ljava/lang/Object; #定义父类
     3 .method public static main([Ljava/lang/String;)V #声明静态的main函数
     4     .locals 4 #使用的寄存器个数,包括一个参数寄存器
     5     .param p0, "args" #一个参数
     6 
     7     .prologue #代码起始指令
     8 
     9 
    10     # 这里是代码主体
    11 
    12 
    13     return-void
    14 .end method

    完整版如下:

     1 .class public LHelloWorld; #定义类名
     2 .super Ljava/lang/Object; #定义父类
     3 .method public static main([Ljava/lang/String;)V #声明静态的main函数
     4     .locals 4 #使用的寄存器个数,包括一个参数寄存器
     5     .param p0, "args" #一个参数
     6 
     7     .prologue #代码起始指令
     8 
     9 
    10     const-string v1, "Hello World"
    11 
    12     sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
    13 
    14     invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    15 
    16 
    17     return-void
    18 .end method

    编译smali

    我们去官网下载smali.jar,然后运行

    java -jar smali.jar -o classes.dex HelloWorld.smali

    编译完后我们把classes.dex push到手机里面

    adb push classes.dex /data/local/ 

    运行

    dalvikvm -cp /data/local/classes.dex HelloWorld  

    加强版本

     1 .class public LHelloWorld; #定义类名
     2 .super Ljava/lang/Object; #定义父类
     3 .method public static main([Ljava/lang/String;)V #声明静态的main函数
     4     .locals 10 #使用的寄存器个数,包括一个参数寄存器
     5     .param p0, "args" #一个参数
     6 
     7     .prologue #代码起始指令
     8 
     9     sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
    10 
    11     # 空指令
    12 
    13     nop
    14 
    15     nop
    16 
    17     nop
    18 
    19 
    20     # 数据定义指令
    21 
    22     const/4 v2, 0x3
    23 
    24     const/16 v3, 0xffff ##不能大于65535
    25 
    26     #大于65535用-wide
    27 
    28     const-wide v4, 0x10000
    29 
    30 
    31     # 定义一个类 类型
    32 
    33     const-class v5, Ljava/lang/String;
    34 
    35 
    36     # 数据操作指令
    37 
    38     move v6, v2
    39 
    40     new-instance v7, Ljava/lang/StringBuilder;
    41 
    42     invoke-direct {v7}, Ljava/lang/StringBuilder;-><init>()V
    43 
    44     const-string v8, "u8fd9u662fu4e00u4e2au624bu5199u7684u0073u006du0061u006cu0069u5b9eu4f8b"
    45 
    46     invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    47 
    48     move-result-object v7
    49 
    50     invoke-virtual {v7}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
    51 
    52     move-result-object v9
    53 
    54     invoke-virtual {v0, v9}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    55 
    56 
    57     # 打印字符串
    58 
    59     const-string v1, "Hello World"
    60 
    61 
    62     invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    63 
    64 
    65     return-void
    66 .end method

    https://blog.csdn.net/woblog/article/details/52106571

  • 相关阅读:
    在线教育项目-day07【添加分类前端】
    在线教育项目-day07【课程分类显示接口】
    在线教育项目-day05【实现EasyExcel对Excel操作】
    在线教育项目-day05【上传头像实现】
    在线教育项目-day05【nginx】
    在线教育项目-day05【Swagger问题】
    在线教育项目-day05【上传头像功能】
    在线教育项目-day04【路由问题】
    在线教育项目-day04【后台讲师修改功能】
    在线教育项目-day04【后台讲师添加模块】
  • 原文地址:https://www.cnblogs.com/eustoma/p/8990713.html
Copyright © 2011-2022 走看看