Smail语法基本知识(一)

Smali 背景:

 Smali,是指安卓系统里的 Java 虚拟机(Dalvik)所使用的一种.dex 格式文件的汇编器。

 Baksmali 则是反汇编器。

 其语法是一种宽松式的 Jasmin/dedexer语法,而且它实现了.dex 格式所有功能(注解,调试信息,线路信息等)。

 Smali,Baksmali 分别是冰岛语中编译器,反编译器的叫法。


Smali 语法简单介绍如下:

类型

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


方法的传参

当一个方法被调用的时候,方法的参数被置于最后 N 个寄存器中;
例如,一个方法有 2 个参数,5 个寄存器(v0~v4)
那么,参数将置于最后 2 个寄存器(v3 和 v4)
非静态方法中的第一个参数总是调用该方法的对象;

说明:对于静态方法除了没有隐含的 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 个寄存器

例如:对于非静态方法
LMyObject——>myMethod(IJZ)V;
有 4 个参数:LMyObject,int,long,bool; 需要 5 个寄存器来存储参数;
P0 this
P1 I (int)
P2,P3 J (long)
P4 Z(bool)

标记

  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

你可能感兴趣的:(Android)