博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(3)Smali系列学习之Smali语法详解
阅读量:4595 次
发布时间:2019-06-09

本文共 43832 字,大约阅读时间需要 146 分钟。

数据类型

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 v015 16     check-cast v0, Lcn/woblog/markdowndiary/domain/Note;17 18     return-object v019 .end method

# direct methods:直接方法,如:

1 # direct methods 2 .method public constructor 
(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;->
()V 9 10 .line 2311 iput-object p1, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->context:Landroid/content/Context;12 13 .line 2414 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 v019 20 iput-object v0, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->orm:Lcom/litesuits/orm/LiteOrm;21 22 .line 2523 iget-object v0, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->orm:Lcom/litesuits/orm/LiteOrm;24 25 const/4 v1, 0x126 27 invoke-virtual {v0, v1}, Lcom/litesuits/orm/LiteOrm;->setDebugged(Z)V28 29 .line 2630 return-void31 .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;)J10 11     .line 3812     return-void13 .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, "yyyy\u5e74MM\u6708dd\u65e5 EEEE"10 11     sget-object v2, Ljava/util/Locale;->CHINESE:Ljava/util/Locale;12 13     invoke-direct {v0, v1, v2}, Ljava/text/SimpleDateFormat;->
(Ljava/lang/String;Ljava/util/Locale;)V14 15 .line 1316 .local v0, "simpleDateFormat":Ljava/text/SimpleDateFormat;17 invoke-static {p0, p1}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;18 19 move-result-object v120 21 invoke-virtual {v0, v1}, Ljava/text/SimpleDateFormat;->format(Ljava/lang/Object;)Ljava/lang/String;22 23 move-result-object v124 25 return-object v126 .end method

字段

与方法表示很相似,只是字段没有方法签名和返回值,取而代之的是字段类型 

Lpackage/name/ObjectName;->FiedlName:Ljava/lang/String;

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

