Smali語法


title: Smali語法
date: 2016-07-17 11:23:12
categories: Dalvik
tags:
- Dalvik
- Android
- Smali


數(shù)據(jù)類型

Dalvik字節(jié)碼只有兩種格式:基本類型和引用類型涧团。對(duì)象和數(shù)組屬于引用類型

語法 含義
V void,只用于返回值類型
Z boolean
B byte
S short
C char
I int
J long
F flot
D double
L Java類 類型
[ 數(shù)組類型

Ljava/lang/String; 相當(dāng)于java.lang.String
[I 相當(dāng)于一維int數(shù)組经磅,int[]
[[I 相當(dāng)于int[][]

方法

它使用方法名辞居,參數(shù)類型和返回值來描述一個(gè)方法
package/name/ObjectName;->methodName(III)Z

package/name/ObjectName:一個(gè)類
methodName:方法名
III:參數(shù)類型
Z:返回值

(III)Z:方法簽名

BakSmali生成的方法代碼以.method指令開始后众,以.end method指令結(jié)束,根據(jù)方法的類型不同,可以會(huì)在方法前加#表示方法類型

# vitual methods:虛方法坦仍,如:

# virtual methods
.method public get(Ljava/lang/String;)Lcn/woblog/markdowndiary/domain/Note;
    .locals 2
    .param p1, "noteId"    # Ljava/lang/String;

    .prologue
    .line 50
    iget-object v0, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->orm:Lcom/litesuits/orm/LiteOrm;

    const-class v1, Lcn/woblog/markdowndiary/domain/Note;

    invoke-virtual {v0, p1, v1}, Lcom/litesuits/orm/LiteOrm;->queryById(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;

    move-result-object v0

    check-cast v0, Lcn/woblog/markdowndiary/domain/Note;

    return-object v0
.end method

# direct methods:直接方法阅羹,如:

# direct methods
.method public constructor <init>(Landroid/content/Context;)V
    .locals 2
    .param p1, "context"    # Landroid/content/Context;

    .prologue
    .line 22
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    .line 23
    iput-object p1, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->context:Landroid/content/Context;

    .line 24
    const-string v0, "note.db"

    invoke-static {p1, v0}, Lcom/litesuits/orm/LiteOrm;->newSingleInstance(Landroid/content/Context;Ljava/lang/String;)Lcom/litesuits/orm/LiteOrm;

    move-result-object v0

    iput-object v0, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->orm:Lcom/litesuits/orm/LiteOrm;

    .line 25
    iget-object v0, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->orm:Lcom/litesuits/orm/LiteOrm;

    const/4 v1, 0x1

    invoke-virtual {v0, v1}, Lcom/litesuits/orm/LiteOrm;->setDebugged(Z)V

    .line 26
    return-void
.end method

有些方法沒有這樣的注釋

.method public save(Lcn/woblog/markdowndiary/domain/Note;)V
    .locals 1
    .param p1, "note"    # Lcn/woblog/markdowndiary/domain/Note;

    .prologue
    .line 37
    iget-object v0, p0, Lcn/woblog/markdowndiary/repository/LocalNoteRepository;->orm:Lcom/litesuits/orm/LiteOrm;

    invoke-virtual {v0, p1}, Lcom/litesuits/orm/LiteOrm;->save(Ljava/lang/Object;)J

    .line 38
    return-void
.end method

靜態(tài)方法:

.method public static formatTime(J)Ljava/lang/String;
    .locals 4
    .param p0, "date"    # J

    .prologue
    .line 11
    new-instance v0, Ljava/text/SimpleDateFormat;

    const-string v1, "yyyy\u5e74MM\u6708dd\u65e5 EEEE"

    sget-object v2, Ljava/util/Locale;->CHINESE:Ljava/util/Locale;

    invoke-direct {v0, v1, v2}, Ljava/text/SimpleDateFormat;-><init>(Ljava/lang/String;Ljava/util/Locale;)V

    .line 13
    .local v0, "simpleDateFormat":Ljava/text/SimpleDateFormat;
    invoke-static {p0, p1}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;

    move-result-object v1

    invoke-virtual {v0, v1}, Ljava/text/SimpleDateFormat;->format(Ljava/lang/Object;)Ljava/lang/String;

    move-result-object v1

    return-object v1
.end method

字段

與方法表示很相似罗洗,只是字段沒有方法簽名和返回值戚宦,取而代之的是字段類型
Lpackage/name/ObjectName;->FiedlName:Ljava/lang/String;

其中字段名與字段類型用冒號(hào)“:”分割

# static fields
.field private static instance:Lcn/woblog/markdowndiary/repository/LocalNoteRepository;


# instance fields
.field private final context:Landroid/content/Context;

其中:
# static fields:靜態(tài)字段
# instance fields:實(shí)例字段

Dalvik指令集

他在調(diào)用格式上模仿了C語言的調(diào)用約定,官方地址,指令語法與助詞有如下特點(diǎn):

  1. 采用采用從目標(biāo)(destination)到源(source)的方法
  2. 根據(jù)字節(jié)碼的大小與類型不同炭晒,一些字節(jié)碼添加了名稱后綴已消除歧義
    2.1 32位常規(guī)類型的字節(jié)碼未添加任何后綴
    2.2 64位常規(guī)類型的字節(jié)碼添加 -wide后綴
    3.3 特殊類型的字節(jié)碼根據(jù)具體類型添加后綴待逞,-boolean,-byte,-char,-short,-int,-long,-float,-double,-object,-string,-class,-void之一
  3. 根據(jù)字節(jié)碼的布局和選項(xiàng)不同,一些字節(jié)碼添加了字節(jié)后綴消除歧義网严,后綴與字節(jié)碼直接用/分割
  4. 在指令集的描述中识樱,寬度值中每個(gè)字母表示寬度為4位

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

move:基礎(chǔ)字節(jié)碼(base opcode),標(biāo)示是基本操作
wide:標(biāo)示指令操作的數(shù)據(jù)寬度為64位寬度
from16:字節(jié)碼后綴(opcode suffix),標(biāo)示源(vBBBB)為一個(gè)16的寄存器引用變量
vAA:目的寄存器震束,v0~v255
vBBBB:源寄存器怜庸,v0~v65535

指令

nop

空操作,被用來做對(duì)齊代碼

數(shù)據(jù)定義

用來定義程序中用到的常量垢村,字符串割疾,類等數(shù)據(jù)
const/4 vA, #+B :將數(shù)組擴(kuò)展為32位后賦給寄存器vA
const/16 vAA, #+BBBB
const vAA, #+BBBBBBBB:將數(shù)組賦值給寄存器vAA
const-wide/16 vAA, #+BBBBB :將數(shù)值擴(kuò)展為64位后賦給寄存器vAA
const-string vAA, string@BBBB:將字符串索引構(gòu)造一個(gè)字符串并賦給vAA
const-class vAA, type@BBBB:通過類型索引獲取一個(gè)類的引用并賦給寄存器vAA

private void testConst() {
    int a = 1;
    int b = 7;
    int c = 254;
    int d = 2345;
    int d1 = 65538;

    long e = 12435465657677L;
    float f = 123235409234.09097945F;
    double g = 111343333454999999999.912384375;
}
//-8到7用4,大于255小于等于65535用16
const/4 v0, 0x1

.line 25
.local v0, "a":I
const/4 v1, 0x7

.line 26
.local v1, "b":I
const/16 v2, 0xfe

.line 27
.local v2, "c":I
const/16 v3, 0x929

.line 28
.local v3, "d":I
const v4, 0x10002 //65538肝断,大于65535用const v4

//long用const-wide
.line 30
.local v4, "d1":I
const-wide v6, 0xb4f5b835d4dL

.line 31
.local v6, "e":J
const v5, 0x51e58b39

.line 32
.local v5, "f":F
const-wide v8, 0x441824cbef6b9491L    # 1.11343333455E20

數(shù)據(jù)操作指令

move destination, source
根據(jù)字節(jié)碼大小和類型不同杈曲,后面回天津不同的后綴
move vA, vB:vB寄存器值賦值給vA寄存器,都為4位
move-object vA,vB
move-result vAA:將上一個(gè)invoke類型的指令操作的單字非對(duì)象結(jié)果負(fù)責(zé)vAA寄存器
move-result-object vAA:將上一個(gè)invoke類型指令操作的對(duì)象賦值給vAA
move-exception vAA:保存一個(gè)運(yùn)行時(shí)發(fā)生的異常vAA寄存器胸懈,必須是異常發(fā)生時(shí)的異常處理的第一條指令

private void testMove() {
    int a = 100;
    long b = 100000000000000000L;

    int c = a;
    long d = b;

    Log.d(TAG,c+"");
    Log.d(TAG,d+"");


    int e = getIntResult();
    Log.d(TAG,e+"");

    try {
        int f = e/c;
    } catch (ArithmeticException e1) {
        e1.printStackTrace();
    }catch (Exception e1) {
        e1.printStackTrace();
    }finally {

    }
}

//move-result-object
invoke-direct {v7}, Ljava/lang/StringBuilder;-><init>()V

invoke-virtual {v7, v1}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

move-result-object v7

const-string v8, ""

invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v7

//move-result
invoke-direct {p0}, Lcom/woblog/testsmali/MainActivity;->getIntResult()I

move-result v6

//move exception
.line 35
:try_start_0
div-int v8, v6, v1
:try_end_0
.catch Ljava/lang/ArithmeticException; {:try_start_0 .. :try_end_0} :catch_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_1
.catchall {:try_start_0 .. :try_end_0} :catchall_0

.line 43
:goto_0
return-void

.line 36
:catch_0
move-exception v7

.line 37
.local v7, "e1":Ljava/lang/ArithmeticException;
:try_start_1
invoke-virtual {v7}, Ljava/lang/ArithmeticException;->printStackTrace()V
:try_end_1
.catchall {:try_start_1 .. :try_end_1} :catchall_0

goto :goto_0

.line 40
.end local v7    # "e1":Ljava/lang/ArithmeticException;
:catchall_0
move-exception v8

throw v8

.line 38
:catch_1
move-exception v7

.line 39
.local v7, "e1":Ljava/lang/Exception;
:try_start_2
invoke-virtual {v7}, Ljava/lang/Exception;->printStackTrace()V
:try_end_2
.catchall {:try_start_2 .. :try_end_2} :catchall_0

goto :goto_0

返回指令

return-void :返回一個(gè)void
return vAA:返回一個(gè)32位非對(duì)象類型的值,返回寄存器為8位
return-wide vAA:返回一個(gè)64位非對(duì)象類型的值恰响,返回寄存器為8位
return-object vAA:返回一個(gè)對(duì)象類型

private String returnObject() {
    return new String("");
}

private float returnFloat() {
    return 12333334.00234345F;
}

private double returnDouble() {
    return 3425465767.9345865;
}

private long returnLong() {
    return 12445657999999L;
}

private int returnInt() {
    return 1024;
}

private void returnVoid() {
    int a = 3;
}
.method private returnDouble()D
    .locals 2

    .prologue
    .line 40
    const-wide v0, 0x41e9858eb4fde822L    # 3.4254657679345865E9

    return-wide v0
.end method

.method private returnFloat()F
    .locals 1

    .prologue
    .line 36
    const v0, 0x4b3c3116    # 1.2333334E7f

    return v0
.end method

.method private returnInt()I
    .locals 1

    .prologue
    .line 48
    const/16 v0, 0x400

    return v0
.end method

.method private returnLong()J
    .locals 2

    .prologue
    .line 44
    const-wide v0, 0xb51bb062a7fL

    return-wide v0
.end method

.method private returnObject()Ljava/lang/String;
    .locals 2

    .prologue
    .line 32
    new-instance v0, Ljava/lang/String;

    const-string v1, ""

    invoke-direct {v0, v1}, Ljava/lang/String;-><init>(Ljava/lang/String;)V

    return-object v0
.end method

.method private returnVoid()V
    .locals 1

    .prologue
    .line 52
    const/4 v0, 0x3

    .line 53
    .local v0, "a":I
    return-void
.end method

鎖指令

鎖指令多用在多線程程序中對(duì)同一對(duì)象的操作
monitor-enter vAA 為指定的對(duì)象獲取鎖
monitor-exit vAA 釋放指定的對(duì)象的鎖

private void callSynchronizeClassMethod() {
    synchronized (MainActivity.class) {
        Log.d("TAG","synchronized class");
    }
}

private void callSynchronizeMethod() {
    synchronized (this) {
        Log.d("TAG","synchronized this");
    }
}

private synchronized void callLockMethod() {
    Log.d("TAG","synchronized method");
}
.method private declared-synchronized callLockMethod()V
    .locals 2

    .prologue
    .line 43
    monitor-enter p0

    :try_start_0
    const-string v0, "TAG"

    const-string v1, "synchronized method"

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    .line 44
    monitor-exit p0

    return-void

    .line 43
    :catchall_0
    move-exception v0

    monitor-exit p0

    throw v0
.end method

.method private callSynchronizeClassMethod()V
    .locals 3

    .prologue
    .line 31
    const-class v1, Lcom/woblog/testsmali/MainActivity;

    monitor-enter v1

    .line 32
    :try_start_0
    const-string v0, "TAG"

    const-string v2, "synchronized class"

    invoke-static {v0, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 33
    monitor-exit v1

    .line 34
    return-void

    .line 33
    :catchall_0
    move-exception v0

    monitor-exit v1
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    throw v0
.end method

.method private callSynchronizeMethod()V
    .locals 2

    .prologue
    .line 37
    monitor-enter p0

    .line 38
    :try_start_0
    const-string v0, "TAG"

    const-string v1, "synchronized this"

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 39
    monitor-exit p0

    .line 40
    return-void

    .line 39
    :catchall_0
    move-exception v0

    monitor-exit p0
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    throw v0
.end method

實(shí)例操作

包括類型轉(zhuǎn)換趣钱,檢查和創(chuàng)建新實(shí)例
check-cast vAA, type@BBBB:將vAA中的對(duì)象轉(zhuǎn)為指定類型,如果失敗會(huì)拋出ClassCastException異常胚宦,如果類型B是基本類型首有,對(duì)于分基本類型的A來說運(yùn)行始終是失敗的
instance-of vA, vB, type@CCCC:判斷vB寄存器的對(duì)象是否可以轉(zhuǎn)為指定類型燕垃,如果可以vA為1,否則為0
new-instance vAA, type@BBBB:構(gòu)造一個(gè)指定類型的對(duì)象井联,并賦值給vAA寄存器卜壕,不能是數(shù)組類型

CharSequence cs = new String();
Object o = cs;

String s = (String) cs;

//實(shí)例檢測(cè)
if (s instanceof CharSequence) {
    Log.d("TAG", "ok");
} else {
    Log.d("TAG","no");
}


//創(chuàng)建實(shí)例
StringBuilder sb = new StringBuilder();
sb.append("Ok");

String s1 = new String("new string");
String s2 = "string";
new-instance v1, Ljava/lang/String;

invoke-direct {v1}, Ljava/lang/String;-><init>()V

.line 33
.local v1, "cs":Ljava/lang/CharSequence;
move-object v7, v1

.local v7, "o":Ljava/lang/CharSequence;
move-object v8, v1

.line 35
check-cast v8, Ljava/lang/String;

.line 38
.local v8, "s":Ljava/lang/String;
instance-of v12, v8, Ljava/lang/CharSequence;

if-eqz v12, :cond_0

.line 39
const-string v12, "TAG"

const-string v13, "ok"

invoke-static {v12, v13}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

.line 46
:goto_0
new-instance v11, Ljava/lang/StringBuilder;

invoke-direct {v11}, Ljava/lang/StringBuilder;-><init>()V

.line 47
.local v11, "sb":Ljava/lang/StringBuilder;
const-string v12, "Ok"

invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

.line 49
new-instance v9, Ljava/lang/String;

const-string v12, "new string"

invoke-direct {v9, v12}, Ljava/lang/String;-><init>(Ljava/lang/String;)V

.line 50
.local v9, "s1":Ljava/lang/String;
const-string v10, "string"

.line 51
.local v10, "s2":Ljava/lang/String;
return-void

.line 41
.end local v9    # "s1":Ljava/lang/String;
.end local v10    # "s2":Ljava/lang/String;
.end local v11    # "sb":Ljava/lang/StringBuilder;
:cond_0
const-string v12, "TAG"

const-string v13, "no"

invoke-static {v12, v13}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

goto :goto_0

數(shù)組操作

包括獲取數(shù)組長度,新建數(shù)組烙常,數(shù)組賦值轴捎,數(shù)組元素取值與賦值等
array-length vA, vB:獲取vB寄存器中數(shù)組的長度并賦值給vA寄存器
new-array vA, vB, type@CCCC:構(gòu)造指定類型(type@CCCC)與大小(vB)的數(shù)組,并賦值給vA寄存器
filled-new-array {vC,vD,vE,vF,vG}, type@BBBB:構(gòu)造指定類型(type@BBBB)與大小vA的數(shù)組并填充數(shù)組內(nèi)容蚕脏,除了指定數(shù)組的大小還指定了參數(shù)個(gè)數(shù)
filled-new-array/range {vCCCC .. vNNNN}, type@BBBB:與上一條類似侦副,只是參數(shù)使用取值范圍,vC是第一個(gè)參數(shù)寄存器驼鞭,N=A+C-1
fill-array-data vAA, +BBBBBBBB:vAA為寄存器數(shù)組引用秦驯,后面跟一個(gè)數(shù)據(jù)表
arrayop vAA, vBB, vCC:對(duì)vBB寄存器指定的數(shù)組元素進(jìn)入取值或賦值。vCC指定數(shù)組元素索引挣棕,vAA寄存器用來存放讀取的或需要設(shè)置的值译隘。讀取元素使用age類指令,賦值使用aput類指令洛心,根據(jù)數(shù)組中存儲(chǔ)的類指令后面會(huì)跟不同的后綴:
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

private void testArray() {
    int[] ints = new int[2];
    int[] ints1 = null;
    int[] ints2 = {1,2,3};

    Integer[] integers = new Integer[]{1,2,4};

    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};

    //數(shù)組長度
    int length = ints.length;
    int length1 = ints2.length;
    int length2 = strings.length;

    //獲取數(shù)組元素
    int string = strings[30];
    int string1 = ints2[1];

    //賦值
    strings[30] =  length;
    ints2[1] =  length2;
}
.method private testArray()V
    .locals 15

    .prologue
    const/16 v14, 0x1e

    const/4 v10, 0x3

    const/4 v13, 0x2

    const/4 v12, 0x1

    .line 27
    new-array v1, v13, [I

    .line 28
    .local v1, "ints":[I
    const/4 v2, 0x0

    .line 29
    .local v2, "ints1":[I
    new-array v3, v10, [I

    fill-array-data v3, :array_0

    .line 31
    .local v3, "ints2":[I
    new-array v0, v10, [Ljava/lang/Integer;

    const/4 v10, 0x0

    invoke-static {v12}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

    move-result-object v11

    aput-object v11, v0, v10

    invoke-static {v13}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

    move-result-object v10

    aput-object v10, v0, v12

    const/4 v10, 0x4

    invoke-static {v10}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

    move-result-object v10

    aput-object v10, v0, v13

    .line 33
    .local v0, "integers":[Ljava/lang/Integer;
    const/16 v10, 0x3a

    new-array v9, v10, [I

    fill-array-data v9, :array_1

    .line 36
    .local v9, "strings":[I
    array-length v4, v1

    .line 37
    .local v4, "length":I
    array-length v5, v3

    .line 38
    .local v5, "length1":I
    array-length v6, v9

    .line 41
    .local v6, "length2":I
    aget v7, v9, v14

    .line 42
    .local v7, "string":I
    aget v8, v3, v12

    .line 45
    .local v8, "string1":I
    aput v4, v9, v14

    .line 46
    aput v6, v3, v12

    .line 47
    return-void

    .line 29
    :array_0
    .array-data 4
        0x1
        0x2
        0x3
    .end array-data

    .line 33
    :array_1
    .array-data 4
        0x1
        0x2
        0x3
        0x4
        0x5
        0x6
        0x5
        0x6
        0x6
        0x6
        0x6
        0x6
        0x6
        0x7
        0x7
        0x8
        0x8
        0x8
        0x8
        0x8
        0x1
        0x1
        0x1
        0x3
        0x3
        0x5
        0x6
        0x36
        0x5
        0x6
        0x38
        0x237
        0x43
        0x6
        0x22
        0x2d
        0x2d
        0x6
        0x38
        0x39
        0x2d
        0x2d
        0x5
        0x38
        0x38
        0x7
        0x22
        0x21f
        0x21f
        0x6
        0x38
        0x38
        0x2d
        0x4
        0x36
        0x5
        0x2d
        0x38
    .end array-data
.end method

異常指令

throw vAA:拋出vAA寄存器中指定類型的異常

private void throw2() {
    try {
        throw new Exception("test throw runtime exception");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void throw1() {
    throw new RuntimeException("test throw runtime exception");
}
.method private throw1()V
    .locals 2

    .prologue
    .line 38
    new-instance v0, Ljava/lang/RuntimeException;

    const-string v1, "test throw runtime exception"

    invoke-direct {v0, v1}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V

    throw v0
.end method

.method private throw2()V
    .locals 3

    .prologue
    .line 31
    :try_start_0
    new-instance v1, Ljava/lang/Exception;

    const-string v2, "test throw runtime exception"

    invoke-direct {v1, v2}, Ljava/lang/Exception;-><init>(Ljava/lang/String;)V

    throw v1
    :try_end_0
    .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

    .line 32
    :catch_0
    move-exception v0

    .line 33
    .local v0, "e":Ljava/lang/Exception;
    invoke-virtual {v0}, Ljava/lang/Exception;->printStackTrace()V

    .line 35
    return-void
.end method

跳轉(zhuǎn)指令

用于從當(dāng)前地址跳轉(zhuǎn)到指定的偏移處细燎,提供了三種指令:無條件(goto),分支跳轉(zhuǎn)(switch),條件跳轉(zhuǎn)(if)
goto +AA:無條件跳轉(zhuǎn)到指定偏移處,AA不能為0
goto/16 +AAAA
goto/32 +AAAAAAAA

packed-switch vAA, +BBBBBBBB:分支跳轉(zhuǎn)皂甘,vAA寄存器為switch分支需要判斷的值

if-test vA, vB, +CCCC 條件跳轉(zhuǎn)指令玻驻,比較vA寄存器與vB寄存器的值,如果比較結(jié)果滿足就跳轉(zhuǎn)到CCCC指定的偏移處偿枕,不能為0璧瞬,有以下幾條:

if-eq:if(vA==vB)
if-ne:vA!=vB
if-lt:vA<vB
if-gt:vA>vB
if-le:vA<=vB
if-ge:vA>=vB

if-testz vAA, +BBBB:條件轉(zhuǎn)移,拿vAA寄存器與0比較渐夸,如果比較結(jié)果滿足或值為0就跳轉(zhuǎn)到BBBB指定的偏移處嗤锉,不為0

if-eqz:vAA==0
if-nez:vAA!=0
if-ltz:vAA<0
if-gtz:vAA>0
if-lez:vAA<=0
if-gez:vAA>=0

private void testIfz() {
    int a = 3;
    if (a == 0) {

    } else {

    }
    if (a != 0) {

    } else {

    }
    if (a < 0) {

    } else {

    }
    if (a > 0) {

    } else {

    }
    if (a <= 0) {

    } else {

    }
    if (a >= 0) {

    } else {

    }

    if (a < 5) {
        Log.d("TAG", "<5");
    } else if (a > 5) {
        Log.d("TAG", ">5");
    } else {
        Log.d("TAG", "=5");
    }
}

private void testIf() {
    int a = 2;
    int b = 3;
    if (a == b) {

    } else {

    }
    if (a != b) {

    } else {

    }
    if (a < b) {

    } else {

    }
    if (a > b) {

    } else {

    }
    if (a <= b) {

    } else {

    }
    if (a >= b) {

    } else {

    }

}
.method private testIf()V
    .locals 2

    .prologue
    .line 69
    const/4 v0, 0x2

    .line 70
    .local v0, "a":I
    const/4 v1, 0x3

    .line 71
    .local v1, "b":I
    if-ne v0, v1, :cond_0

    .line 76
    :cond_0
    if-eq v0, v1, :cond_1

    .line 81
    :cond_1
    if-ge v0, v1, :cond_2

    .line 86
    :cond_2
    if-le v0, v1, :cond_3

    .line 91
    :cond_3
    if-gt v0, v1, :cond_4

    .line 96
    :cond_4
    if-lt v0, v1, :cond_5

    .line 102
    :cond_5
    return-void
.end method

.method private testIfz()V
    .locals 3

    .prologue
    const/4 v1, 0x5

    .line 27
    const/4 v0, 0x3

    .line 28
    .local v0, "a":I
    if-nez v0, :cond_0

    .line 33
    :cond_0
    if-eqz v0, :cond_1

    .line 38
    :cond_1
    if-gez v0, :cond_2

    .line 43
    :cond_2
    if-lez v0, :cond_3

    .line 48
    :cond_3
    if-gtz v0, :cond_4

    .line 53
    :cond_4
    if-ltz v0, :cond_5

    .line 59
    :cond_5
    if-ge v0, v1, :cond_6

    .line 60
    const-string v1, "TAG"

    const-string v2, "<5"

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 66
    :goto_0
    return-void

    .line 61
    :cond_6
    if-le v0, v1, :cond_7

    .line 62
    const-string v1, "TAG"

    const-string v2, ">5"

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    goto :goto_0

    .line 64
    :cond_7
    const-string v1, "TAG"

    const-string v2, "=5"

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    goto :goto_0
.end method

比較指令

用于對(duì)兩個(gè)寄存器的值比較
cmpkind vAA, vBB, vCC:vBB和vCC為要比較的值,結(jié)果放到vAA中
cmpl-float:單精度墓塌,vBB大于vCC瘟忱,vAA=-1,等于vAA=0,小于vAA=1
cmpg-float:?jiǎn)尉龋瑅BB大于vCC苫幢,vAA=1,等于vAA=0,小于vAA=-1
cmpl-double:雙精度
cmpg-double:雙精度
cmp-long:長整形

private void testCmpLong() {
    long a = 13;
    long b = 12;
    if (a < b) {
        Log.d("TAG", "<");
    } else if (a > b) {
        Log.d("TAG", ">");
    } else {
        Log.d("TAG", "=");
    }
}

private void testCmpDouble() {
    double a = 13.4;
    double b = 11.4;
    if (a < b) {
        Log.d("TAG", "<");
    } else if (a > b) {
        Log.d("TAG", ">");
    } else {
        Log.d("TAG", "=");
    }
}

private void testCmpFloat() {
    float a = 13.4F;
    float b = 10.4F;
    if (a < b) {
        Log.d("TAG", "<");
    } else if (a > b) {
        Log.d("TAG", ">");
    } else {
        Log.d("TAG", "=");
    }
}
.method private testCmpDouble()V
    .locals 6

    .prologue
    .line 46
    const-wide v0, 0x402acccccccccccdL    # 13.4

    .line 47
    .local v0, "a":D
    const-wide v2, 0x4026cccccccccccdL    # 11.4

    .line 48
    .local v2, "b":D
    cmpg-double v4, v0, v2

    if-gez v4, :cond_0

    .line 49
    const-string v4, "TAG"

    const-string v5, "<"

    invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 55
    :goto_0
    return-void

    .line 50
    :cond_0
    cmpl-double v4, v0, v2

    if-lez v4, :cond_1

    .line 51
    const-string v4, "TAG"

    const-string v5, ">"

    invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    goto :goto_0

    .line 53
    :cond_1
    const-string v4, "TAG"

    const-string v5, "="

    invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    goto :goto_0
.end method

.method private testCmpFloat()V
    .locals 4

    .prologue
    .line 58
    const v0, 0x41566666    # 13.4f

    .line 59
    .local v0, "a":F
    const v1, 0x41266666    # 10.4f

    .line 60
    .local v1, "b":F
    cmpg-float v2, v0, v1

    if-gez v2, :cond_0 #>=

    .line 61
    const-string v2, "TAG"

    const-string v3, "<"

    invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 67
    :goto_0
    return-void

    .line 62
    :cond_0
    cmpl-float v2, v0, v1

    if-lez v2, :cond_1 #<=

    .line 63
    const-string v2, "TAG"

    const-string v3, ">"

    invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    goto :goto_0

    .line 65
    :cond_1
    const-string v2, "TAG"

    const-string v3, "="

    invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    goto :goto_0
.end method

.method private testCmpLong()V
    .locals 6

    .prologue
    .line 34
    const-wide/16 v0, 0xd

    .line 35
    .local v0, "a":J
    const-wide/16 v2, 0xc

    .line 36
    .local v2, "b":J
    cmp-long v4, v0, v2

    if-gez v4, :cond_0

    .line 37
    const-string v4, "TAG"

    const-string v5, "<"

    invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 43
    :goto_0
    return-void

    .line 38
    :cond_0
    cmp-long v4, v0, v2

    if-lez v4, :cond_1

    .line 39
    const-string v4, "TAG"

    const-string v5, ">"

    invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    goto :goto_0

    .line 41
    :cond_1
    const-string v4, "TAG"

    const-string v5, "="

    invoke-static {v4, v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    goto :goto_0
.end method

字段操作指令

用來對(duì) 對(duì)象實(shí)例的字段進(jìn)行讀寫操作访诱。字段類型可以是Java中有效的類型,對(duì)于實(shí)例字段和靜態(tài)字段有兩類指令:
iget,iput對(duì)實(shí)例字段進(jìn)行讀韩肝,寫
sget,sput對(duì)靜態(tài)字段

會(huì)根據(jù)類型不同添加不同的后綴
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
...

private void testInstanceFieldOperator() {
    //write
    InstanceObject instanceObject = new InstanceObject();
    instanceObject.aInt=1;
    instanceObject.aLong=12454L;
    instanceObject.aFloat=12344.45F;
    instanceObject.aDouble=123546.2;
    instanceObject.object=new Object();
    instanceObject.aBoolean=true;
    instanceObject.aByte=3;
    instanceObject.aChar='c';
    instanceObject.aShort=1;

    Log.d("TAG",String.valueOf(instanceObject.aInt));
    Log.d("TAG",String.valueOf(instanceObject.aLong));
    Log.d("TAG",String.valueOf(instanceObject.aFloat));
    Log.d("TAG",String.valueOf(instanceObject.aDouble));
    Log.d("TAG",String.valueOf(instanceObject.object));
    Log.d("TAG",String.valueOf(instanceObject.aBoolean));
    Log.d("TAG",String.valueOf(instanceObject.aByte));
    Log.d("TAG",String.valueOf(instanceObject.aChar));
    Log.d("TAG",String.valueOf(instanceObject.aShort));
}

private void testStatusFieldOperator() {
    //write
    StatusObject.aInt=1;
    StatusObject.aLong=12454L;
    StatusObject.aFloat=12344.45F;
    StatusObject.aDouble=123546.2;
    StatusObject.object=new Object();
    StatusObject.aBoolean=true;
    StatusObject.aByte=3;
    StatusObject.aChar='c';
    StatusObject.aShort=1;

    Log.d("TAG",String.valueOf(StatusObject.aInt));
    Log.d("TAG",String.valueOf(StatusObject.aLong));
    Log.d("TAG",String.valueOf(StatusObject.aFloat));
    Log.d("TAG",String.valueOf(StatusObject.aDouble));
    Log.d("TAG",String.valueOf(StatusObject.object));
    Log.d("TAG",String.valueOf(StatusObject.aBoolean));
    Log.d("TAG",String.valueOf(StatusObject.aByte));
    Log.d("TAG",String.valueOf(StatusObject.aChar));
    Log.d("TAG",String.valueOf(StatusObject.aShort));
}
.method private testInstanceFieldOperator()V
    .locals 5

    .prologue
    const/4 v4, 0x1

    .line 30
    new-instance v0, Lcom/woblog/testsmali/InstanceObject;

    invoke-direct {v0}, Lcom/woblog/testsmali/InstanceObject;-><init>()V

    .line 31
    .local v0, "instanceObject":Lcom/woblog/testsmali/InstanceObject;
    iput v4, v0, Lcom/woblog/testsmali/InstanceObject;->aInt:I

    .line 32
    const-wide/16 v2, 0x30a6

    iput-wide v2, v0, Lcom/woblog/testsmali/InstanceObject;->aLong:J

    .line 33
    const v1, 0x4640e1cd

    iput v1, v0, Lcom/woblog/testsmali/InstanceObject;->aFloat:F

    .line 34
    const-wide v2, 0x40fe29a333333333L    # 123546.2

    iput-wide v2, v0, Lcom/woblog/testsmali/InstanceObject;->aDouble:D

    .line 35
    new-instance v1, Ljava/lang/Object;

    invoke-direct {v1}, Ljava/lang/Object;-><init>()V

    iput-object v1, v0, Lcom/woblog/testsmali/InstanceObject;->object:Ljava/lang/Object;

    .line 36
    iput-boolean v4, v0, Lcom/woblog/testsmali/InstanceObject;->aBoolean:Z

    .line 37
    const/4 v1, 0x3

    iput-byte v1, v0, Lcom/woblog/testsmali/InstanceObject;->aByte:B

    .line 38
    const/16 v1, 0x63

    iput-char v1, v0, Lcom/woblog/testsmali/InstanceObject;->aChar:C

    .line 39
    iput-short v4, v0, Lcom/woblog/testsmali/InstanceObject;->aShort:S

    .line 41
    const-string v1, "TAG"

    iget v2, v0, Lcom/woblog/testsmali/InstanceObject;->aInt:I

    invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;

    move-result-object v2

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 42
    const-string v1, "TAG"

    iget-wide v2, v0, Lcom/woblog/testsmali/InstanceObject;->aLong:J

    invoke-static {v2, v3}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;

    move-result-object v2

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 43
    const-string v1, "TAG"

    iget v2, v0, Lcom/woblog/testsmali/InstanceObject;->aFloat:F

    invoke-static {v2}, Ljava/lang/String;->valueOf(F)Ljava/lang/String;

    move-result-object v2

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 44
    const-string v1, "TAG"

    iget-wide v2, v0, Lcom/woblog/testsmali/InstanceObject;->aDouble:D

    invoke-static {v2, v3}, Ljava/lang/String;->valueOf(D)Ljava/lang/String;

    move-result-object v2

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 45
    const-string v1, "TAG"

    iget-object v2, v0, Lcom/woblog/testsmali/InstanceObject;->object:Ljava/lang/Object;

    invoke-static {v2}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;

    move-result-object v2

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 46
    const-string v1, "TAG"

    iget-boolean v2, v0, Lcom/woblog/testsmali/InstanceObject;->aBoolean:Z

    invoke-static {v2}, Ljava/lang/String;->valueOf(Z)Ljava/lang/String;

    move-result-object v2

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 47
    const-string v1, "TAG"

    iget-byte v2, v0, Lcom/woblog/testsmali/InstanceObject;->aByte:B

    invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;

    move-result-object v2

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 48
    const-string v1, "TAG"

    iget-char v2, v0, Lcom/woblog/testsmali/InstanceObject;->aChar:C

    invoke-static {v2}, Ljava/lang/String;->valueOf(C)Ljava/lang/String;

    move-result-object v2

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 49
    const-string v1, "TAG"

    iget-short v2, v0, Lcom/woblog/testsmali/InstanceObject;->aShort:S

    invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;

    move-result-object v2

    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 50
    return-void
.end method

.method private testStatusFieldOperator()V
    .locals 4

    .prologue
    const/4 v2, 0x1

    .line 54
    sput v2, Lcom/woblog/testsmali/StatusObject;->aInt:I

    .line 55
    const-wide/16 v0, 0x30a6

    sput-wide v0, Lcom/woblog/testsmali/StatusObject;->aLong:J

    .line 56
    const v0, 0x4640e1cd

    sput v0, Lcom/woblog/testsmali/StatusObject;->aFloat:F

    .line 57
    const-wide v0, 0x40fe29a333333333L    # 123546.2

    sput-wide v0, Lcom/woblog/testsmali/StatusObject;->aDouble:D

    .line 58
    new-instance v0, Ljava/lang/Object;

    invoke-direct {v0}, Ljava/lang/Object;-><init>()V

    sput-object v0, Lcom/woblog/testsmali/StatusObject;->object:Ljava/lang/Object;

    .line 59
    sput-boolean v2, Lcom/woblog/testsmali/StatusObject;->aBoolean:Z

    .line 60
    const/4 v0, 0x3

    sput-byte v0, Lcom/woblog/testsmali/StatusObject;->aByte:B

    .line 61
    const/16 v0, 0x63

    sput-char v0, Lcom/woblog/testsmali/StatusObject;->aChar:C

    .line 62
    sput-short v2, Lcom/woblog/testsmali/StatusObject;->aShort:S

    .line 64
    const-string v0, "TAG"

    sget v1, Lcom/woblog/testsmali/StatusObject;->aInt:I

    invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 65
    const-string v0, "TAG"

    sget-wide v2, Lcom/woblog/testsmali/StatusObject;->aLong:J

    invoke-static {v2, v3}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 66
    const-string v0, "TAG"

    sget v1, Lcom/woblog/testsmali/StatusObject;->aFloat:F

    invoke-static {v1}, Ljava/lang/String;->valueOf(F)Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 67
    const-string v0, "TAG"

    sget-wide v2, Lcom/woblog/testsmali/StatusObject;->aDouble:D

    invoke-static {v2, v3}, Ljava/lang/String;->valueOf(D)Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 68
    const-string v0, "TAG"

    sget-object v1, Lcom/woblog/testsmali/StatusObject;->object:Ljava/lang/Object;

    invoke-static {v1}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 69
    const-string v0, "TAG"

    sget-boolean v1, Lcom/woblog/testsmali/StatusObject;->aBoolean:Z

    invoke-static {v1}, Ljava/lang/String;->valueOf(Z)Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 70
    const-string v0, "TAG"

    sget-byte v1, Lcom/woblog/testsmali/StatusObject;->aByte:B

    invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 71
    const-string v0, "TAG"

    sget-char v1, Lcom/woblog/testsmali/StatusObject;->aChar:C

    invoke-static {v1}, Ljava/lang/String;->valueOf(C)Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 72
    const-string v0, "TAG"

    sget-short v1, Lcom/woblog/testsmali/StatusObject;->aShort:S

    invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 73
    return-void
.end method

方法調(diào)用

在方法調(diào)用者我們可以看到有:

invoke-super {p0, p1}, Lcom/woblog/testsmali/BaseActivity;->onCreate(Landroid/os/Bundle;)V

invoke-virtual {p0, v0}, Lcom/woblog/testsmali/MainActivity;->setContentView(I)V

invoke-direct {p0}, Lcom/woblog/testsmali/MainActivity;->initMove()V

invoke-static {}, Lcom/woblog/testsmali/TimeUtil;->getCurrentTime()J

invoke-interface {v0}, Lcom/woblog/testsmali/ICallback;->onSuccess()V

數(shù)據(jù)轉(zhuǎn)換

數(shù)據(jù)轉(zhuǎn)換指令用于將一種數(shù)據(jù)類型轉(zhuǎn)換為另一個(gè)類型,unop vA, vB:寄存器存儲(chǔ)要轉(zhuǎn)換的數(shù)據(jù)哀峻,vA存儲(chǔ)轉(zhuǎn)換后的數(shù)據(jù)
neg-int:整形求補(bǔ)
not-int:整形求反
neg-long:長整型求補(bǔ)
not-long:長整型求反
neg-float:單精度求補(bǔ)
not-float:
neg-double:
not-double:

int-to-long:整型轉(zhuǎn)為長整型
int-to-float:整型轉(zhuǎn)單精度浮點(diǎn)型
int-to-double:整型轉(zhuǎn)雙精度浮點(diǎn)型

int-to-byte:整型轉(zhuǎn)字節(jié)型
int-to-char:整型轉(zhuǎn)字符串
int-to-short:整型轉(zhuǎn)短整型

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

private void testConvert() {
    int i1=13;

    //int 轉(zhuǎn)其他類型
    long l1 = i1;
    float f1 = i1;
    double d1 = i1;

    byte b1 = (byte) i1;
    char c1 = (char) i1;
    short s1 = (short) i1;

    //long 轉(zhuǎn)其他類型
    long l2 = 234444556576L;
    int i2 = (int) l2;
    float f2 = l2;
    double d2 = l2;

    //float 轉(zhuǎn)其他類型
    float f10 =234399.9F;
    int i10 = (int) f10;
    long l10 = (long) f10;
    double d10 = f10;

    //double 轉(zhuǎn)其他類型
    double d20 = 123344445.324;
    int i20 = (int) d20;
    long l20 = (long) d20;
    float f20 = (float) d20;
}
.method private testConvert()V
    .locals 29

    .prologue
    .line 30
    const/16 v16, 0xd

    .line 33
    .local v16, "i1":I
    move/from16 v0, v16

    int-to-long v0, v0

    move-wide/from16 v20, v0

    .line 34
    .local v20, "l1":J
    move/from16 v0, v16

    int-to-float v12, v0

    .line 35
    .local v12, "f1":F
    move/from16 v0, v16

    int-to-double v4, v0

    .line 37
    .local v4, "d1":D
    move/from16 v0, v16

    int-to-byte v2, v0

    .line 38
    .local v2, "b1":B
    move/from16 v0, v16

    int-to-char v3, v0

    .line 39
    .local v3, "c1":C
    move/from16 v0, v16

    int-to-short v0, v0

    move/from16 v28, v0

    .line 42
    .local v28, "s1":S
    const-wide v24, 0x3695fc0920L

    .line 43
    .local v24, "l2":J
    move-wide/from16 v0, v24

    long-to-int v0, v0

    move/from16 v18, v0

    .line 44
    .local v18, "i2":I
    move-wide/from16 v0, v24

    long-to-float v14, v0

    .line 45
    .local v14, "f2":F
    move-wide/from16 v0, v24

    long-to-double v8, v0

    .line 48
    .local v8, "d2":D
    const v13, 0x4864e7fa    # 234399.9f

    .line 49
    .local v13, "f10":F
    float-to-int v0, v13

    move/from16 v17, v0

    .line 50
    .local v17, "i10":I
    float-to-long v0, v13

    move-wide/from16 v22, v0

    .line 51
    .local v22, "l10":J
    float-to-double v6, v13

    .line 54
    .local v6, "d10":D
    const-wide v10, 0x419d6858f54bc6a8L    # 1.23344445324E8

    .line 55
    .local v10, "d20":D
    double-to-int v0, v10

    move/from16 v19, v0

    .line 56
    .local v19, "i20":I
    double-to-long v0, v10

    move-wide/from16 v26, v0

    .line 57
    .local v26, "l20":J
    double-to-float v15, v10

    .line 58
    .local v15, "f20":F
    return-void
.end method

數(shù)據(jù)運(yùn)行指令

算術(shù)運(yùn)算:加涡相,減哲泊,乘,除催蝗,模切威,移位等
邏輯運(yùn)算:與,或丙号,非先朦,異或等

binop vAA, vBB, vCC:將vBB寄存器與vCC寄存器進(jìn)行運(yùn)算,結(jié)果保存到vAA

上面的指令會(huì)根據(jù)數(shù)據(jù)類型的不同在基礎(chǔ)后面添加數(shù)據(jù)類型后綴槽袄,如:-int或-long
add-type vBB:vBB寄存器與vCC寄存器值進(jìn)行加法運(yùn)算,+
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:無符號(hào)>>

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

binop/2addr vA, vB:將vA寄存器與vB寄存器進(jìn)行運(yùn)算遍尺,結(jié)果保存到vA
binop/lit16 vA, vB, #+CCCC:將vB寄存器與常量CCCC進(jìn)行運(yùn)算截酷,結(jié)果保存到vA
binop/lit8 vAA, vBB, #+CC:將vBB寄存器與常量CC進(jìn)行運(yùn)行,結(jié)果保存到vAA

Dalvik hello world

首先寫一個(gè)基本框架

.class public LHelloWorld; #定義類名
.super Ljava/lang/Object; #定義父類
.method public static main([Ljava/lang/String;)V #聲明靜態(tài)的main函數(shù)
    .locals 4 #使用的寄存器個(gè)數(shù)乾戏,包括一個(gè)參數(shù)寄存器
    .param p0, "args" #一個(gè)參數(shù)

    .prologue #代碼起始指令


    # 這里是代碼主體


    return-void
.end method

完整版如下:

.class public LHelloWorld; #定義類名
.super Ljava/lang/Object; #定義父類
.method public static main([Ljava/lang/String;)V #聲明靜態(tài)的main函數(shù)
    .locals 4 #使用的寄存器個(gè)數(shù)迂苛,包括一個(gè)參數(shù)寄存器
    .param p0, "args" #一個(gè)參數(shù)

    .prologue #代碼起始指令


    const-string v1, "Hello World"

    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

    invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V


    return-void
.end method

編譯smali

我們?nèi)ス倬W(wǎng)下載smali.jar,然后運(yùn)行

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

編譯完后我們把classes.dex push到手機(jī)里面

adb push classes.dex /data/local/ 

運(yùn)行

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

加強(qiáng)版本

.class public LHelloWorld; #定義類名
.super Ljava/lang/Object; #定義父類
.method public static main([Ljava/lang/String;)V #聲明靜態(tài)的main函數(shù)
    .locals 10 #使用的寄存器個(gè)數(shù)鼓择,包括一個(gè)參數(shù)寄存器
    .param p0, "args" #一個(gè)參數(shù)

    .prologue #代碼起始指令

    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

    # 空指令

    nop

    nop

    nop


    # 數(shù)據(jù)定義指令
    
    const/4 v2, 0x3

    const/16 v3, 0xffff ##不能大于65535

    #大于65535用-wide
    
    const-wide v4, 0x10000


    # 定義一個(gè)類 類型
    
    const-class v5, Ljava/lang/String;


    # 數(shù)據(jù)操作指令

    move v6, v5

    new-instance v7, Ljava/lang/StringBuilder;

    invoke-direct {v7}, Ljava/lang/StringBuilder;-><init>()V


    const-string v8, "\u8fd9\u662f\u624b\u5199\u7684\u0073\u006d\u0061\u006c\u0069\u0044\u0065\u006d\u006f"

    invoke-virtual {v7, v12}, Ljava/java/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilber;

    invoke-direct {v7}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v9

    invoke-virtual {v0, v9}, Ljava/io/PrintStream;->println(Ljava/java/String;)V


    # 打印字符串

    const-string v1, "Hello World"


    invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V


    return-void
.end method

如果我的文章對(duì)來帶來的幫助或者有不明白的地方三幻,可加QQ群:129961195,大家一起交流

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末呐能,一起剝皮案震驚了整個(gè)濱河市念搬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摆出,老刑警劉巖朗徊,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異偎漫,居然都是意外死亡爷恳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門象踊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來温亲,“玉大人,你說我怎么就攤上這事杯矩≌恍椋” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵菊碟,是天一觀的道長节芥。 經(jīng)常有香客問我,道長逆害,這世上最難降的妖魔是什么头镊? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮魄幕,結(jié)果婚禮上相艇,老公的妹妹穿的比我還像新娘。我一直安慰自己纯陨,他們只是感情好坛芽,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著翼抠,像睡著了一般咙轩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上阴颖,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天活喊,我揣著相機(jī)與錄音,去河邊找鬼量愧。 笑死钾菊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的偎肃。 我是一名探鬼主播煞烫,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼累颂!你這毒婦竟也來了滞详?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤紊馏,失蹤者是張志新(化名)和其女友劉穎料饥,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瘦棋,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡稀火,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赌朋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凰狞。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沛慢,靈堂內(nèi)的尸體忽然破棺而出赡若,到底是詐尸還是另有隱情,我是刑警寧澤团甲,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布逾冬,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏身腻。R本人自食惡果不足惜产还,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嘀趟。 院中可真熱鬧脐区,春花似錦、人聲如沸她按。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酌泰。三九已至媒佣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陵刹,已是汗流浹背默伍。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留授霸,地道東北人巡验。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像碘耳,于是被迫代替她去往敵國和親显设。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容