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 | 如果大于等于零 |
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
相关文章推荐
- 自定义公用Adapter适配器--回调机制
- 2016.05.04,英语,《Vocabulary Builder》Unit 22
- 转 Js窗体window大小设置
- 知其然不知其所以然之 Hello Android
- 设计模式之责任链模式
- 我的c\c++之旅(六)
- You must set ES_CLASSPATH var
- AssetBundle使用注意
- 安卓5.x新控件仿b站侧滑菜单
- cros跨域配置
- Dr.Elephant入门指南 ——Hadoop监控
- 匿名内部类
- 用Nodejs连接MySQL
- Android开发:组播(多播)与广播
- 在线小工具
- application和ServletContext的关系
- C语言二维数组实现扫雷游戏
- ARM的三级流水线结构(二)
- Material Design之NavigationView
- C语言二维数组实现扫雷游戏