1 # static fields2 .field private static instance:Lcn/woblog/markdowndiary/repository/LocalNoteRepository;3 4 5 # instance fields6 .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":I10 const/16 v2, 0xfe11 12 .line 2713 .local v2, "c":I14 const/16 v3, 0x92915 16 .line 2817 .local v3, "d":I18 const v4, 0x10002 //65538,大于65535用const v419 20 //long用const-wide21 .line 3022 .local v4, "d1":I23 const-wide v6, 0xb4f5b835d4dL24 25 .line 3126 .local v6, "e":J27 const v5, 0x51e58b3928 29 .line 3230 .local v5, "f":F31 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;->
()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 v713 14 //move-result15 invoke-direct {p0}, Lcom/woblog/testsmali/MainActivity;->getIntResult()I16 17 move-result v618 19 //move exception20 .line 3521 :try_start_022 div-int v8, v6, v123 :try_end_024 .catch Ljava/lang/ArithmeticException; {:try_start_0 .. :try_end_0} :catch_025 .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_126 .catchall {:try_start_0 .. :try_end_0} :catchall_027 28 .line 4329 :goto_030 return-void31 32 .line 3633 :catch_034 move-exception v735 36 .line 3737 .local v7, "e1":Ljava/lang/ArithmeticException;38 :try_start_139 invoke-virtual {v7}, Ljava/lang/ArithmeticException;->printStackTrace()V40 :try_end_141 .catchall {:try_start_1 .. :try_end_1} :catchall_042 43 goto :goto_044 45 .line 4046 .end local v7 # "e1":Ljava/lang/ArithmeticException;47 :catchall_048 move-exception v849 50 throw v851 52 .line 3853 :catch_154 move-exception v755 56 .line 3957 .local v7, "e1":Ljava/lang/Exception;58 :try_start_259 invoke-virtual {v7}, Ljava/lang/Exception;->printStackTrace()V60 :try_end_261 .catchall {:try_start_2 .. :try_end_2} :catchall_062 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 method10 11 .method private returnFloat()F12     .locals 113 14     .prologue15     .line 3616     const v0, 0x4b3c3116    # 1.2333334E7f17 18     return v019 .end method20 21 .method private returnInt()I22     .locals 123 24     .prologue25     .line 4826     const/16 v0, 0x40027 28     return v029 .end method30 31 .method private returnLong()J32     .locals 233 34     .prologue35     .line 4436     const-wide v0, 0xb51bb062a7fL37 38     return-wide v039 .end method40 41 .method private returnObject()Ljava/lang/String;42     .locals 243 44     .prologue45     .line 3246     new-instance v0, Ljava/lang/String;47 48     const-string v1, ""49 50     invoke-direct {v0, v1}, Ljava/lang/String;->
(Ljava/lang/String;)V51 52 return-object v053 .end method54 55 .method private returnVoid()V56 .locals 157 58 .prologue59 .line 5260 const/4 v0, 0x361 62 .line 5363 .local v0, "a":I64 return-void65 .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;)I14     :try_end_015     .catchall {:try_start_0 .. :try_end_0} :catchall_016 17     .line 4418     monitor-exit p019 20     return-void21 22     .line 4323     :catchall_024     move-exception v025 26     monitor-exit p027 28     throw v029 .end method30 31 .method private callSynchronizeClassMethod()V32     .locals 333 34     .prologue35     .line 3136     const-class v1, Lcom/woblog/testsmali/MainActivity;37 38     monitor-enter v139 40     .line 3241     :try_start_042     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;)I47 48     .line 3349     monitor-exit v150 51     .line 3452     return-void53 54     .line 3355     :catchall_056     move-exception v057 58     monitor-exit v159     :try_end_060     .catchall {:try_start_0 .. :try_end_0} :catchall_061 62     throw v063 .end method64 65 .method private callSynchronizeMethod()V66     .locals 267 68     .prologue69     .line 3770     monitor-enter p071 72     .line 3873     :try_start_074     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;)I79 80     .line 3981     monitor-exit p082 83     .line 4084     return-void85 86     .line 3987     :catchall_088     move-exception v089 90     monitor-exit p091     :try_end_092     .catchall {:try_start_0 .. :try_end_0} :catchall_093 94     throw v095 .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;->
()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, v111 12 .line 3513 check-cast v8, Ljava/lang/String;14 15 .line 3816 .local v8, "s":Ljava/lang/String;17 instance-of v12, v8, Ljava/lang/CharSequence;18 19 if-eqz v12, :cond_020 21 .line 3922 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;)I27 28 .line 4629 :goto_030 new-instance v11, Ljava/lang/StringBuilder;31 32 invoke-direct {v11}, Ljava/lang/StringBuilder;->
()V33 34 .line 4735 .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 4941 new-instance v9, Ljava/lang/String;42 43 const-string v12, "new string"44 45 invoke-direct {v9, v12}, Ljava/lang/String;->
(Ljava/lang/String;)V46 47 .line 5048 .local v9, "s1":Ljava/lang/String;49 const-string v10, "string"50 51 .line 5152 .local v10, "s2":Ljava/lang/String;53 return-void54 55 .line 4156 .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_060 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;)I65 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_1100     .array-data 4101         0x1102         0x2103         0x3104         0x4105         0x5106         0x6107         0x5108         0x6109         0x6110         0x6111         0x6112         0x6113         0x6114         0x7115         0x7116         0x8117         0x8118         0x8119         0x8120         0x8121         0x1122         0x1123         0x1124         0x3125         0x3126         0x5127         0x6128         0x36129         0x5130         0x6131         0x38132         0x237133         0x43134         0x6135         0x22136         0x2d137         0x2d138         0x6139         0x38140         0x39141         0x2d142         0x2d143         0x5144         0x38145         0x38146         0x7147         0x22148         0x21f149         0x21f150         0x6151         0x38152         0x38153         0x2d154         0x4155         0x36156         0x5157         0x2d158         0x38159     .end array-data160 .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;->
(Ljava/lang/String;)V11 12 throw v013 .end method14 15 .method private throw2()V16 .locals 317 18 .prologue19 .line 3120 :try_start_021 new-instance v1, Ljava/lang/Exception;22 23 const-string v2, "test throw runtime exception"24 25 invoke-direct {v1, v2}, Ljava/lang/Exception;->
(Ljava/lang/String;)V26 27 throw v128 :try_end_029 .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_030 31 .line 3232 :catch_033 move-exception v034 35 .line 3336 .local v0, "e":Ljava/lang/Exception;37 invoke-virtual {v0}, Ljava/lang/Exception;->printStackTrace()V38 39 .line 3540 return-void41 .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_0101 102     .line 64103     :cond_7104     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;)I109 110     goto :goto_0111 .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_1100     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;)I105 106     goto :goto_0107 .end method108 109 .method private testCmpLong()V110     .locals 6111 112     .prologue113     .line 34114     const-wide/16 v0, 0xd115 116     .line 35117     .local v0, "a":J118     const-wide/16 v2, 0xc119 120     .line 36121     .local v2, "b":J122     cmp-long v4, v0, v2123 124     if-gez v4, :cond_0125 126     .line 37127     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;)I132 133     .line 43134     :goto_0135     return-void136 137     .line 38138     :cond_0139     cmp-long v4, v0, v2140 141     if-lez v4, :cond_1142 143     .line 39144     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;)I149 150     goto :goto_0151 152     .line 41153     :cond_1154     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;)I159 160     goto :goto_0161 .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     //write27     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;->
()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;->
()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 v2106 107 invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I108 109 .line 46110 const-string v1, "TAG"111 112 iget-boolean v2, v0, Lcom/woblog/testsmali/InstanceObject;->aBoolean:Z113 114 invoke-static {v2}, Ljava/lang/String;->valueOf(Z)Ljava/lang/String;115 116 move-result-object v2117 118 invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I119 120 .line 47121 const-string v1, "TAG"122 123 iget-byte v2, v0, Lcom/woblog/testsmali/InstanceObject;->aByte:B124 125 invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;126 127 move-result-object v2128 129 invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I130 131 .line 48132 const-string v1, "TAG"133 134 iget-char v2, v0, Lcom/woblog/testsmali/InstanceObject;->aChar:C135 136 invoke-static {v2}, Ljava/lang/String;->valueOf(C)Ljava/lang/String;137 138 move-result-object v2139 140 invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I141 142 .line 49143 const-string v1, "TAG"144 145 iget-short v2, v0, Lcom/woblog/testsmali/InstanceObject;->aShort:S146 147 invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;148 149 move-result-object v2150 151 invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I152 153 .line 50154 return-void155 .end method156 157 .method private testStatusFieldOperator()V158 .locals 4159 160 .prologue161 const/4 v2, 0x1162 163 .line 54164 sput v2, Lcom/woblog/testsmali/StatusObject;->aInt:I165 166 .line 55167 const-wide/16 v0, 0x30a6168 169 sput-wide v0, Lcom/woblog/testsmali/StatusObject;->aLong:J170 171 .line 56172 const v0, 0x4640e1cd173 174 sput v0, Lcom/woblog/testsmali/StatusObject;->aFloat:F175 176 .line 57177 const-wide v0, 0x40fe29a333333333L # 123546.2178 179 sput-wide v0, Lcom/woblog/testsmali/StatusObject;->aDouble:D180 181 .line 58182 new-instance v0, Ljava/lang/Object;183 184 invoke-direct {v0}, Ljava/lang/Object;->
()V185 186 sput-object v0, Lcom/woblog/testsmali/StatusObject;->object:Ljava/lang/Object;187 188 .line 59189 sput-boolean v2, Lcom/woblog/testsmali/StatusObject;->aBoolean:Z190 191 .line 60192 const/4 v0, 0x3193 194 sput-byte v0, Lcom/woblog/testsmali/StatusObject;->aByte:B195 196 .line 61197 const/16 v0, 0x63198 199 sput-char v0, Lcom/woblog/testsmali/StatusObject;->aChar:C200 201 .line 62202 sput-short v2, Lcom/woblog/testsmali/StatusObject;->aShort:S203 204 .line 64205 const-string v0, "TAG"206 207 sget v1, Lcom/woblog/testsmali/StatusObject;->aInt:I208 209 invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;210 211 move-result-object v1212 213 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I214 215 .line 65216 const-string v0, "TAG"217 218 sget-wide v2, Lcom/woblog/testsmali/StatusObject;->aLong:J219 220 invoke-static {v2, v3}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;221 222 move-result-object v1223 224 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I225 226 .line 66227 const-string v0, "TAG"228 229 sget v1, Lcom/woblog/testsmali/StatusObject;->aFloat:F230 231 invoke-static {v1}, Ljava/lang/String;->valueOf(F)Ljava/lang/String;232 233 move-result-object v1234 235 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I236 237 .line 67238 const-string v0, "TAG"239 240 sget-wide v2, Lcom/woblog/testsmali/StatusObject;->aDouble:D241 242 invoke-static {v2, v3}, Ljava/lang/String;->valueOf(D)Ljava/lang/String;243 244 move-result-object v1245 246 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I247 248 .line 68249 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 v1256 257 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I258 259 .line 69260 const-string v0, "TAG"261 262 sget-boolean v1, Lcom/woblog/testsmali/StatusObject;->aBoolean:Z263 264 invoke-static {v1}, Ljava/lang/String;->valueOf(Z)Ljava/lang/String;265 266 move-result-object v1267 268 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I269 270 .line 70271 const-string v0, "TAG"272 273 sget-byte v1, Lcom/woblog/testsmali/StatusObject;->aByte:B274 275 invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;276 277 move-result-object v1278 279 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I280 281 .line 71282 const-string v0, "TAG"283 284 sget-char v1, Lcom/woblog/testsmali/StatusObject;->aChar:C285 286 invoke-static {v1}, Ljava/lang/String;->valueOf(C)Ljava/lang/String;287 288 move-result-object v1289 290 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I291 292 .line 72293 const-string v0, "TAG"294 295 sget-short v1, Lcom/woblog/testsmali/StatusObject;->aShort:S296 297 invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;298 299 move-result-object v1300 301 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I302 303 .line 73304 return-void305 .end method

