您的位置:首页 > 其它

smali语言程序流程控制语法

2016-05-04 14:01 337 查看

选择结构(if-else)

smali条件跳转分支语法

if-<条件> v0 v1,:cond_** // 如果v0<条件>v1成立,则跳转到:cond_**处的代码。
if-eq vA, vB, :cond_1f   //如果vA等于vB则程序跳转到:cond_1f处的代码执,行。


条件判断关键字如下

条件关键字意思
if-eq如果等于
if-ne如果不等于
if-lt如果小于
if-le如果小于等于
if-gt如果大于
if-ge如果大于等于
if-eqz如果等于零
if-nez如果不等于0
if-ltz如果小于零
if-lez如果小于等于零
if-gtz如果大于零
if-gez如果大于等于零
java代码

int a = 2;
int b = 3;
int c = 4;
private void ifelseMethod() {
if (b > c) {
Log.d(TAG, "b>c");
} else if (b > a) {
Log.d(TAG, "b>a");
} else {
Log.d(TAG, "b<a, b<c");
}
}


smali代码

.method private ifelseMethod()V
.registers 3

.prologue
.line 65
iget v0, p0, Lcom/example/user/smalitest/MainActivity;->b:I#v0--b

iget v1, p0, Lcom/example/user/smalitest/MainActivity;->c:I#v1--c

if-le v0, v1, :cond_e #如果v0小于等于v1(java代码中if(b>c)不成立)则跳转到:cond_e处执行代码(第24行),否则接着往下执行

.line 66
iget-object v0, p0, Lcom/example/user/smalitest/MainActivity;->TAG:Ljava/lang/String;#这里是(b>c)情况下执行的代码

const-string v1, "b>c"

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

.line 73
:goto_d#标记:goto_d,   在其他地方的代码出现goto :goto_d,程序会跳转到这里执行
return-void#return void 跳出方法,后边其他的代码都不会执行

.line 67
:cond_e#标记cond_e, 如果在前边(第10行)"b<=c"的情况下,程序会跳转到cond_e 即这里接着往下执行
iget v0, p0, Lcom/example/user/smalitest/MainActivity;->b:I#v0--b

iget v1, p0, Lcom/example/user/smalitest/MainActivity;->a:I#v0--a

if-le v0, v1, :cond_1c#如果v0小于等于v1(java中 b>a)跳转到:cond_1c处(第41行)执行,否则接着往下执行

.line 68
iget-object v0, p0, Lcom/example/user/smalitest/MainActivity;->TAG:Ljava/lang/String;

const-string v1, "b>a"

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

goto :goto_d #跳转到标记为 :goto_d的地方(第20行)执行,

.line 70
:cond_1c
iget-object v0, p0, Lcom/example/user/smalitest/MainActivity;->TAG:Ljava/lang/String;

const-string v1, "b<a, b<c"

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

goto :goto_d
.end method


循环结构

在smali中循环的实现就是通过无条件跳转语句goto 加条件语句if-<条件>相结合实现。

#例如for循环,while循环
:goto_1
if_<条件> v0 v1,  :cond_2 #如果满足条件的时候就跳转到cond_2v处。
#循环内容
goto :goto_1

:cond_2
#循环结束的代码


do-while循环

:cond_1 #循环开始
#循环体
if_<条件> v0 v1, :cond_1 #如果满足v0 v1 满足条件 跳转到:cond_1继续循环
#循环结束代码


for循环例子

java代码

private void forMethod() {
for (int i = 0; i < 3; i++) {
Log.d("TAG", "Button1 Log:" + i);
}
}


smali代码

.method private forMethod()v
.registers 5

.prologue
.line 93
const/4 v0, 0x0

.local v0, "i":I
:goto_1     //循环开始
const/4 v1, 0x3

if-ge v0, v1, :cond_1f   //判断条件 满足v0>=v1 程序跳转到 :cond_1f(跳出循环) v0就是i的值,v1为3(在java中 当不满足i<3时,跳出循环,即当i>=3时)

.line 94
const-string v1, "TAG"

new-instance v2, Ljava/lang/StringBuilder;

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

const-string v3, "Button1 Log:"

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

move-result-object v2

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

move-result-object v2

invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v2

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

.line 93
add-int/lit8 v0, v0, 0x1

goto :goto_1  //跳转到 :goto_1 继续循环

.line 96
:cond_1f  //跳出循环后执行
return-void
.end method


while循环例子

java代码

private void whileMethod() {
int k = 0;
while (k < 5) {
k++;
Log.d("TAG", "Button3 Log:" + k);
}
}


