IF 指令
z 字母 : zero 简写,表示 0
eq 或 e:equal 简写,表示等于
n : 表示 不
g 或 gt : 表示 大于
l 或 lt: 表示 小于
命令 | 含义 |
---|---|
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_** |
示例:
.method private test(I)V
.registers 3 # 定义寄存器个数
.param p1, "x" # I
.prologue
.line 13
if-nez p1, :cond_4 # 如果参数不等于 0,就跳转至 cond_4。否则就执行下面的语句
.line 14
const/4 p1, 0x2
.line 20
:goto_3 # 定义语句 goto_3,在满足条件时可以跳到该语句中
return-void
.line 15
:cond_4
const/4 v0, 0x1
if-ne p1, v0, :cond_9
.line 16
const/4 p1, 0x3
goto :goto_3
.line 18
:cond_9
const/4 p1, 0x4
goto :goto_3
.end method
上述代码对应的 java 文件为:
private void test(int x){
if(x == 0){
x = 2;
}else if(x == 1){
x = 3;
}else{
x = 4;
}
}
while
while 循环其实可以使用 if 与 goto 表示:当满足 if 条件时,goto 到指定的语句执行。执行完毕后再判断一 if 条件。
这也是 smali 实现 while 循环的思路:
.method private test(I)V
.registers 3
.param p1, "x" # I
.prologue
.line 13
:goto_0
const/16 v0, 0xa
if-ge p1, v0, :cond_7
.line 14
add-int/lit8 p1, p1, 0x1
goto :goto_0
.line 16
:cond_7
return-void
.end method
其对应的 java 代码为:
private void test(int x){
while(x < 10){
x++;
}
}
从中可以看出,while 循环转换成一次次 if 判断以及 goto 语句。
每一次 if 判断成功后,会执行 while 代码块中的语句。执行完毕后,通过 goto 跳转到 if 判断。直到 if 判断失败,也就是整个循环执行完毕。
for
同 while 循环一样, for 循环也会被转换为 if 判断与 goto 语句。