Smali,是指安卓系统里的 Java 虚拟机(Dalvik)所使用的一种.dex 格式文件的汇编器。
Baksmali 则是反汇编器。
其语法是一种宽松式的 Jasmin/dedexer语法,而且它实现了.dex 格式所有功能(注解,调试信息,线路信息等)。
Smali,Baksmali 分别是冰岛语中编译器,反编译器的叫法。Davlik 字节码中,寄存器都是 32 位的,
所以64 位类型(Long/Double)需要用 2 个寄存器表示。
Dalvik 字节码有两种类型:原始类型和引用类型(包括对象和数组)V void 只能用于返回值类型
Z boolean
B byte
S short
C char
I int
J long(64 位)
F float
D double(64 位)
说明:只有boolean和long不同,因为他们和byte,int的首字符一样,所以换了一个字符表示。
使用L来表示对象。
Lpackage/name/ObjectName;
相当于 java 中的package.name.ObjectName;
其中:
L 表示这是一个对象类型
package/name 该对象所在的包
ObjectName 对象名
; 表示对象名称的结束
使用[ 来表示数组。
[I :表示一个整形的一维数组,相当于 java 的 int[];
对于多维数组,只要增加[ 就行了,[[I = int[][];
注:每一维最多 255 个;
例如:
[Ljava/lang/String 表示一个 String 的对象数组;
也就是Java代码中的字符串数组: java.lang.String[]
Lpackage/name/ObjectName;->methodName(III)Z
Lpackage/name/ObjectName 表示是哪个类
methodName 表示方法名
III 表示参数(这里表示为 3 个整型参数,因为整形是I)
Z 返回值,这里是boolean
说明:方法的参数是一个接一个的,中间没有隔开。
Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;
即表示: 包名(package.name),成员变量名(ObjectName)和各成员变量类型(java.lang.String)
有两种方式指定一个方法中有多少寄存器是可用的
.registers 指令指定了方法中寄存器的总数.locals 指令表明了方法中非参寄存器的总数,出现在方法中的第一行
例如:
.method private static a(Ljava/io/File;)V
.locals 3 //表明有3个非参数寄存器 v0,v1,v2
说明:对于静态方法除了没有隐含的 this 参数外,其他都一样。
可以这样理解 reg = local + para(详细解析见下段)
有两种方式——V命名方式和P命名方式。
P命名方式中的第一个寄存器就是方法中的第一个参数寄存器。
在下表中我们用这两种命名方式来表示上一个例子中有5个寄存器和3个参数的方法。
v0 第一个local register
v1 第二个local register
v2 p0 第一个parameter register
v3 p1 第二个parameter register
v4 p2 第三个parameter register
你可以用任何一种方式来引用参数寄存器——他们没有任何差别。
使用 P 命名是为了防止以后如果在方法中增加寄存器,需要对参数寄存器重新进行编号的缺点
特别说明一下:Long 和 Double 类型是 64 位的,需要 2 个寄存器
例如:对于非静态方法# static fields 定义静态变量的标记
# instance fields 定义实例变量的标记
# direct methods 定义静态方法的标记
# virtual methods 定义非静态方法的标记
概要:http://wenku.baidu.com/view/2ac1725e8e9951e79b8927df.html
寄存器P,V命名方式:http://blog.sina.com.cn/s/blog_65380c300101dn8f.html
smali 语法:http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html