Dalvik指令集

转载请以链接形式标明出处:
本文出自:103style的博客

对于 Android 4.4 之前的系统, 可以在 Android 源码 davik/libdex/DexOpcodes.h中找到完整的Dalvik指令集。
对于 Android 4.4 及之后的以 ART 主导的系统, 可以在 Android 源码 art/runtime/dexinstuctionlist.h中找到完整的Dalvik指令集。

空操作指令

nop :值为00

通常用于对齐代码,不进行实际操作


数据操作指令

数据操作指令为move,原型为 move destination, source

指令作用
move vA, vB4位 vB 寄存器的 值 赋值给4位 vA 寄存器
move/from16 vAA, vBBBB16位 vBBBB 寄存器的 值 赋值给8位 vAA 寄存器
move/16 vAAAA, vBBBB16位 vBBBB 寄存器的 值 赋值给16位 vAAAA 寄存器
move-wide vA, vB4位 vB 寄存器的 值 赋值给4位 vA 寄存器
move-wide/from16 vAA, vBBBBmove/from16 vAA, vBBBB
move-object vA, vB4位 vB 寄存器的 对象 赋值给4位 vA 寄存器
move-object/from16 vAA, vBBBB16位 vBBBB 寄存器的 对象 赋值给8位 vAA 寄存器
move-object/16 vAAAA, vBBBB16位 vBBBB 寄存器的 对象 赋值给16位 vAAAA 寄存器
move-result vAA用于将上一个invoke类型指令操作的 单字非对象结果 赋予 vAA 寄存器
move-result-wide vAA用于将上一个invoke类型指令操作的 双字非对象结果 赋予 vAA 寄存器
move-result-object vAA用于将上一个invoke类型指令操作的 对象结果 赋予 vAA 寄存器
move-exception vAA用与将上一个在运行时发生的异常保存到 vAA 寄存器,必须在异常发生时由异常处理器使用

返回指令

返回指令:函数结束时运行的最后一条指令,基础字节码为return

指令作用
return-void函数从一个void方法返回
return vAA函数返回一个32位非对象类型的值,返回值为8位寄存器 vAA
return-wide vAA函数返回一个64位非对象类型的值,返回值为8位寄存器 vAA
return-object vAA函数返回一个对象类型的值,返回值为8位寄存器 vAA

数据定义指令
指令作用
const/4 vA, #+B将数值符号扩展为32位后赋予寄存器vA
const/16 vAA, #+BBBB将数值符号扩展为32位后赋予寄存器vAA
const vAA, #+BBBBBBBB将数值赋予寄存器vAA
const/high16 vAA, #+BBBB0000将数值右边的0扩展为32位后赋予寄存器vAA
const-wide/16 vAA, #+BBBB将数值符号扩展为64位后赋予寄存器vAA
const-wide/32 vAA, #+BBBBBBBB将数值符号扩展为64位后赋予寄存器vAA
const-wide vAA, #+BBBBBBBBBBBBBBBB将数值符号赋予寄存器vAA
const-wide/high16 vAA, #+BBBB000000000000将数值右边的0扩展为64位后赋予寄存器vAA
const-string vAA, string@BBBB通过字符串索引构造一个字符串,并将其赋予寄存器vAA
const-string/jumbo vAA, string@BBBBBBBB通过字符串索引(较大)构造一个字符串,并将其赋予寄存器vAA
const-class vAA, type@BBBB通过类型索引获取一个类的引用,并将其赋予寄存器vAA
const-class vAAAA, type@BBBBBBBB通过给定类型索引获取一个类的引用,并将其赋予寄存器vAAAA,此指令占2字节,值为0x00ff

锁指令
指令作用
monitor-enter vAA为指定对象获取锁
monitor-exit vAA为指定对象释放锁

实例操作指令

包括 类型转换检查 以及 创建 等。

