dalvik smali 语法

dalvik字节码有两种类型,原始类型和引用类型。对象和数组是引用类型,其它都是原始类型。

V void,只能用于返回值类型
Z boolean
B byte
S short
C char
I int
J long(64位)
F float
D double(64位)


1.对象 
  对象以Lpackage/name/ObjectName;的形式表示。

  前面的L表示这是一个对象类型,package/name/是该对象所在的包,ObjectName是对象的名字,“;”表示对   象名称的结束。相当于java中的package.name.ObjectName。例如:Ljava/lang/String;相java.lang.String


2.数组

  数组的表示形式 
 [I——表示一个整型一维数组,相当于java中的int[]。
 对于多维数组,只要增加[就行了。[[I相当于int[][],[[[I相当于int[][][]。注意每一维的最多255个。

  对象数组的表示:[Ljava/lang/String;表示一个String对象数组。


3.方法
  表示形式:Lpackage/name/ObjectName;->MethodName(III)Z
 Lpackage/name/ObjectName;表示类型,MethodName是方法名。III为参数(在此是3个整型参数),Z是返回   类型(bool型)。
 方法的参数是一个接一个的,中间没有隔开。
  一个更复杂的例子:
  method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
  在java中则为:String method(int, int[][], int, String, Object[])\


4.字段

  表示形式:Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;
  即包名,字段名和各字段类型。


5.寄存器
 在dalvik字节码中,寄存器都是32位的,能够支持任何类型。64位类型(Long和Double型)用2个寄存器表   示。
 有两种方式指定一个方法中有多少寄存器是可用的。.registers指令指定了方法中寄存器的总数。.locals指  令表明了方法中非参寄存器的数量。
  

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


 例如,非静态方法LMyObject;->callMe(II)V有2个整型参数,另外还有一个隐含的LMyObject;参数,所以总共  有3个参数。假如在该方法中指定了5个寄存器(v0-v4),以.registers方式指定5个或以.locals方式指定2个  (即2个local寄存器+3个参数寄存器)。当该方法被调用的时候,调用该方法的对象(即this引用)存放在v2  中,第一个整型参数存放在v3中,第二个整型参数存放在v4中。
 对于静态方法除了没有隐含的this参数外其它都一样。

6.寄存器的命名方式

 有两种方式——V命名方式和P命名方式。P命名方式中的第一个寄存器就是方法中的第一个参数寄存器。在下  表中我们用这两种命名方式来表示上一个例子中有5个寄存器和3个参数的方法。
 v0 第一个local register
 v1 第二个local register
 v2 p0 第一个parameter register
 v3 p1 第二个parameter register
 v4 p2 第三个parameter register
 你可以用任何一种方式来引用参数寄存器——他们没有任何差别。
 注意:baksmali默认对参数寄存器使用P命名方式。如果想使用V命名方式,可以使用-pl—no-parameter-    registers选项。
 使用P命名方式是为了防止以后如果要在方法中增加寄存器,需要对参数寄存器重新进行编号的缺点。
 Long/Double值
 Long和double类型是64位的,需要2个寄存器(切记切记)。

 例如,对于非静态方法LMyObject;->MyMethod(IJZ)V,参数分别是LMyObject;,int,long,bool。故该方法  需要5个寄存器来存储参数。
 p0 this
 p1 I
 p2,p3 J

 p4 Z


other:

 # static fields             定义静态变量的标记

 # instance fields        定义实例变量的标记

 # direct methods       定义静态方法的标记

 # virtual methods      定义非静态方法的标记

 构造函数的返回类型为V,名字为<init>。

 if-eq p1, v0, :cond_8 表示如果p1和v0相等,则执行cond_8的流程:

 :cond_8

 invoke-direct {p0}, Lcom/paul/test/a;->d()V

 调用com.paul.test.a的d()方法

 if-ne p1, v0, :cond_b 表示不相等则执行cond_b的流程:

 :cond_b

 const/4 v0, 0x0

 invoke-virtual {p0, v0}, Lcom/paul/test/a;->setPressed(Z)V

 invoke-super {p0, p1, p2}, Landroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z

 move-result v0

  大概意思就是调用com.paul.test.a的setPressed方法,然后再调用父类View的onKeyUp方法,最后 return v0

 举两个例子:

 01.

 sget-object v5, Lcom/google/youngandroid/runtime;->Lit227:Lgnu/mapping/SimpleSymbol;

 获取com.google.youngandroid.runtime中的Lit227字段存入v5寄存器,相当于

 gnu.mapping.SimpleSymbol localVariable = com.google.youngandroid.runtime.Lit227;

 02.

 sput-object v0, Lcom/google/youngandroid/runtime;->Lit78:Lkawa/lang/SyntaxTemplate;

 Likewise, this is setting the value of a static field. i.e.

 设置com.google.youngandroid.runtime.Lit78的值为v0寄存器中的kawa.lang.SyntaxTemplate类型变量的   值。相当于com.google.youngandroid.runtime.Lit78 = kawa.lang.SyntaxTemplate localVariable;

 03.

 const /4 vx, lit4 //表示存入4位常量到vx寄存器

 input-object vx, vy, 字段ID //根据 字段ID将vx寄存器的值存入实例的对象引用字段,vy寄存器中是  该实例的引用。

 那么什么叫对象的引用呢?

 class A{//类体内容

 }

 A a1

 它代表A是类,a1是引用,a1不是对象,a1所指向的对象为空null;

 这样就好理解下面的例子:

  const/4 v0, 0x0

  iput-object v0, p0, Lcom/example/button/MainActivity;->btn1:Landroid/widget/Button;

  

 p0 --this (Button)

 相当于android.widget.Button btn1 = v0;//v0 = null

  Button 为对象,btn1为对象Button 的引用


你可能感兴趣的:(dalvik smali 语法)