數據類型
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語言的調用約定,官方地址,指令語法與助詞有如下特點:
- 采用采用從目標(destination)到源(source)的方法
- 根據字節碼的大小與類型不同,一些字節碼添加了名稱后綴已消除歧義
2.1 32位常規類型的字節碼未添加任何后綴
2.2 64位常規類型的字節碼添加 -wide后綴
3.3 特殊類型的字節碼根據具體類型添加后綴,-boolean,-byte,-char,-short,-int,-long,-float,-double,-object,-string,-class,-void之一 - 根據字節碼的布局和選項不同,一些字節碼添加了字節后綴消除歧義,后綴與字節碼直接用/分割
- 在指令集的描述中,寬度值中每個字母表示寬度為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
