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      无符号右移

 

posted on 2019-06-03 10:01  黑箱  阅读(495)  评论(0)    收藏  举报