Dalvik指令集

特点
  • 参数采用从目标到源的方式
  • 根据字节码的大小与类型不同,一些字节码添加了名称后缀以消除歧义
    • 32位常规类型的字节码未添加任何后缀
    • 64位常规类型的字节码添加-wide后缀
    • 特殊类型的字节码根据具体类型添加后缀。可以是-boolean、-byte、-char、-short、-int、-long、-float、-double、-object、-string、-class、-void之一。
  • 根据字节码的布局与选项不同,一些字节码添加了字节码后缀以消除歧义。这些后缀通过在字节码主名称后添加斜杠“/”来分隔。
  • 在指令集的描述中,宽度值中每个字母表示宽度为4位。

例如:move-wide/from16 vAA, VBBBB
move 基础字节码。标识为基本操作。
wide 名称后缀。标识指令操作数据宽度(64位)
from16 字节码后缀。标识源为16位寄存器引用变量
vAA 目的寄存器。取值v0-v255
vBBBB 源寄存器。取值v0-v65535

Dalvik指令集中大多数指令用到了寄存器作为目的操作数或源操作数,其中A/B/C/D/E/F/G/H代表一个4位数值,可表示0-15的数值或v0-v15的寄存器,而AA/BB/CC/DD/EE/FF/GG/HH代表8位的数值,可表示0-255的数值或v0-v255的寄存器,AAAA/BBBB/CCCC/DDDD/EEEE/FFFF/GGGG/HHHH代表8位的数值,可表示0-65535的数值或v0-v65535的寄存器。

空指令 nop
nop # 用来作对齐代码之用,值为00,无实际操作。  
数据操作指令 move
# 原型
move destination, source
move destination

# 将寄存器vB赋值给vA,源和目的寄存器为4位
move vA, vB 

# 将vBBBB赋值给vAA,源为16位,目的为8位
move/from16 vAA, vBBBB

# 为4位的寄存器对赋值。源和目标寄存器为4位
move-wide vA, vB 

move-wide/from16 vAA, vBBBB # 实现与move-wide相同
move-wide/16 vAAAA, vBBBB # 实现与move-wide相同

# 为对象赋值
move-object vA, vB # 源和目标为4位
move-object/from16 vAA, vBBBB # 源8位,目的16位
move-object/16 vAAAA, vBBBB # 源和目标16位

move-result vAA # 将上一个invoke类型指令操作的单字非对象结果赋值给vAA寄存器
move-result-wide vAA # 将上一个invoke类型指令操作的双字非对象结果赋值给vAA寄存器
move-result-object vAA # 将上一个invoke类型指令操作的对象结果赋值给vAA寄存器

move-exception vAA # 保存一个运行时发生的异常到vAA寄存器。必须是异常发生时的指令,否则无效
返回指令 return
# 原型
return 

return-void # void返回
return vAA # 返回32位非对象类型的值,返回值寄存器为8位
return-wide vAA # 返回64位非对象类型的值,返回值寄存器为8位
return-object vAA # 返回对象类型的值,返回值寄存器为8位
数据定义指令 const
# 原型
const

const/4 vA, #+B                                # 将数值符号扩展为32位后赋值给vA
const/16 vAA, #+BBBB                           # 将数值符号扩展为32位后赋值给vAA
const vAA, #+BBBBBBBB                          # 将数值赋值给vAA
const/high16 vAA, #+BBBB0000                   # 将数值右边零扩展为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, #+BBBBBBBB00000000      # 将数值右边零扩展为64位后赋值给vAA
const-string vAA, string@BBBB                  # 通过字符串索引构造一个字符串并赋值给vAA
const-string/jumbo vAA, string@BBBBBBBB        # 通过字符串索引(较大)构建字符串并赋值给vAA
const-class vAA, type@BBBB                     # 通过类型索引获取一个类的引用并赋值给vAA
const-class/jumbo vAAAA, type@BBBBBBBB         # 通过类型索引获取一个类的引用并赋值给vAAAA,这条指令占用2个字节,值为0x00ff
锁指令
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 # 构建一个指定对象。类型不能为数组类

check-cast/jumbo vAAAA, type@BBBBBBBB # 寄存器值与索引取值范围更大
instance-of/jumbo vAAAA, vBBBB, type@CCCCCCCC # 寄存器值与索引取值范围更大
new-instance/jumbo # 寄存器值与索引取值范围更大
数组操作
array-length vA, vB # 获取vB数组的长度到vA
new-array vA, vB, 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 .. vDDDD}, type@BBBB # 与“filled-new-array {vC, vD, vE, vF, vG}, type@BBBB”相同,只是参数寄存器使用range字节码后缀指定了取值范围,vC是第一个参数寄存器,N = A + C - 1
fill-array-data vAA, +BBBBBBBB # 用指定数据填充数组

new-array/jumbo vAAAA, vBBBB, type@CCCCCCCC # 与“new-array vA, vB, type@CCCC”相同,寄存器与索引取值范围更大
filled-new-array/jumbo {vCCCC .. vNNNN}, type@BBBBBBBB # 与“filled-new-array {vCC .. vNN}, type@BBBB”相同,寄存器与索引值取值范围更大

arrayop vAA, vBB, vCC # 对数组vBB进行取值或者赋值操作,vCC指定数组索引,vAA用来存放读取的或需要设置的数组元素值。
aget
aget-wide
aget-object
aget-boolean
aget-byte
aget-char
aget-short

aput
aput-wide
aput-object
aput-boolean
aput-byte
aput-char
aput-short
异常指令 throw
throw vAA # 抛出vAA指定的类型的异常
跳转指令
# 1. goto 无条件跳转到指定偏移处
goto +AA # AA不能为0
goto/16 +AAAA # AAAA不能为0
goto/32 +AAAAAAAA

# 2. switch跳转
packed-switch vAA, +BBBBBBBB # vAA要判断的值,BBBBBBBB指向一个packed-switch-payload格式的偏移表,表中的值规律递增 
sparse-switch vAA, +BBBBBBBB # vAA要判断的值,BBBBBBBB指向一个sparse-switch-payload格式的偏移表,表中的值是无规律的偏移量

# 3. if跳转
# 3.1 if-test vA, vB, +CCCC # 比较vA与vB,满足则跳转到CCCC处,CCCC不能为0
if-eq # if(vA == vB)
if-ne # if(vA != vB)
if-lt # if(vA < vB)
if-ge # if(vA >= vB)
if-gt # if(vA > vB)
if-le # if(vA <= vB)
# 3.2 if-testz vAA, +BBBB
if-eq # if(!AA)
if-ne # if(vAA)
if-lt # if(vAA<0)
if-ge # if(vAA>=0)
if-gt # if(vAA>0)
if-le # if(vAA<=0)
比较指令
# 原型
cmpkind vAA, vBB, vCC # 比较vBB与vCC,结果放到vAA

cmpl-float # 比较float,如果vBB>vCC结果为-1,如果vBB==vCC结果为0,如果vBB<vCC结果为1
cmpg-float # 比较float, 如果vBB>vCC结果为1,如果vBB==vCC结果为0,如果vBB<vCC结果为-1
cmpl-double # 比较double, vBB>vCC则-1,vBB==vCC则0,vBB<vCC则1
cmpg-double # 比较double,vBB>vCC则1,vBB==vCC则0,vBB<vCC则-1
cmpl-lang # 比较lang
字段操作指令
# 1. 普通字段
iinstanceop vA, vB, field@CCCC
# 2. 静态字段
sstaticop vAA, field@BBBB

# 普通字段前缀为i,比如读取用iget,写入用iput
# 静态字段前缀为s,比如读取用sget,写入用sput
# 根据访问字段类型不同,指令后紧跟类型后缀,比如iget-byte
iget
iget-wide
iget-object
iget-boolean
iget-byte
iget-char
iget-short

iput
iput-wide
iput-object
iput-boolean
iput-byte
iput-char
iput-short
方法调用指令 invoke
# 原型
invoke-kind {vC,vD,vE,vF,vG}, method@BBBB
invoke-kind/range {vCCCC .. vNNNN}, method@BBBB

# 调用虚方法
invoke-virtual
invoke-virtual/range

# 调用父类方法
invoke-super
invoke-super/range

# 调用直接方法
invoke-direct
invoke-direct/range

# 调用静态方法
invoke-static
invoke-static/range

# 调用实例的接口方法
invoke-interface
invoke-interface/range

# 方法调用返回值需要调用move-result* 指令来获取,比如
invoke-static {}, Landroid/os/Parcel;->obtain()Landroid/os/Parcel;
move-result-object v0
数据转换指令
# 原型
unop vA, vB # 转为vB,结果存在vA中

neg-int # 整数求补
not-int # 整数求反
neg-long # 长整型求补
not-long # 长整型求反
neg-float # 单精度浮点求补
not-float # 单精度浮点求反

int-to-long
int-to-float
int-to-double
long-to-int
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
数据运算指令
# 原型
binop vAA, vBB, vCC # 将vBB与vCC进行运算,结果保存到vAA
binop/2addr vA, vB  # 将vA与vB进行计算,结果保存到vA
binop/lit16 vA, vB, #+CCCC # 将vB与常量CCCC进行计算,保存到vA
binop/lit8 vAA, vBB, #+CC # 将vBB与CC进行计算,保存到vAA

add-type # vBB+vCC
sub-type # vBB-vCC
mul-type # vBB*vCC
div-type # vBB/vCC
rem-type # vBB%vCC
and-type # vBB and vCC
or-type  # vBB or vCC
xor-type # vBB xor vCC
shl-type # vBB << vCC
shr-type # vBB >> vCC
ushr-type # vBB >> vCC

# -type可以为-int、-long、-float、-double
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值