zoukankan      html  css  js  c++  java
  • 3 Dalvik基础知识

    Dalvik汇编基础知识:

    Dalvik指令:由位描述+指令格式标示

    位描述:

    1. 每16位空格隔开

    2. 每个字母表示4位,每个字母按从高字节开始,排列到低字节。每四位之间可用 | 分开表示不同内容

    3. 顺序采用A~Z单个大写字母作为一个4位操作码,op表示一个8位操作码

    4. Ø表示这字段所有位为0

    Eg:A|G|op BBBB F|E|D|C

           分成三部分:A|G|op 高8位是A G 低8位是op 

                                BBBBB 一个16位的偏移值

                                F|E|D|C 表示寄存器参数

     

    指令格式:

    1. 大多有三个字符组成,前两个是数字,后一个是字母

    2. 第一个数字表示指令有多少个16位的字

    3. 第二个数字表示指令最多使用的寄存器个数,“r”标示使用一定范围内的寄存器

    4. 第三个字母为类型码

    助记符

    位大小

    说明

    b

    8

    8位有符号立即数

    c

    16,32

    常量池索引

    f

    16

    接口常量(仅静态有效)

    h

    16

    有符号立即数(32位或64位的高值位,低值位为0)

    i

    32

    立即数,有符号整数或32位浮点数

    l

    64

    立即数,有符号或64位双精度浮点数

    m

    16

    方法常量(仅静态有效)

    n

    4

    4位立即数

    s

    16

    短整形立即数

    t

    8,16,32

    跳转,分支

    x

    0

    无额外数据

    Eg:22x    两个16位字,2个寄存器,无额外数据

     

    Dalvik语法:

    1. 每条指令从操作码开始,后面紧跟参数,参数之间由逗号隔开

    2. 每条指令的参数从指令第一部分开始,op位于低8位,高8位可以是一个8位参数,两个4位参数或空,超过16位,指令后面部分依次作为参数

    3. 参数“vX”表示是一个寄存器

    4. 参数“#+X”表示常量数字

    5. 参数“+X”表示地址偏移

    6. 参数“kind@X”表示常量池索引,kind可以是:string,type,field,meth

     

    Dalvik寄存器:

    Dalvik虚拟机基于ARM架构,将部分寄存器映射到ARM寄存器上,其余的通过调用栈模拟

    说明:Dalvik寄存器是32位。支持64位,两个相邻的寄存器标示

    Eg: op vAAAA,vBBBB    寄存器从v0开始,寄存器可能的范围 0~65535

    每个函数的头部 .registers 指定函数使用的寄存器数目

     

    寄存器--V和P命名法

    假设一个函数有M个寄存器N个参数:

    V:从v0开始依次递增

    P:函数使用的寄存器从v0开始依次递增,参数从p0开始依次递增

     

    一、Dalvik类型:

    Dalvik字节码只有两种类型:

    1. 基本类型:除对象,数组,其他的java类型

    2. 引用类型:对象,数组

    字节码描述符

    语法

    含义

    V

    void 只用于返回值类型

    Z

    boolean

    B

    byte

    S

    short

    C

    char

    I

    int

    J

    long

    F

    float

    D

    double

    L

    Java类类型

    [

    数组类型

    说明:Dalvik寄存器是32位表示象J 、D 等64位数据类型两个相邻的寄存器存储

    L  Ljava/lang/String; 后面有 ;表示结束,相当于 java.lang.String

    [  后面紧跟基本类型描述符

           [I 一维整形数组 int[]

           [[I  二维整形数组 int[][]

           [[[I   三维整形数组 int[][][]

           数组最大维数255个

    L和[同时表示对象数组

           [Ljava/lang/String;  Java中的字符串数组

     

    二、Dalvik方法

    使用方法名,类型参数,返回值描述一个方法

    Eg:Lpackage/name/ObjectName;->MethodName(III)Z

           Lpackage/name/ObjectName; 一个类型

           MethodName 方法名

           (III) 三个int型参数

           Z 返回值类型为void

           method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;

    等价于:String method(int ,int[][] ,int ,String ,Object[])

          

    三、Dalvik字段

    字段与方法类似,没有方法的参数和返回值

    Eg:Lpackage/name/ObjectName;->FiledName:Ljava/lang/String;

           Lpackage/name/ObjectName; 包名

           FiledName  字段名 用:隔开字段类型

    Ljava/lang/String; 字段类型

    #注释

     

    Dalvik指令特点:

    1. 参数从目标到源

    2. 根据字节码大小和类型添加后缀

    a)      32位常规类型没有后缀

    b)      64位类型添加- wide后缀

    c)      特殊类型字节码根据具体类型添加后缀:boolean, byte, char, short, int, long, float, double, object, string, class, void

    3. 根据字节布局与选项添加字节码后缀消除歧义。这些后缀通过字节码主名“/”分隔

    4. 指令集中每个字母宽度为4

    Eg:move-wide/from16 vAA,vBBBB

           move为基础字节码,标示基本操作

           wide 为名称后后缀,标示指令操作的数据宽度(16位)

           from16 为字节码后缀,标示一个16位的寄存器引用变量

           vAA 为目的寄存器,始终在源寄存器前

           vBBBB 为源寄存器

     

    空操作指令 nop 值为0,常用来对齐操作,无实际操作

     

    数据操作指令 move

    move 格式:move 目标寄存器,源寄存器    move根据字节码的大小与类型,后会跟上不同后缀

     

    返回指令 return

           返回函数结尾时运行的最后一条指令。   

     

    数据定义指令 用来定义程序中的常量,字符串,类等数据,基础字节码 const

           const 格式:const 目标寄存器,源寄存器     const根据字节码的大小与类型,后会跟上不同后缀

     

    锁指令 有两种:

           monitor-enter vAA  为指定对象获取锁

           monitor-exit vAA  释放指定对象的锁

     

    实例操作指令:包括类型转换,检查,新建等

    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    

    instance-of/jumbo vAAAA,type@CCCCCCCC

    new-instance/jumbo vAAAA,type@BBBBBBBB

     

    数组操作指令:

           获取数组长度,新建数组,数组赋值,数组元素赋值取值操作

           arrary-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           功能同上,参数寄存器使用range字节码后缀指定取值范围

           fill-array-data vAA,+BBBBBBBB         用指定数据填充数组,vAA为数组引用(必需是基础类型),指令后跟一个数据表

           new-array/jumbo vAAAA,vBBBB,type@CCCCCCCC      

           arrayop vAA,vBB,vCC          对vBB寄存器指定的数组元素进入取值与赋值,vCC指定数组元素索引,vAA存放读取的或需要设置的数组元素的值。读取用aget指令,赋值用aput类指令。

     

    异常指令

           throw vAA

     

    跳转指令:

           三种跳转指令,无条件跳转(go-to),分支跳转(switch),条件跳转(if)

           goto +AA

           goto/16 +AAAA

           goto/32 +AAAAAAAA

           packed-switch vAA,+BBBBBBBB

           sparse-switch vAA,+BBBBBBBB

           if-test vA,vB,+CCCC

                  if-test类型:

                         if-eq       vA == vB

                         if-ne         !=

                         if-lt           <

                         if-ge         >=

                         if-gt         >

                         if-le          <=

           if-testz vAA,+BBBB

                  if-eqz              == 0

                  if-nez              !=0

                  if-ltz               <0

                  if-gez              >=0

                  if-gtz               >=0

                  if-lez                <=0

     

    比较指令:

           cmpkind vAA,vBB,vCC        vBB和vCC比较结果存放到vAA              vBB>vCC 结果-1  vBB==vCC结果0 vBB<vCC结果1

                  cmpl-float

                  cmpg-float

                  cmpl-double

                  cmpg-double

                  cmp-long

     

    字段操作指令:

           用来对对象实例的字段进行读写操作

           普通字段:iinstanceop vA,vB,field@CCCC

                  普通字段指令前缀i,读操作iget,写操作iput

           静态字段:staticop vAA,field@BBBB

                  静态字段指令前缀s,读操作sget,写操作sput

           根据字段类型不同,字段操作后面会紧跟字段类型后缀,两类指令操作结果一样,只是指令前缀与操作字段类型不同

     

    方法调用指令

           负责类的调用类的实例方法,基础指令invoke分两类:

    1. invoke-kind {vC,vD,vE,vF,vG},meth@BBBB

    2. Invoke-kind{vCCCC...vNNNN},meth@BBBB

    根据方法类型不同,共有5条方法调用指令

           1.invoke-virtual   invoke-virtual/range 调用实例的虚方法

           2.invoke-super     invoke-super/range 调用实例的父类方法

           3.invoke-direct     invoke-direct/range 调用实例的直接方法

           4.Invoke-interface invoke-interface/range 调用实例的接口方法

     

    数据转换指令:

          格式unop vA,vB   vB需要转换的数据,vA转换后的结果

           neg-int          int数      求补

           not-int                         求反

           neg-long       long

           not-long

           neg-float

           neg-double

           int-to-long           int转long

           int-to-float

           int-to-double

           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

     

    数据运算指令

           有4类指令:

    1. binop vAA,vBB,vCC                     vBB与vCC计算结果保存到vAA

    2. Binop/2addr vA,vB

    3. Binop/lit16 vA,vB,#+CCCC

    4. Binop/lit8 vAA,vBB,#+CC

    第一类指令可归结为:

           add-type

           sub-type

           mul-type

           div-type

           rem-type       摸运算

           and-type

           or-type

           xor-type

           shl-type         有符号左移

           shr-type        有符号右移

           ushr-type      无符号右移

  • 相关阅读:
    PHP之Trait详解
    PHP中__call()方法与重载解析
    PHP Closure(闭包)类详解
    PHP 核心特性
    回调函数
    php的各种 I/O流 以及用法
    关于php的buffer(缓冲区)
    php的运行原理、cgi对比fastcgi以及php-cgi和php-fpm之间的联系区别
    低功耗设计入门(一)——低功耗设计目的与功耗的类型
    从CMOS到触发器(一)
  • 原文地址:https://www.cnblogs.com/heixiang/p/10965978.html
Copyright © 2011-2022 走看看