指令作用
check-cast vAA, type@BBBBvAA 寄存器中的对象引用转换成指定的类型
instance-of vA, vB, type@CCCC判断 vB 寄存器中的对象引用是否可以转换成指定的类型, 可以 vA 寄存器中的值为 1, 否则 为 0
new-instance vAA, type@BBBB构造一个指定对象的新实例,并赋值给 vAA 寄存器,type不能时数组类
check-cast/jumbo vAAAA, type@BBBBBBBBcheck-cast vAA, type@BBBB类似,只是取值范围更大
instance-of/jumbo vAAAA, vBBBB, type@CCCCCCCinstance-of vA, vB, type@CCCC类似,只是取值范围更大
new-instance/jumbo vAAAA, type@BBBBBBBBnew-instance vAA, type@BBBB类似,只是取值范围更大

数组操作指令

包括 获取数组长度新建数组数组赋值数组元素取值和赋值

指令作用
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)的数组并填充数组内容。
filled-new-array/range{vCCCC ... vNNNN}, type@BBBBfilled-new-array类似,只是用 range 来指定取值范围
fill-array-data vAA, +BBBBBBBB用指定的数据类填充数组
new-array/jumbo vAAAA, vBBBB, type@CCCCCCCCnew-array类似,只是取值范围更大
filled-new-array/jumbo{vCCCC ... vNNNN}, type@BBBBfilled-new-array类似,只是取值范围更大
arrayop vAA, vBB, vCCvBB寄存器指定的数组元素进行取值和赋值;vCC寄存器用于指定数组元素的索引; vAA寄存器用于存放读取获取或需要设置的数组元素的值

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

跳转指令

指从当前地址跳转到指定的偏移出。分为以下三类:

  • 无条件跳转指定 goto
  • 分支跳转指令 switch
  • 条件跳转指令 if
指令作用
goto +AA无条件跳转到指定偏移处,偏移量 AA 不能为0
goto/16 +AAAA无条件跳转到指定偏移处,偏移量 AAAA 不能为0
goto/32 +AAAAAAAA无条件跳转到指定偏移处
packed-swtich vAA, +BBBBBBBBvAA 寄存器为 swtich 分支中需要判断的值, BBBBBBBB指向一个packed-swtich-payload格式的偏移表,表中的值时 递增 的偏移量
sparse-swtich vAA, +BBBBBBBBvAA 寄存器为 swtich 分支中需要判断的值, BBBBBBBB指向一个packed-swtich-payload格式的偏移表,表中的值时 无规律 的偏移量
if-test vA, vB, +CCCC条件跳转指令用于比较 vAvB 寄存器的值
if-testz vAA, +BBBBvAA 寄存器中的值与 0 比较,如果满足或者值为 0,则跳转到 BBBB 偏移处,BBBB 不能为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 指令如下:

指令作用
if-eqz如果 vAA0 则跳转,Java语法表示为if(!vAA)
if-nez如果 vAA 不为 0 则跳转,Java语法表示为if(vAA)
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)

比较指令

对两个寄存器的值进行比较,格式 cmpkid vAA, vBB, vCCvAA 表示 vBBvCC 比较的结果。

指令作用
cmpl-float vAA, vBB, vCC用于比较两个单精度浮点数 (vAA=0 : vBB=vCCvAA=-1 : vBB>vCCvAA=1 : vBB<vCC)
cmpg-float vAA, vBB, vCC用于比较两个单精度浮点数(vAA=0 : vBB=vCCvAA=1 : vBB>vCCvAA=-1 : vBB<vCC)
cmpl-double vAA, vBB, vCC用于比较两个双精度浮点数(vAA=0 : vBB=vCCvAA=-1 : vBB>vCCvAA=1 : vBB<vCC)
cmpg-double vAA, vBB, vCC用于比较两个双精度浮点数(vAA=0 : vBB=vCCvAA=1 : vBB>vCCvAA=-1 : vBB<vCC)
cmp-long vAA, vBB, vCC用于比较两个长整型数(vAA=0 : vBB=vCCvAA=1 : vBB>vCCvAA=-1 : vBB<vCC)

