android smail 语法学习之二

下面是if 语句 for 语句在smali中写法:

条件跳转分支:

"if-eq vA, vB, :cond_**"   如果vA等于vB则跳转到:cond_**
"if-ne vA, vB, :cond_**"   如果vA不等于vB则跳转到:cond_**
"if-lt vA, vB, :cond_**"    如果vA小于vB则跳转到:cond_**
"if-ge vA, vB, :cond_**"   如果vA大于等于vB则跳转到:cond_**
"if-gt vA, vB, :cond_**"   如果vA大于vB则跳转到:cond_**
"if-le vA, vB, :cond_**"    如果vA小于等于vB则跳转到:cond_**
"if-eqz vA, :cond_**"   如果vA等于0则跳转到:cond_**
"if-nez vA, :cond_**"   如果vA不等于0则跳转到:cond_**
"if-ltz vA, :cond_**"    如果vA小于0则跳转到:cond_**
"if-gez vA, :cond_**"   如果vA大于等于0则跳转到:cond_**
"if-gtz vA, :cond_**"   如果vA大于0则跳转到:cond_**
"if-lez vA, :cond_**"    如果vA小于等于0则跳转到:cond_**

if函数的java代码:

private boolean ifSense(){
        boolean tempFlag = ((3-2)==1)? true : false;
        if (tempFlag) {
            return true;
        }else{
            return false;
        }
    }
.method private ifSense()Z
    .locals 2

    .prologue
    .line 22
    const/4 v0, 0x1     // v0赋值为1

    .line 24
    .local v0, tempFlag:Z
    if-eqz v0, :cond_0            // 判断v0是否等于0, 不符合条件向下走, 符合条件执行cond_0分支

    .line 25
    const/4 v1, 0x1            // 符合条件分支

    .line 27
    :goto_0
    return v1

    :cond_0
    const/4 v1, 0x0            // cond_0分支

    goto :goto_0
.end method

###文字描述:如果符合if分支则程序往下走,最终return ; 而如果条件不符合则会走到 :cond_0分支 , 最终执行 goto :goto_0走回 :goto_0返回

for函数java代码:

private void forSense(){
    listStr = new ArrayList<String>(COUNT);
    for (int i = 0; i < COUNT; i++) {
        listStr.add("现在轮到我上场乐");
    }
}

 

for函数分析:

复制代码
.line 40
    const/4 v0, 0x0

    .local v0, i:I
    :goto_0
    if-lt v0, v3, :cond_0            //  if-lt判断数值v0小于v3 ,    如不符合往下走, 符合执行分支 :cond_0

    .line 43
    return-void

    .line 41
    :cond_0                // 标签
    iget-object v1, p0, Lcom/example/smalidemo/MainActivity;->listStr:Ljava/util/List;                // 引用对象

    const-string v2, "\u73b0\u5728\u8f6e\u5230\u6211\u4e0a\u573a\u4e50"

    invoke-interface {v1, v2}, Ljava/util/List;->add(Ljava/lang/Object;)Z        // List是接口, 所以执行接口方法add

    .line 40
    add-int/lit8 v0, v0, 0x1    // 将第二个v0寄存器中的值,加上0x1的值放入第一个寄存器中, 实现自增长

    goto :goto_0                // 回去:goto_0标签

###文字描述:设定一个标签goto_0, 判断v0小于v3, 符合执行分支:cond_0 ,然后又跑回:goto_0做继续判断

获取变量的时候,可能会用到的指令有:
iget、sget、iget-boolean、sget-boolean、iget-object、sget-object等,操作的指令有:iput、sput、iput-boolean、sput-boolean、iput-object、sput-object等。

没有“-object”后缀的表示操作的成员变量对象是基本数据类型,带“-object”表示操作的成员变量是对象类型,特别地,boolean类型则使用带“-boolean”的指令操作。
(1)、获取static fields的指令类似是:
[plain] view plain copy
 
  1. sget-object v0, Lcom/disney/WMW/WMWActivity;->PREFS_INSTALLATION_ID:Ljava/lang/String;  
      sget-object就是用来获取变量值并保存到紧接着的参数的寄存器中,在这里,把上面出现的PREFS_INSTALLATION_ID这个String成员变量获取并放到v0这个寄存器中,注意:前面需要该变量所属的类的类型,后面需要加一个冒号和该成员变量的类型,中间是“->”表示所属关系
 
      (2)、获取instance fields的指令与static fields的基本一样,只是由于不是static变量,不能仅仅指出该变量所在类的类型,还需要该变量所在类的实例。看例子:
[plain] view plain copy
 
  1. iget-object v0, p0, Lcom/disney/WMW/WMWActivity;->_view:Lcom/disney/common/WMWView;  
      可以看到iget-object指令比sget-object多了一个参数,就是该变量所在类的实例,在这里就是p0即“this”。
(3)、获取array的还有aget和aget-object,指令使用和上述类似,不细述。
 
      (4)、put指令的使用和get指令是统一的,直接看例子不解释:
[plain] view plain copy
 
  1. const/4 v3, 0x0  
  2. sput-object v3, Lcom/disney/WMW/WMWActivity;->globalIapHandler:Lcom/disney/config/GlobalPurchaseHandler;  
      相当于:this.globalIapHandler = null;(null = 0x0)
 
[plain] view plain copy
 
  1. .local v0, wait:Landroid/os/Message;  
  2. const/4 v1, 0x2  
  3. iput v1, v0, Landroid/os/Message;->what:I  
      相当于:wait.what = 0x2;(wait是Message的实例)


posted @ 2017-02-08 11:28  杨征  阅读(630)  评论(0编辑  收藏  举报