Smail语法

数据类型:

原始类型:

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

引用类型:

对象: L + 包名.对象 + ;
      对象的表示则以L作为开头,格式是LpackageName/objectName;(注意必须有个分号跟在最后),例如String对象在smali中为:Ljava/lang/String;,其中java/lang对应java.lang包,String就是定义在该包中的一个对象。

数组:

[ + 数据类型
     数组的表示方式是:在基本类型前加上前中括号“[”,例如int数组和float数组分别表示为:[I、[F
      
     [I——表示一个整型一维数组,相当于java中的int[]。
  对于多维数组,只要增加[就行了。[[I相当于int[][],[[[I相当于int[][][]。注意每一维的最多255个。
  对象数组的表示:[Ljava/lang/String;表示一个String对象数组。

 

语法:

1.方法定义:
 表示形式: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[])
2.内部类:
 既然类是用LpackageName/objectName;来表示,那类里面的内部类又如何在smali中引用呢?答案是:LpackageName/objectName$subObjectName;。也就是在内部类前加“$”符号
3.字段:
 表示形式: Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;  即包名,字段名和各字段类型。

4.标记说明:
 # static fields             定义静态变量的标记
# instance fields        定义实例变量的标记
# direct methods       定义静态方法的标记
# virtual methods      定义非静态方法的标记
构造函数的返回类型为V,名字为<init>。
5.语法: If语句

 if-eq p1, v0, :cond_0表示如果p1和v0相等,则执行cond_0的流程:
  :cond_0
  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

寄存器:

概念:

在dalvik字节码中,寄存器都是32位的,能够支持任何类型。64位类型(Long和Double型)用2个寄存器表示。
有两种方式指定一个方法中有多少寄存器是可用的。

  .registers指令指定了方法中寄存器的总数。
  .locals指令表明了方法中非参寄存器的数量。

v0 第一个本地寄存器 
v1 第二个本地寄存器 
v2 p0 (this) 
v3 p1 第一个参数 
v4 p2 第二个参数 
v5 p3 第三个参数 

Long/Double值
Long和double类型是64位的,需要2个寄存器

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


p0	this
p1	I
p2,p3	J
p4	Z

smail操作:

.field private isFlag:z  定义变量

.method  方法

.parameter  方法参数

.prologue  方法开始

.line 12  此方法位于第12行

invoke-super  调用父函数

const/high16  v0, 0x7fo3  把0x7fo3赋值给v0

invoke-direct  调用函数

return-void  函数返回void

.end method  函数结束

new-instance  创建实例

iput-object  对象赋值

iget-object  调用对象

invoke-static  调用静态函数

 

smali中的函数调用也分为direct和virtual两种类型,direct method就是private函数,public和protected函数都属于virtual method。在调用函数时,有invoke-direct,invoke-virtual,invoke-static、invoke-super以及invoke-interface等几种不同的指令。还有invoke-XXX/range 指令的,这是参数多于4个的时候调用的指令,比较少见。

invoke-static:就是调用static函数的,示例:

invoke-static {}, Lcom/disney/Class1;->fun()Z

上句invoke-static后面有一对大括号“{}”,内部是调用该方法的实例和参数列表,由于这是static方法也不需要参数,所以{}内为空。

invoke-super:调用父类方法,在onCreate、onDestroy等方法都能看到。
invoke-direct:调用private函数,示例:

invoke-direct {p0}, Lcom/disney/Class1;->getGlobalIapHandler()Lcom/disney/config/GlobalPurchaseHandler;

上句即this->getGlobalIapHandler(),函数GlobalPurchaseHandler getGlobalIapHandler()是定义在Class1中的一个private函数。

invoke-virtual:用于调用protected或public函数,示例:

sget-object v0, Lcom/disney/Class1;->shareHandler:Landroid/os/Handler;
invoke-virtual {v0, v3}, Landroid/os/Handler;->removeCallbacksAndMessages(Ljava/lang/Object;)V

上句v0是shareHandler android/os/Handler,v3是传递给removeCallbackAndMessage方法的Ljava/lang/Object参数。

 

1.If语句 
 
   if-nez v0,:cond_0    如果结果不为0,就跳转到cond_0标号处

    if-eqz v0,:cond_1    如果结果为0,就跳转到cond_1标号处

    

2.数据操作指令

    move v0,v1    将v1的值赋给v0 ,两个寄存器都为4位

    move-result v0    将上一个invoke类型指令操作的单字非对象结果赋给v0

    move-result-object v0    将上一个invoke类型指令操作的对象结果(返回值)赋给v0

3.返回指令

    return-void

    return v0

    return-object v0

4.实例操作指令

    check-cast v1, Landroid/widget/TextView;  将v1寄存器中的对象引用转化成指定的类型(这里是 TextView)

    new-instance v1, Ljava/lang/StringBuilder; 构造一个指定类型对象的新实例  

5.数组操作指令

    new-array v0,v0,[I  构造Int类型,大小是v0的数组,并将值赋给v0寄存器

    array-length v1,v0  获取v0数组的长度且将值赋给v1

    

6.异常指令

    throw vAA 抛出vAA寄存器中指定类型的异常

    

7.跳转指令

    1,goto :goto_0  偏移量goto_0不能为0 

    2,If语句

    3,switch    

        packed-switch v0, :pswitch_data_0  v0是switch需要判断的值     :pswitch_data_0 偏移表,表中值是有规律递增的。

        sparse-switch v0, :pswitch_data_0  偏移表中值是无规律的。

8.比较指令

    cmpl-float v0,v2,v3     比较v2和v3,如果v2>v3,v0=-1;反之,v0=1;相等,v0=0

    cmpg-float v0,v2,v3  比较v2和v3,如果v2>v3,v0=1;反之,v0=-1;相等,v0=0

    cmpl-double v0,v2,v3  同理

    cmpg-double v0,v2,v3  同理

    cmp-long v0,v2,v3    比较v2和v3,如果v2>v3,v0=1;反之,v0=-1;相等,v0=0
 

转载于:https://my.oschina.net/phybrain/blog/1575840

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值