字段操作指令

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

有以下两种指令集:

  • iinstanceop vA, vB, field@CCCC : 操作普通字段,以i开头 – iget读,iput
  • sstaticop vAA, field@CCCC : 操作静态字段,以s开头 – sget读,sput
指令
igetsgetiputsput
iget-widesget-wideiput-sput-
iget-objectsget-objectiput-objectsput-object
iget-booleansget-booleaniput-booleansput-boolean
iget-bytesget-byteiput-bytesput-byte
iget-charsget-chariput-charsput-char
iget-shortsget-shortiput-shortsput-short

Android 4.0 中, Dalvik指令集增加了以下两类指令:

  • iinstanceop/jumbo vAAAA, vBBBB, field@CCCCCCCC
  • sstaicop/jumbo vAAAA, field@BBBBBBBB

和上面两类类似,只是增加了 jimbo后缀,且寄存器的指令索引的取值范围更大。


方法调用指令

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

可分为以下两类:

  • invoke-kind {vC, vD, vE, vF, vG}, meth#BBBB
  • invoke-kind/range {vCCC ... vNNNN}, meth#BBBB
    相比第一类,只是用range来指定寄存器的范围
指令作用
invoke-virtual or invoke-virtual/range调用实例的虚方法
invoke-super or invoke-super/range调用实例的父类方法
invoke-direct or invoke-direct/range调用实例的直接方法
invoke-static or invoke-static/range调用实例的静态方法
invoke-interface or invoke-interface/range调用实例的接口方法

数据转换指令
指令作用
neg-int用于对 整数类型 求 补
not-int用于对 整数类型 求 反
neg-long用于对 长整型 求 补
not-long用于对 长整型 求 反
neg-float用于对 单精度浮点型 求 补
neg-double用于对 双精度浮点型 求 补
int-to-float用于 整型 转换为 单精度浮点型
A-to-B同上,用于 A( int、long、float、double ) 转换为 B( int、long、float、double )
int-to-byte用于 整型 转换为 字节型
int-to-char用于 整型 转换为 字符型
int-to-short用于 整型 转换为 短整型

数据运算指令

数据运算指令 包含 算术运算指令逻辑运算指令

可以分成以下四类:

指令类别作用
binop vAA, vBB, vCCvBBvCC 寄存器进行运算,将运算结果保存在 vAA
binop/2addr vA, vBvAvB 寄存器进行运算,将运算结果保存在 vA
binop/lit16 vA, vB, #+CCCCvB 寄存器和 CCCC 常量进行运算,将运算结果保存在 vA
binop/lit8 vAA, vBB, #+CCvBB 寄存器和 CC 常量进行运算,将运算结果保存在 vAA

第一类binop vAA, vBB, vCC指令可归类如下:

指令作用
add-typevBBvCC 寄存器的值进行 加法运算 vBB + vCC
sub-typevBBvCC 寄存器的值进行 减法运算 vBB - vCC
mul-typevBBvCC 寄存器的值进行 乘法运算 vBB * vCC
div-typevBBvCC 寄存器的值进行 除法运算 vBB / vCC
rem-typevBBvCC 寄存器的值进行 模运算 vBB % vCC
and-typevBBvCC 寄存器的值进行 与运算 vBB AND vCC
or-typevBBvCC 寄存器的值进行 或运算 vBB OR vCC
xor-typevBBvCC 寄存器的值进行 异或运算 vBB XOR vCC
shl-typevBB 寄存器中的值(有符号数)左移 vCCvBB<<vCC
shr-typevBB 寄存器中的值(有符号数)右移 vCCvBB>>vCC
ushr-typevBB 寄存器中的值(无符号数)右移 vCCvBB>>vCC

以上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值