方法调用

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

1 invoke-super {p0, p1}, Lcom/woblog/testsmali/BaseActivity;->onCreate(Landroid/os/Bundle;)V2 3 invoke-virtual {p0, v0}, Lcom/woblog/testsmali/MainActivity;->setContentView(I)V4 5 invoke-direct {p0}, Lcom/woblog/testsmali/MainActivity;->initMove()V6 7 invoke-static {}, Lcom/woblog/testsmali/TimeUtil;->getCurrentTime()J8 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, v0101 102     .line 56103     .local v19, "i20":I104     double-to-long v0, v10105 106     move-wide/from16 v26, v0107 108     .line 57109     .local v26, "l20":J110     double-to-float v15, v10111 112     .line 58113     .local v15, "f20":F114     return-void115 .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-void14 .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;)V15 16 17     return-void18 .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     nop14 15     nop16 17     nop18 19 20     # 数据定义指令21 22     const/4 v2, 0x323 24     const/16 v3, 0xffff ##不能大于6553525 26     #大于65535用-wide27 28     const-wide v4, 0x1000029 30 31     # 定义一个类 类型32 33     const-class v5, Ljava/lang/String;34 35 36     # 数据操作指令37 38     move v6, v239 40     new-instance v7, Ljava/lang/StringBuilder;41 42     invoke-direct {v7}, Ljava/lang/StringBuilder;->
()V43 44 const-string v8, "\u8fd9\u662f\u4e00\u4e2a\u624b\u5199\u7684\u0073\u006d\u0061\u006c\u0069\u5b9e\u4f8b"45 46 invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;47 48 move-result-object v749 50 invoke-virtual {v7}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;51 52 move-result-object v953 54 invoke-virtual {v0, v9}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V55 56 57 # 打印字符串58 59 const-string v1, "Hello World"60 61 62 invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V63 64 65 return-void66 .end method

 

转载于:https://www.cnblogs.com/eustoma/p/8990713.html

你可能感兴趣的文章
JavaScript空判断
查看>>
洛谷 P1439 【模板】最长公共子序列(DP,LIS?)
查看>>
python timeit
查看>>
Wireless Network 并查集
查看>>
51nod 1019 逆序数
查看>>
打电话的代码
查看>>
C++ STL stack(栈)
查看>>
实验3观后感
查看>>
用js采集网页数据并插入数据库最快的方法
查看>>
final关键字
查看>>
作业七
查看>>
【HNOI2006】【Luogu2320】鬼谷子的钱袋(进制,玄学)
查看>>
爬虫大作业
查看>>
spring boot之actuator简介
查看>>
禁用php函数
查看>>
11.5随笔
查看>>
[err]default argument given for parameter 3 of '***'
查看>>
spring bean depends on
查看>>
51nod1256【exgcd求逆元】
查看>>
JCEF3——谷歌浏览器内核Java版实现(一):使用jawt获取窗体句柄
查看>>