J-long Z-boolean B-byte C-charD-double F-float I-int S-short V-void [Lxxx/nnn-array
如 int和float 1维数组表示为:[I、[F;对象的表示格式是LpackageName/objectName;(注意分号),如String:Ljava/lang/String;,数组每一个维度最多255个,内部类的引用是:LpackageName/objectName$subObjectName;
方法:参数间无分隔符: f()V - void f() f (III)Z -boolean f(int, int, int) f(Z[ILjava/lang/String;J)Ljava/lang/String; - String f(boolean, int[], String, long)
"if-eq vA, vB, :cond_**" vA等于vB则goto_**
"if-ne vA, vB, :cond_**" 不等于
"if-lt vA, vB, :cond_**" 小于
"if-ge vA, vB, :cond_**" 大于等于
"if-gt vA, vB, :cond_**" 大于
"if-le vA, vB, :cond_**" 小于等于
"if-eqz vA, :cond_**" 等于0
"if-nez vA, :cond_**" 不等于0
"if-ltz vA, :cond_**" 小于0
"if-gez vA, :cond_**" 大于等于0
"if-gtz vA, :cond_**" 大于0
"if-lez vA, :cond_**" 小于等于0
if:
private boolean e(){
boolean temp = ()? true : false;
if (temp ) {
return true;
}else{
return false;
}
}
.method private e()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
.line 25
const/4 v1, 0x1
.line 27
:goto_0
return v1
:cond_0
const/4 v1, 0x0
goto :goto_0
.end method
for:
private void for(){
listStr = new ArrayList<String>(COUNT);
for (int i = 0; i < COUNT; i++) {
listStr.add("l");
}
}
.line 40
const/4 v0, 0x0
.local v0, i:I
:goto_0
if-lt v0, v3, :cond_0 // if-lt判断数值v0小于v3
.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
.line 40
add-int/lit8 v0, v0, 0x1 //将第二个v0寄存器中的值,加上0x1的值放入第一个寄存器中
goto :goto_0
本地寄存器(无限制):如v0、v1、v2,参数寄存器:如p0、p1、p2 注p0不一定是第一个参数,在非static方法中,p0指“this”,p1表示方法的第一个参数,p2代表方法中的第二个…在static方法中p0才对应第一个参数(因为Java的static方法中没this方法)
const/4 v0, 0x0 //把值0x0(false)存到v0中
iput-boolean v0, p0, Lcom/d/W/WA;->is:Z //iput-boolean指令把v0中的值存到com.d.W.WA.is成员变量中,p0为this
调用变量的指令:iget、sget、iget-boolean、sget-boolean、iget-object、sget-object等,赋值:iput、sput、iput-boolean、sput-boolean、iput-object、sput-object等
1)static fields:sget-object v0, Lcom/d/W/WA;->ID:Ljava/lang/String; //获取变量值并保存到紧接着的参数的寄存器中
2)获取instance fields:由于不是static变量,不仅指出该变量所在类的类型,还需该变量所在类的实例:
iget-object v0, p0, Lcom/d/W/WA;->veiw:Lcom/d/co/WV; //比sget-object多了该变量所在类的实例参数p0即“this”
put和get指令相对:
const/4 v3, 0x0
sput-object v3, Lcom/d/W/WA;->handler:Lcom/d/con/Handler;
this.handler = null;(null = 0x0)
.local v0, wait:Landroid/os/Message; //wait是Message的实例
const/4 v1, 0x2
iput v1, v0, Landroid/os/Message;->what:I
wait.what = 0x2;
direct method是private方法,其余为virtual。
const-string v0, "fx"
invoke-static
{v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V //v0就是"fx",“{}”,调用该方法的实例+参数们,这方法既不需参数也是static的,static方法比起其他调用少调用者参数
const/4 v2, 0x0
invoke-virtual {p0, v2}, Lcom/disney/WMW/WMWActivity;->getPreferences(I)Landroid/content/SharedPreferences;
invoke-static/range{v0 .. v5}, Lcn/game189/sms/SMS;->checkFee(Ljava/lang/String;Landroid/app/Activity;Lcn/game189/sms/SMSListener;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z //6个参数多于4个时invoke-XXX/range
move-result-object v1 // v1保存的就是调用getPreferences(int)方法返回的SharedPreferences实例。move-result(返回基本数据类型)和move-result-object(返回对象), smali调用与获取返回值分开 有别于javainvoke-virtual {v2}, Ljava/lang/String;->length()I
move-result v2 //v2保存的则是调用String.length()返回的整型。
#annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Lcom/d/W/WA$MessageHandler;,
Lcom/d/W/WA$FinishActivityArgs;
}
.end annotation//表示有俩成员内部类
# static fields # instance fields //成员变量
# direct methods
.method static synthetic ac$200(Lcom/d/W/WA;)Lcom/d/co/WV; //
.locals 3 // 在这个方法中最少要用到的本地寄存器的个数,在方法的第一行。.registers指定方法中寄存器总个数
.parameter "x0" // move p0, v3 把v3寄存器的值移动到寄存器p0上. const v0, 把值0x1赋值到寄存器v0上 .parameter .parameter //表示有两个参数
.prologue //方法开始
.line 30 //非必需
.invoke-direct {p0}, Lcom/d/W/WA;->initIap()V //
iget-object v0, p0, Lcom/d/W/WA;->_view:Lcom/d/co/WV;
return-object v0
.end method
常见错误:.local 的值不对,invoke-virtual或invoke-static将在回编译后程序运行时引发一个常见的VerifyError