(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, "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;-><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, "\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 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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM