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, vB 4位 vB 寄存器的 值 赋值给4位 vA 寄存器
move/from16 vAA, vBBBB 16位 vBBBB 寄存器的 值 赋值给8位 vAA 寄存器
move/16 vAAAA, vBBBB 16位 vBBBB 寄存器的 值 赋值给16位 vAAAA 寄存器
move-wide vA, vB 4位 vB 寄存器的 值 赋值给4位 vA 寄存器
move-wide/from16 vAA, vBBBB move/from16 vAA, vBBBB
move-object vA, vB 4位 vB 寄存器的 对象 赋值给4位 vA 寄存器
move-object/from16 vAA, vBBBB 16位 vBBBB 寄存器的 对象 赋值给8位 vAA 寄存器
move-object/16 vAAAA, vBBBB 16位 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@BBBB vAA 寄存器中的对象引用转换成指定的类型
instance-of vA, vB, type@CCCC 判断 vB 寄存器中的对象引用是否可以转换成指定的类型, 可以 vA 寄存器中的值为 1, 否则 为 0
new-instance vAA, type@BBBB 构造一个指定对象的新实例,并赋值给 vAA 寄存器,type不能时数组类
check-cast/jumbo vAAAA, type@BBBBBBBB check-cast vAA, type@BBBB类似,只是取值范围更大
instance-of/jumbo vAAAA, vBBBB, type@CCCCCCC instance-of vA, vB, type@CCCC类似,只是取值范围更大
new-instance/jumbo vAAAA, type@BBBBBBBB new-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@BBBB filled-new-array类似,只是用 range 来指定取值范围
fill-array-data vAA, +BBBBBBBB 用指定的数据类填充数组
new-array/jumbo vAAAA, vBBBB, type@CCCCCCCC new-array类似,只是取值范围更大
filled-new-array/jumbo{vCCCC ... vNNNN}, type@BBBB filled-new-array类似,只是取值范围更大
arrayop vAA, vBB, vCC vBB寄存器指定的数组元素进行取值和赋值;vCC寄存器用于指定数组元素的索引; vAA寄存器用于存放读取获取或需要设置的数组元素的值

异常指令

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

跳转指令

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

  • 无条件跳转指定 goto
  • 分支跳转指令 switch
  • 条件跳转指令 if
指令 作用
goto +AA 无条件跳转到指定偏移处,偏移量 AA 不能为0
goto/16 +AAAA 无条件跳转到指定偏移处,偏移量 AAAA 不能为0
goto/32 +AAAAAAAA 无条件跳转到指定偏移处
packed-swtich vAA, +BBBBBBBB vAA 寄存器为 swtich 分支中需要判断的值, BBBBBBBB指向一个packed-swtich-payload格式的偏移表,表中的值时 递增 的偏移量
sparse-swtich vAA, +BBBBBBBB vAA 寄存器为 swtich 分支中需要判断的值, BBBBBBBB指向一个packed-swtich-payload格式的偏移表,表中的值时 无规律 的偏移量
if-test vA, vB, +CCCC 条件跳转指令用于比较 vAvB 寄存器的值
if-testz vAA, +BBBB vAA 寄存器中的值与 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
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)
cmpg-float vAA, vBB, vCC 用于比较两个单精度浮点数(vAA=0 : vBB=vCCvAA=1 : vBB>vCCvAA=-1 : vBB)
cmpl-double vAA, vBB, vCC 用于比较两个双精度浮点数(vAA=0 : vBB=vCCvAA=-1 : vBB>vCCvAA=1 : vBB)
cmpg-double vAA, vBB, vCC 用于比较两个双精度浮点数(vAA=0 : vBB=vCCvAA=1 : vBB>vCCvAA=-1 : vBB)
cmp-long vAA, vBB, vCC 用于比较两个长整型数(vAA=0 : vBB=vCCvAA=1 : vBB>vCCvAA=-1 : vBB)

字段操作指令

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

有以下两种指令集:

  • 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, vCC vBBvCC 寄存器进行运算,将运算结果保存在 vAA
binop/2addr vA, vB vAvB 寄存器进行运算,将运算结果保存在 vA
binop/lit16 vA, vB, #+CCCC vB 寄存器和 CCCC 常量进行运算,将运算结果保存在 vA
binop/lit8 vAA, vBB, #+CC vBB 寄存器和 CC 常量进行运算,将运算结果保存在 vAA

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

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

如果觉得不错的话,请帮忙点个赞呗。

以上


扫描下面的二维码,关注我的公众号 Android1024, 点关注,不迷路。

Android1024

你可能感兴趣的:(Dalvik指令集)