smali代码

.method private whileMethod()V
.registers 5

.prologue
.line 76
const/4 v0, 0x0

.line 77
.local v0, "k":I
:goto_1   //循环开始
const/4 v1, 0x5  //v1 值为5

if-ge v0, v1, :cond_1f 判断条件 如果v0>=v1 跳转到:cond_1f处,否则继续循环(java中当k<5时,继续循环)

.line 78
add-int/lit8 v0, v0, 0x1  //java中k++

.line 79
const-string v1, "TAG"

new-instance v2, Ljava/lang/StringBuilder;

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

const-string v3, "Button3 Log:"

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

move-result-object v2

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

move-result-object v2

invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v2

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

goto :goto_1 //跳转到goto_1 继续循环

.line 81
:cond_1f //跳出循环后 从这里继续执行
return-void
.end method


do-while循环例子

java代码

private void doWhileMethod() {
int j = 0;
do {
j++;
Log.d("TAG", "Button2 Log:" + j);
} while (j < 5);

}


smali代码

.method private doWhileMethod()V
.registers 5

.prologue
.line 84
const/4 v0, 0x0

.line 86
.local v0, "j":I
:cond_1  //标记:cond_1  从这里开始循环
add-int/lit8 v0, v0, 0x1  //java中  j++;

.line 87
const-string v1, "TAG"

new-instance v2, Ljava/lang/StringBuilder;

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

const-string v3, "Button2 Log:"

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

move-result-object v2

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

move-result-object v2

invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v2

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

.line 88
const/4 v1, 0x5  //v1---5

if-lt v0, v1, :cond_1   //如果v0<v1(java中 j<5),就跳转到:cond_1处继续循环

.line 90
return-void
.end method


分支结构

分支结构在smali中有两种, 第一中,case的值是连续递增的,关键字packed-switch ,如下所示:

packed-switch p1, :pswitch_data_0  #p1为传递进来的要匹配case值的参数
:goto_0
#退出分支结构代码
:pswitch_0
#case0时的程序代码
goto :goto_0    #跳转到分支结构退出代码
:pswitch_1
#程序代码
goto :goto_0
:pswitch_2
#程序代码
goto :goto_0
:pswitch_data_0
.packed-switch 0x0  #case值开始的地方,一次递增
:pswitch_0      #case 0:
:pswitch_1      #case 1:
:pswitch_2      #case 2:
.end packed-switch


第二种 ,case值可以为任意值,关键字sparse-switch,如下所示

sparse-switch p1, :switch_data_0    #p1 传进来的参数,跳转到

:goto_0   #case 出口
#代码
:pswitch_0   #case 5 跳转到这里
#case值等于5时的程序代码
goto :goto_0    #跳转到分支结构退出代码
:pswitch_1
#程序代码
goto :goto_0
:pswitch_2
#程序代码
goto :goto_0
:pswitch_data_0
.sparse-switch   #case值开始的地方,一次递增
0x5 -> :pswitch_0      #case 5:
0xf -> :pswitch_1      #case 15:
0x23 -> :pswitch_2      #case 35:
.end packed-switch


java代码

public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_1:
forMethod();
break;
case R.id.btn_2:
doWhileMethod();
break;
case R.id.btn_3:
whileMethod();
break;
case R.id.btn_4:
ifelseMethod();
break;
}
}


smali代码

.method public onClick(Landroid/view/View;)V
.registers 3
.param p1, "view"    # Landroid/view/View;

.prologue
.line 47
invoke-virtual {p1}, Landroid/view/View;->getId()I

move-result v0

packed-switch v0, :pswitch_data_18 #switch分支开始除,v0为参数 即Java中view.getId()值。

.line 62
:goto_7
return-void

.line 49
:pswitch_8
invoke-direct {p0}, Lcom/example/user/smalitest/MainActivity;->forMethod()V

goto :goto_7

.line 52
:pswitch_c
invoke-direct {p0}, Lcom/example/user/smalitest/MainActivity;->doWhileMethod()V

goto :goto_7

.line 55
:pswitch_10
invoke-direct {p0}, Lcom/example/user/smalitest/MainActivity;->whileMethod()V

goto :goto_7

.line 58
:pswitch_14
invoke-direct {p0}, Lcom/example/user/smalitest/MainActivity;->ifelseMethod()V

goto :goto_7

.line 47
:pswitch_data_18
.packed-switch 0x7f0c0050
:pswitch_8
:pswitch_c
:pswitch_10
:pswitch_14
.end packed-switch
.end method
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: