Smali文件结构解
  Smali文件与java中的类是一一对应的,包括内部类和匿名内部类也会生成对应的smali文件(典型的比如实现某个接口的匿名内部类),所以你会看到.smali文件比.java文件更多。
smali文件是由Dalvik指令组成的,它有自己的一套规则,它的指令都是以“.”开头,常用的指令如下:
 
  指令
  说明
 
  .class
  包名+类名
  .super
  父类类名
  .source
  源文件名称
  .implements
  接口实现
  .field
  定义字段
  .method/.end method
  方法的开始与结束
  .locals
  方法内使用的v开口的寄存器个数
  .prologue
  表示方法中代码的开始处
  .line
  对应java中的行数
  .param
  指定了方法的参数
  .paramter
  和.paramter含义相同
  .param
  指定了方法的参数
  .annotation/.end annotation
  注解的开始和结束
 
 
现在来看下smali文件的结构:
1.头文件
格式如下:
 
.class <访问权限修饰符> [非权限修饰符] <类名>
.super <父类名>
.source <源文件名称>
1234
访问权限修饰符即所谓的public,protected,private,而非权限修饰符则指的是final,abstract,static,两者都可以为空。
举例如下:
 
.class public final Llutey/FTPServer/preferences/PreferencesFactory;
.super Ljava/lang/Object;
.source "PreferencesFactory.java"
1234
如果原java代码有经过混淆,那一般.class里面的类名和.source的源文件名会不一样,以下是经过混淆的(类名正常是xxx/PreferencesFactory,混淆以后变成xxx/d):
 
.class public final Llutey/FTPServer/preferences/d;
.super Ljava/lang/Object;
.source "PreferencesFactor123
 
2.接口实现
格式如下:
 
#interfaces
.implements <接口名称>12
举例如下:
 
# interfaces
.implements Landroid/view/View$OnClickListener;12
其中# interfaces为注释
 
3.注解
如果一个类中使用了注解,就会出现.annotation,格式如下:
 
#annotations
.annotation [注解的属性] <注解类名>
    [注解字段=值]
    ...
.end annotation12345
举例如下:
 
# annotations
.annotation build Landroid/annotation/TargetApi;
    value = 0xb
.end annotation1234
其中# annotations为注释
 
4.变量定义
使用.field描述字段的定义,分为静态变量和普通变量两种:
 
静态变量
格式如下:
 
#static fields
.field <访问权限> static [修饰词] <字段名>:<变量类型>12
使用# static fields注释,并加了static修饰符,
举例说明:
smali:
 
# static fields
.field public static mStr:Ljava/lang/String;12
java:
 
public static final String mStr;1
 
普通变量
格式如下:
 
#instance fields
.field <访问权限修饰符> [非权限修饰符] <变量名>:<变量类型>12
使用# instance fields注释,
举例说明:
smali:
 
.field private bool:Z1
java:
 
private boolean bool;1
 
5.方法描述
  smali中的方法以.method/.end method进行描述,有分两种方法,一种是直接方法,一种是虚方法,
什么事直接方法和虚方法呢?直接方法就是不能被覆写的方法,包括用static,private修饰的方法,虚方法表示可以被覆写的方法,包括public,protected修饰的方法。
两者在smali中的注释分别是直接方法(#direct methods),虚方法(#virtual methods),一般直接方法在smali文件的前半部分,虚方法在后半部分。
方法的格式如下:
 
#direct methods/#virtual methods
.method <访问权限修饰符> [非访问权限修饰符] <方法原型>
      <.locals>
      [.parameter]
      [.prologue]
      [.line]
      <代码逻辑>
.end12345678
其中.parameter,.prologue,.line是可选的。
举例说明:
 
# virtual methods
.method public final onClick(Landroid/view/View;)V
    .locals 1
    .prologue
    .line 71
    iget-object v0, p0, Llutey/FTPServer/preferences/sdk11/pre/a;->a:Llutey/FTPServer/preferences/sdk11/pre/FTPServerPreferences;
    invoke-static {v0}, Llutey/FTPServer/preferences/sdk11/pre/FTPServerPreferences;->a(Llutey/FTPServer/preferences/sdk11/pre/FTPServerPreferences;)V
    .line 72
    return-void
.end method12345678910111213
注意几个特殊的方法:
 
.method xxx constructor <clinit>()V  //类中final变量的初始化
.method xxx constructor <init>()V   //类中的构造行数
.method static synthetic methodName(xxxx)V //加synthetic修饰符的方法,synthetic是合成的意思,即这个方法在原java代码里面是没有的,是在java编译成Dalvik字节码的时候合成的,后续会详细分析这类方法123
方法中具体的语法在文章的后半部分详细为您说明。
 
 
smali数据类型
  Dalvik字节码和Java一样,都只有两种数据类型:基本类型和引用类型,8中基本数据类型,对象和数组是引用类型,Dalvik字节码和Jvm中对数据类型的描述是一致的,
对于基本类型和无返回类型用一个大写字母表示,对象类型用一个大写字母L加对象的全限定名表示,如Ljava/lang/String表示字符串对象类型,
一维数组用一个“[”加数据类型或对象类型表示.
java数据类型和Dalvik字节码的数据类型一一对应,对应关系如下表:
 
  java类型
  smali描述符
 
  boolean
  Z
  byte
  B
  short
  S
  char
  C
  int
  I
  long
  L
  float
  F
  double
  D
  void
  V
  对象类型
  L
  数组类型
  [
 
 
基本数据类型
  Z,B,S,C,I,L,F,D为基本数据类型,从上表可以看出,Dalvik字节码基本类型的描述符基本上是java基本类型的首字母,除了boolean对应为Z外
 
对象类型
  L加上类或者接口的全称表示对象类型,即Lpackage/objectName,如String类型描述符为Ljava/lang/String,包com.biyou下面的test类的类型描述符为Lcom/biyou/test
 
数组类型
  基本类型的数组为”[“加上基本类型描述符来表示,一维数组前面是一个”[“,多一个维度前面多加一个”[“,比如int类型,一维是:[I,二维是:[[I,依次类推。
对象类型的数组为”[“加上对象类型表示符来表示,如String类型表示为:[Ljava/lang/String。
 
smali语法
  smali的语法跟汇编语言有点类似,但没有汇编那么复杂,可以很轻松的看懂,推荐使用source insight来看。
 
变量的描述
格式为:
 
对象类型描述符->变量名:类型描述符;1
举例说明:
 
Lcom/biyou/test;->count:I  //基本类型
Lcom/biyou/test;->str:Ljava/lang/String  //对象类型12
Dalvik对变量的描述都会指明变量定义的和变量的类型,如例子中的count变量的描述,说明它定义在com.biyou.test类,是int类型的变量
 
方法的描述
格式为:
 
对象类型描述符->方法名(参数类型描述符)返回值类型描述符;1
下面我们通过几个例子来说明,以java.lang.String为例:
 
java方法:public char charAt(int index){...}
Davilk描述:Ljava/lang/String;->charAt(I)C
java方法:public void getChars(int srcBegin,int srcEnd,char dst[],int dstBegin){...}
Davilk描述:Ljava/lang/String;->getChars(II[CI)V
java方法:public boolean equals(Object anObject){...}
Davilk描述:Ljava/lang/String;->equals(Ljava/lang/Object)Z12345678
 
Dalvik指令集
 掌握以上的字段和方法的描述,只能说我们懂了如何描述一个字段和方法,而关于方法中具体的逻辑则需要了解Dalvik中的指令集.因为Dalvik是基于寄存器的架构的,因此指令集和JVM中的指令集区别较大,反而更类似x86的中的汇编指令。
 
1.空操作指令
  空操作指令的助记符为nop,它的值为00,通常nop指令被用来作对齐代码之用,无实际操作。
2.数据定义指令
  数据定义指令用于定义代码中使用的常量,字符串,类等数据,基础字节码是const
 
  指令
  描述
 
  const/4 vA,#+B
  将数值符号扩展为32后赋值给寄存器vA
  const/16 vAA, #+BBBB
  将数据符号扩展为32位后赋给寄存器vAA
  const vAA, #+BBBBBBBB
  将数值赋给寄存器vAA
  const/high16 vAA, #+BBBB0000
  将数值右边零扩展为32位后赋给寄存器vAA
  const-wide/16 vAA,#+BBBB
  将数值符号扩展为64位后赋值个寄存器对vAA
  const-wide/32 vAA,#+BBBB
  将数值符号扩展为64位后赋值个寄存器对vAA
  const-wide vAA, #+BBBBBBBBBBBBBBBB
  将数值赋给寄存器对vAA
  const-wide/high16 vAA, #+BBBB000000000000
  将数值右边零扩展为64位后赋给寄存器对vAA
  const-string vAA,string@BBBB
  通过字符串索引高走字符串赋值给寄存器vAA
  const-string/jumbo vAA, string@BBBBBBBB
  通过字符串索引(较大)构造一个字符串并赋给寄存器vAA
  const-class vAA,type@BBBB
  通过类型索引获取一个类的引用赋值给寄存器vAA
  const-class/jumbo vAAAA, type@BBBBBBBB
  通过给定的类型索引获取一个类引用并赋给寄存器vAAAA。这条指令占用两个字节,值为0xooff(Android4.0中新增的指令)
 
3.锁指令
  锁指令多用在多线程程序中对同一对象的操作。Dalvik指令集中有两条锁指令:
monitor-enter vAA:为指定的对象获取锁。
monitor-exit vAA:释放指定的对象的锁。12
如java的com.biyou.test类需要需要加锁:
java为:
 
    synchronized (test.class)
    {
      ...
    }1234
smali为:
 
     const-class v0, Lcom/biyou/test;
     monitor-enter v0
     ...
     monitor-exit v01234
 
4.变量操作指令
  字段操作指令表示对对象字段进行设值和取值操作,就像是你在代码中长些的set和get方法.基本指令是iput-type,iget-type,sput-type,sget-type.type表示数据类型.
普通字段读写操作
前缀是i的iput-type和iget-type指令用于字段的读写操作.
 
  指令
  描述
 
  iget-object vAA,vBB,filed_id
  读取vAA寄存器中的对象中的filed_id对象的引用值给vBB寄存器
  iget-boolean vAA,vBB,filed_id
  读取vAA寄存器中的对象中的filed_id的值给vBB寄存器
  iget-wide vAA,vBB,filed_id
  读取vAA寄存器中的对象中的filed_id的值给vBB寄存器
  iget vAA,vBB,filed_id
  读取vAA寄存器中的对象中的filed_id的值给vBB寄存器
  iput-object vAA,vBB,filed_id
  把vAA寄存器指向的对象的引用赋值给vBB寄存器中的filed_id对象
  iput-boolean vAA,vBB,filed_id
  把vAA寄存器的值给vBB寄存器中的boolean类型
  iput-wide vAA,vBB,filed_id
  把vAA寄存器的值给vBB寄存器中的wide类型
  iput vAA,vBB,filed_id
  把vAA寄存器的值给vBB寄存器中的int类型
 
 
静态字段读写操作
前缀是s的sput-type和sget-type指令用于静态字段的读写操作
 
  指令
  描述
 
  sget-object vAA,vBB,filed_id
  读取vAA寄存器中的对象中的filed_id对象的引用值给vBB寄存器
  sget-boolean vAA,vBB,filed_id
  读取vAA寄存器中的对象中的filed_id的值给vBB寄存器
  sget-wide vAA,vBB,filed_id
  读取vAA寄存器中的对象中的filed_id的值给vBB寄存器
  sget vAA,vBB,filed_id
  读取vAA寄存器中的对象中的filed_id的值给vBB寄存器
  sput-object vAA,vBB,filed_id
  把vAA寄存器指向的对象的引用赋值给vBB寄存器中的filed_id对象
  sput-boolean vAA,vBB,filed_id
  把vAA寄存器的值给vBB寄存器中的boolean类型
  sput-wide vAA,vBB,filed_id
  把vAA寄存器的值给vBB寄存器中的wide类型
  sput vAA,vBB,filed_id
  把vAA寄存器的值给vBB寄存器中的int类型
 
 
5.跳转指令
  跳转指令用于从当前地址跳转到指定的偏移处。Dalvik指令集中有三种跳转指令:无条件跳转(goto),分支跳转(switch)与条件跳转(if)。
goto +AA:无条件跳转到指定偏移处,偏移量AA不能为0。
goto/16 +AAAA:无条件跳转到指定偏移处,偏量AAAA不能为0。
goto/32 +AAAAAAAA:无条件跳转到指定偏移处。
packed-switch vAA, +BBBBBBBB:分支跳转指令。vAA寄存器为switch分支中需要判断的值,BBBBBBBB指向一个packed-switch-payload格式的偏移表,表中的值是有规律递增的。
sparse-switch vAA, +BBBBBBBB:分支跳转指令。vAA寄存器为switch分支中需要判断的值,BBBBBBBB指向一个sparse-switch-payload格式的偏移表,表中的值是无规律的偏移量。
if-test vA, vB, +CCCC:条件跳转指令。比较vA寄存器与vB寄存器的值,如果比较结果满足就跳转到CCCC指定的偏移处。偏移量CCCC不能为0。if-test类型的指令有以下几条:
if-eq:如果vA等于vB则跳转。Java语法表示为“if(vA == vB)”
if-ne:如果vA不等于vB则跳转。Java语法表示为“if(vA != vB)”
if-lt:如果vA小于vB则跳转。Java语法表示为“if(vA < vB)”
if-ge:如果vA大于等于vB则跳转。Java语法表示为“if(vA >= vB)”
if-gt:如果vA大于vB则跳转。Java语法表示为“if(vA > vB)”
if-le:如果vA小于等于vB则跳转。Java语法表示为“if(vA <= vB)”
if-testz vAA, +BBBB:条件跳转指令。拿vAA寄存器与0比较,如果比较结果满足或值为0时就跳转到BBBB指定的偏移处。偏移量BBBB不能为0。if-testz类型的指令有以下几条:
if-eqz:如果vAA为0则跳转。Java语法表示为“if(vAA == 0)”
if-nez:如果vAA不为0则跳转。Java语法表示为“if(vAA != 0)”
if-ltz:如果vAA小于0则跳转。Java语法表示为“if(vAA < 0)”
if-gez:如果vAA大于等于0则跳转。Java语法表示为“if(vAA >= 0)”
if-gtz:如果vAA大于0则跳转。Java语法表示为“if(vAA > 0)”
if-lez:如果vAA小于等于0则跳转。Java语法表示为“if(vAA <= 0)”
6.比较指令
比较指令用于对两个寄存器的值(浮点型或长整型)进行比较。它的格式为“cmpkind vAA, vBB, vCC”,其中vBB寄存器与vCC寄存器是需要比较的两个寄存器或寄存器对,比较的结果放到vAA寄存器。Dalvik指令集中共有5条比较指令:
cmpl-float vAA,vBB,vCC:比较两个单精度浮点数。如果vBB寄存器大于vCC寄存器,结果为-1,相等则结果为0,小于的话结果为1
cmpg-float vAA,vBB,vCC:比较两个单精度浮点数。如果vBB寄存器大于vCC寄存器,则结果为1,相等则结果为0,小于的话结果为-1
cmpl-double vAA,vBB,vCC:比较两个双精度浮点数。如果vBB寄存器对大于vCC寄存器对,则结果为-1,相等则结果为0,小于则结果为1
cmpg-double vAA,vBB,vCC:比较两个双精度浮点数。如果vBB寄存器对大于vCC寄存器对,则结果为1,相等则结果为0,小于的话,则结果为-1
cmp-long vAA,vBB,vCC:比较两个长整型数。如果vBB寄存器大于vCC寄存器,则结果为1,相等则结果为0,小则结果为-1
7.数据转换指令
数据转换指令用于将一种类型的数值转换成另一种类型。它的格式为“unop vA, vB”,vB寄存器或vB寄存器对存放需要转换的数据,转换后的结果保存在vA寄存器或vA寄存器对中。
•“neg-int”:对整型数求补。
•“not-int”:对整型数求反。
•“neg-long”:对长整型数求补。
•“not-long”:对长整型数求反。
•“neg-float”:对单精度浮点型数求补。
•“neg-double”:对双精度浮点型数求补。
•“int-to-long”:将整型数转换为长整型。
•“int-to-float”:将整型数转换为单精度浮点型数。
•“int-to-dobule”:将整型数转换为双精度浮点数。
•“long-to-int”:将长整型数转换为整型。
•“long-to-float”:将长整型数转换为单精度浮点型。
•“long-to-double”:将长整型数转换为双精度浮点型。
•“float-to-int”:将单精度浮点数转换为整型。
•“float-to-long”:将单精度浮点数转换为长整型数。
•“float-to-double”:将单精度浮点数转换为双精度浮点型数。
•“double-to-int”:将双精度浮点数转换为整型。
•“double-to-long”:将双精度浮点数转换为长整型。
•“double-to-float”:将双精度浮点数转换为单精度浮点型。
•“int-to-byte”:将整型转换为字节型。
•“int-to-char”:将整型转换为字符型。
•“int-to-short”:将整型转换为短整型。
8.数据运行指令
  数据运算指令包括算术运算指令与逻辑运算指令。算术运算指令主要进行数值间如加,减,乘,除,模,移位等运算。逻辑运算指令主要进行数值间与,或,非,抑或等运算。数据运算指令有如下四类(数据运算时可能是在寄存器或寄存器对间进行,下面的指令作用讲解时使用寄存器来描述):
•“binop vAA, vBB, vCC”:将vBB寄存器与vCC寄存器进行运算,结果保存到vAA寄存器。
•“binop/2addr vA, vB”:将vA寄存器与vB寄存器进行运算,结果保存到vA寄存器。
•“binop/lit16 vA, vB, #+CCCC”:将vB寄存器与常量 CCCC进行运算,结果保存到vA寄存器。
•“binop/lit8 vAA, vBB, #+CC”:将vBB寄存器与常量CC进行运算,结果保存到vAA寄存器。
后面3类指令比第1类指令分别多出了2addr,lit16,lit8等指令后缀。四类指令中基础字节码相同的指令执行的运算操作是类似的,第1类指令中,根据数据的类型不同会在基础字节码后面加上数据类型后缀,如 -int 或 -long 分别表示操作的数据类型为整型与长整型。第1类指令可归类如下:
•“add-type”:vBB寄存器与vCC寄存器值进行加法运算(vBB + vCC)
•”sub-type”:vBB寄存器与vCC寄存器值进行减法运算(vBB - vCC)
•”mul-type”:vBB寄存器与vCC寄存器值进行乘法运算(vBB * vCC)
•”div-type”:vBB寄存器与vCC寄存器值进行除法运算(vBB / vCC)
•”rem-type”:vBB寄存器与vCC寄存器值进行模运算(vBB % vCC)
•”and-type”:vBB寄存器与vCC寄存器值进行与运算(vBB & vCC)
•”or-type”:vBB寄存器与vCC寄存器值进行或运算(vBB | vCC)
•”xor-type”:vBB寄存器与vCC寄存器值进行异或运算(vBB ^ vCC)
•”shl-type”:vBB寄存器值(有符号数)左移vCC位(vBB << vCC )
•”shr-type”:vBB寄存器值(有符号)右移vCC位(vBB >> vCC)
•”ushr-type”:vBB寄存器值(无符号数)右移vCC位(vBB >>> vCC)
其中基础字节码后面的-type可以是-int,-long, -float,-double。后面3类指令与之类似。
9.方法调用指令
  方法调用指令负责调用类实例的方法。它的基础指令为 invoke,方法调用指令有“invoke-kind {vC, vD, vE, vF, vG},meth@BBBB”与“invoke-kind/range {vCCCC  .. vNNNN},meth@BBBB”两类,两类指令在作用上并无不同,只是后者在设置参数寄存器时使用了range来指定寄存器的范围。根据方法类型的不同,共有如下五条方法调用指令:
•invoke-virtual或 invoke-virtual/range调用实例的虚方法。
•invoke-super或”invoke-super/range调用实例的父类方法。
•invoke-direct或“invoke-direct/range调用实例的直接方法。
•invoke-static或invoke-static/range调用实例的静态方法。
•invoke-interface或invoke-interface/range调用实例的接口方法。
在Android4.0系统中,Dalvik指令集中增加了“invoke-kind/jumbo {vCCCC  .. vNNNN},meth@BBBBBBBB”这类指令,它与上面介绍的两类指令作用相同,只是在指令中增加了jumbo字节码后缀,且寄存器值与指令的索引取值范围更大。
方法调用指令的返回值必须使用move-result*指令来获取。如下面两条指令:
invoke-static {}, Landroid/os/Parcel;->obtain() Landroid/os/Parcel;
move-result-object v012
 
10.异常处理指令
  Dalvik指令集中有一条指令用来抛出异常。
•throw vAA:抛出vAA寄存器中指定类型的异常。
11.实例操作指令
  与实例相关的操作包括实例的类型转换,检查及新建等:
•check-cast vAA, type@BBBB:将vAA寄存器中的对象引用转换成指定的类型,如果失败会抛出ClassCastException异常。如果类型B指定的是基本类型,对于非基本类型的A来说,运行时始终会失败。
•instance-of vA, vB, type@CCCC:判断vB寄存器中的对象引用是否可以转换成指定的类型,如果可以vA寄存器赋值为1,否则vA寄存器赋值为0。
•new-instance vAA, type@BBBB:构造一个指定类型对象的新实例,并将对象引用赋值给vAA寄存器,类型符type指定的类型不能是数组类。
•check-cast/jumbo vAAAA, type@BBBBBBBB:指令功能与“check-cast vAA, type@BBBB”相同,只是寄存器值与指令的索引取值范围更大(Android4.0中新增的指令)。
•instance-of/jumbo vAAAA, vBBBB, type@CCCCCCCC:指令功能与“instance-of vA, vB, type@CCCC”相同,只是寄存器值与指令的索引取值范围更大(Android4.0中新增的指令)。
•new-instance/jumbo vAAAA, type@BBBBBBBB:指令功能与“new-instance vAA, type@BBBB”相同,只是寄存器值与指令的索引取值范围更大(Android4.0中新增的指令)。
12.返回指令
  返回指令指的是函数结尾时运行的最后一条指令。它的基础字节码为teturn,共有以下四条返回指令:
•return-void:表示函数从一个void方法返回。
•return vAA:表示函数返回一个32位非对象类型的值,返回值寄存器为8位的寄存器vAA。
•return-wide vAA:表示函数返回一个64位非对象类型的值,返回值为8位的寄存器对vAA。
•return-object vAA:表示函数返回一个对象类型的值。返回值为8位的寄存器vAA。
13.数据操作指令
  数据操作指令为move。move指令的原型为“move destination,source”,move指令根据字节码的大小与类型不同,后面会跟上不同的后缀。
•move vA, vB:将vB寄存器的值赋给vA寄存器,A源寄存器与目的寄存器都为4位。
•move/from16 vAA, vBBBB:将vBBBB寄存器的值赋给vAA寄存器,源寄存器为16位,目的寄存器为8位。
•move/16 vAAAA, vBBBB:将vBBBB寄存器的值赋给vAAAA寄存器,源寄存器与目的寄存器都为16位。
•move-wide vA, vB:为4位的寄存器对赋值。源寄存器与目的寄存器都为4位。
•move-wide/from16 vAA, vBBBB 与“move-wide/16 vAAAA, vBBBB”实现与“move-wide”相同。
•move-object vA, vB:为对象赋值。源寄存器与目的寄存器都为4位。
•move-object/from16 vAA, vBBBB:为对象赋值。源寄存器为16位,目的寄存器为8位。
•move-object/16 vAA, vBBBB:为对象赋值。源寄存器与目的寄存器都为16位。
•move-result vAA:将上一个invoke类型指令操作的单字非对象结果赋给vAA寄存器。
•move-result-wide vAA:将上一个invoke类型指令操作的双字非对象结果赋给vAA寄存器。
•move-result-object vAA:将上一个invoke类型指令操作的对象结果赋给vAA寄存器。
•move-exception vAA:保存一个运行时发生的异常到vAA寄存器,这条指令必须是异常发生时的异常处理器的一条指令。否则的话,指令无效。
14.对象操作指令
  与对象实例相关的操作,比如对象创建,对象检查等.
15.数组操作指令
  数组操作包括获取数组长度,新建数组,数组赋值,数组元素取值与赋值等操作。
•array-length vA, vB:获取给定vB寄存器中数组的长度并将值赋给vA寄存器,数组长度指的是数组的条目个数。
•new-array vA, vB, type@CCCC:构造指定类型(type@CCCC)与大小(vB)的数组,并将值赋给vA寄存器。
•filled-new-array {vC, vD, vE, vF, vG},type@BBBB:构造指定类型(type@BBBB)与大小(vA)的数组并填充数组内容。vA寄存器是隐含使用的,除了指定数组的大小外还指定了参数的个数,vC~vG是使用到的参数寄存序列。
•filled-new-array/range {vCCCC  ..vNNNN}, type@BBBB:指令功能与“filled-new-array {vC, vD, vE, vF, vG},type@BBBB”相同,只是参数寄存器使用range字节码后缀指定了取值范围 ,vC是第一个参数寄存器,N = A +C -1。
•fill-array-data vAA, +BBBBBBBB:用指定的数据来填充数组,vAA寄存器为数组引用,引用必须为基础类型的数组,在指令后面会紧跟一个数据表。
•new-array/jumbo vAAAA, vBBBB,type@CCCCCCCC:指令功能与“new-
array vA,vB,type@CCCC”相同,只是寄存器值与指令的索引取值范围更大(Android4.0中新增的指令)。
•filled-new-array/jumbo {vCCCC  ..vNNNN},type@BBBBBBBB:指令功能与“filled-new-array/range {vCCCC  ..vNNNN},type@BBBB”相同,只是索引取值范围更大(Android4.0中新增的指令)。
•arrayop vAA, vBB, vCC:对vBB寄存器指定的数组元素进入取值与赋值。vCC寄存器指定数组元素索引,vAA寄存器用来存放读取的或需要设置的数组元素的值。读取元素使用aget类指令,元素赋值使用aput类指定,根据数组中存储的类型指令后面会紧跟不同的指令后缀,指令列表有 aget, aget-wide, aget-object, aget-boolean, aget-byte,aget-char, aget-short, aput, aput-wide, aput-object, aput-boolean, aput-byte, aput-char, aput-short。
————————————————
版权声明:本文为CSDN博主「逆风Lee」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lixpjita39/article/details/75193833

Android: samil语法指令集-基于dex文件结构的寄存器虚拟机的更多相关文章

  1. Android开发自学笔记(基于Android Studio1.3.1)—1.环境搭建(转)

    一.引言    本套学习笔记的开发环境是Windows 10 专业版和Android Studio 的最新版1.3.1. Android Studio 是一个Android开发环境,基于Intelli ...

  2. Android研究之为基于 x86 的 Android* 游戏选择合适的引擎具体解释

     摘要 游戏开发者知道 Android 中蕴藏着巨大的机遇. 在 Google Play 商店的前 100 款应用中,约一半是游戏应用(在利润最高的前 100 款应用中.它们所占的比例超过 90% ...

  3. 零成本实现Android/iOS自动化测试:基于Appium和Test Perfect

    https://item.taobao.com/item.htm?spm=a230r.1.14.14.42KJ3L&id=527677900735&ns=1&abbucket= ...

  4. 语法设计——基于LL(1)文法的预测分析表法

    实验二.语法设计--基于LL(1)文法的预测分析表法 一.实验目的 通过实验教学,加深学生对所学的关于编译的理论知识的理解,增强学生对所学知识的综合应用能力,并通过实践达到对所学的知识进行验证.通过对 ...

  5. Android(java)学习笔记156:Java虚拟机和Dalvik虚拟机的区别

    Google于2007年底正式发布了Android SDK, 作为 Android系统的重要特性,Dalvik虚拟机也第一次进入了人们的视野.它对内存的高效使用,和在低速CPU上表现出的高性能,确实令 ...

  6. Android(java)学习笔记99:Java虚拟机和Dalvik虚拟机的区别

    Google于2007年底正式发布了Android SDK, 作为 Android系统的重要特性,Dalvik虚拟机也第一次进入了人们的视野.它对内存的高效使用,和在低速CPU上表现出的高性能,确实令 ...

  7. 基于本地存储的kvm虚拟机在线迁移

    基于本地存储的kvm虚拟机在线迁移 kvm虚拟机迁移分为4种(1)热迁移基于共享存储(2)热迁移基于本地存储(3)冷迁移基于共享存储(4)冷迁移基于本地存储 这里介绍的是基于本地存储的热迁移 动态块迁 ...

  8. x86CPU 实模式 保护模式 傻傻分不清楚? 基于Xv6-OS 分析CR0 寄存器

    基于Xv6-OS 分析CR0 寄存器 之前一直认为晕乎乎的...啥?什么时候切换real model,怎么切换,为什么要切换? ------------------------------------ ...

  9. 【转载】基于Linux命令行KVM虚拟机的安装配置与基本使用

    基于Linux命令行KVM虚拟机的安装配置与基本使用 https://alex0227.github.io/2018/06/06/%E5%9F%BA%E4%BA%8ELinux%E5%91%BD%E4 ...

随机推荐

  1. 小菜鸟之oracle触发器

    1.触发器说明 触发器是一种在事件发生时隐式地自动执行的PL/SQL块,不能接受参数,不能被显式调用 2.触发器类型 根据触发器所创建的语句及所影响的对象的不同,将触发器分为以下3类 (1)DML触发 ...

  2. Java没有引用传递机制,C#有。

    Java没有引用传递机制,C#有: public class Obj { private Integer myValue; public Integer getMyValue() { return m ...

  3. WinForm打包

    首先要在想要打包的项目下创建一个新的项目, 创建好setup项目,之后点击属性,去修改打包软件的名字,ProductName....可以选填 到此已经创建好了setup工程了,那么下面开始将要打包的d ...

  4. ubuntu 忘记密码如何 修改密码

    ubuntu 忘记密码如何 修改密码 这个链接讲的很不错 https://blog.csdn.net/zd147896325/article/details/81664558 本来我只是玩一玩,但是我 ...

  5. 剑指offer39:平衡二叉树

    1 题目描述 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 2 思路和方法 平衡二叉树,又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1 ...

  6. php 连接webservice接口

    首先谢谢前人, 引用:https://www.cnblogs.com/xbxxf/p/10103430.html 本来说对接接口,我以为是一扮curl接口形式,结果最后给接口锝时候才告诉我是webse ...

  7. php 求两个数组的差集应该注意的事情

    对于 phper 来说 array_diff 这个函数应该知道它的用途,获取两个数组的差集,我理解中的差集是这样的 但是执行下代码会发现结果并不是 <?php $a = [1,2,3,4,5]; ...

  8. Python基础『一』

    内置数据类型 数据名称 例子 数字: Bool,Complex,Float,Integer True/False; z=a+bj; 1.23; 123 字符串: String '123456' 元组: ...

  9. python爬取网页数据并存储到mysql数据库

    #python 3.5 from urllib.request import urlopen from urllib.request import urlretrieve from bs4 impor ...

  10. fish redux 个人理解

    fish redux 理解 fish redux是什么 Fish Redux 是一个基于 Redux 数据管理的组装式 flutter 应用框架, 它特别适用于构建中大型的复杂应用. 它的特点是配置式 ...