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

3 Dalvik基础知识的更多相关文章

  1. APK反编译之一:基础知识—APK、Dalvik字节码和smali文件

    refs: APK反编译之一:基础知识http://blog.csdn.net/lpohvbe/article/details/7981386 APK反编译之二:工具介绍http://blog.csd ...

  2. JVM基础知识(1)-JVM内存区域与内存溢出

    JVM基础知识(1)-JVM内存区域与内存溢出 0. 目录 什么是JVM 运行时数据区域 HotSpot虚拟机对象探秘 OutOfMemoryError异常 1. 什么是JVM 1.1. 什么是JVM ...

  3. 【Xamarin开发 Android 系列 4】 Android 基础知识

    原文:[Xamarin开发 Android 系列 4] Android 基础知识 什么是Android? Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Li ...

  4. Android基础知识(一)

    前言 前言 从软件测试最终目的发现问题缺陷来看,Findyou比较认同一个观念,测试的能力大致可以划分成三个能力层次:发现问题.定位问题.预防问题.有机会探讨一下这个分类. 发现问题各种方式方法,比如 ...

  5. .NET面试题系列[1] - .NET框架基础知识(1)

    很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...

  6. RabbitMQ基础知识

    RabbitMQ基础知识 一.背景 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然 ...

  7. Java基础知识(壹)

    写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...

  8. selenium自动化基础知识

    什么是自动化测试? 自动化测试分为:功能自动化和性能自动化 功能自动化即使用计算机通过编码的方式来替代手工测试,完成一些重复性比较高的测试,解放测试人员的测试压力.同时,如果系统有不份模块更改后,只要 ...

  9. [SQL] SQL 基础知识梳理(一)- 数据库与 SQL

    SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...

随机推荐

  1. mac下操作小记

    安装homebrew https://juejin.im/post/5c738bacf265da2deb6aaf97 主要问题:按官网安装方法(/usr/bin/ruby -e "$(cur ...

  2. centos7 编译安装 haproxy1.8.20

    当前系统信息: [root@localhost ~]# cat /etc/os-release NAME="CentOS Linux" VERSION="7 (Core) ...

  3. Ubuntu16.04安装Filebeat

    Filebeat官方文档地址 https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-installation.html 下载和 ...

  4. NIO (一) NIO是什么

    参考文档:java为什么需要NIO:https://liuchi.coding.me/2017/08/01/浅谈Java为什么需要NIO/美团技术团队 NIO浅析:https://tech.meitu ...

  5. Guava 源码分析之Cache的实现原理

    Guava 源码分析之Cache的实现原理 前言 Google 出的 Guava 是 Java 核心增强的库,应用非常广泛. 我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Goog ...

  6. Yarn和Zookeeper的区别

    Yarn:分布式资源管理器 Zookeeper:分布式协作服务 Zookeeper是一个分布式协调服务(Coordination),一个leader,多个follower组成的集群,就是为用户的分布式 ...

  7. 【Kubernetes学习之二】Kubernetes集群安装

    环境 centos 7 Kubernetes有三种安装方式:yum.二进制.kubeadm,这里演示kubeadm. 一.准备工作1.软件版本 软件 版本 kubernetes v1.15.3 Cen ...

  8. 依赖注入(DI)与控制反转(IOC)基础知识

    依赖注入(DI)与控制反转(IOC)基础知识 一.什么是依赖注入? 依赖注入英文是Dependcy Injection简写DI,依赖注入会将所依赖的对象自动交由目标对象使用,而不是让对象自己去获取. ...

  9. 在博文顶部添加文章字数及阅读时间信息:阅读本文需要xx分钟

    1.在博客园设置中,页首Html代码中添加js代码 2.js代码如下 <script type="text/javascript"> $("#cnblogs_ ...

  10. 043 用户注册功能03--Redis安装及完成短信发送功能

    1.Redis安装 (1)下载地址:https://github.com/MicrosoftArchive/redis/releases/tag/win-3.2.100   ( redis官网: ht ...