Dalvik汇编代码由Dalvik指令组成,指令语法由指令的位描述与指令格式辨识来决定。位描述的约定如下所示:
举例,如以下指令:
A|G|op BBBB F|E|D|C
单独使用位标识还无法确定一条指令,必须通过指令格式标识来指定格式编码,它的约定如下所示:
举例,如以下指令
op vAA, string@BBBB
1个寄存器vAA,1个字符串常量池索引。
Dalvik指令的语法与助记符有如下特点:
举例,如以下指令:
move-wide/from16 vAA,vBBBB
助记符:nop
指令:对齐代码,无实际操作。
助记符:move
指令:move指令会根据字节码的大小和类型不同,后面跟不同的后缀
move destination,source
举例
move/from16 vAA,vBBBB;将vBBBB寄存器的值赋给vAA寄存器,源寄存器和目的寄存器都为16位
move-wide vA,vB;4位寄存器对赋值,源寄存器与目的寄存器都为4位
move-result vAA;将上一个invoke类型指令操作的双字非对象结果赋值给vAA寄存器
move-object vA,vB;为对象赋值,源寄存器与目的寄存器都为4位
move-exception vAA;保存一个运行时发生的异常到vAA寄存器
助记符:return
指令:它有4中类型
return-void;表示函数从一个void方法返回
return-vAA;表示函数返回一个32位非对象类型的值,返回寄存器为6位jicunqivAA
return-wide vAA;表示函数返回一个62位非对象类型的值,返回值为8位的寄存器vAA
return-object vAA;表示函数返回一个对象类型的值,返回值为8位的寄存器vAA
助记符:const
指令:数据定义指令用来定义程序中用到的常量、字符串和类等数据。
const/4 vA,#+B;将数值符号扩展为32位后赋值给寄存器vA
const/16 vAA,#+BBBB;将数值符号扩展为32位后赋给寄存器vAA
const/high16 vAA,#+BBBB0000;将数值右边零扩展为32位后赋给寄存器vAA
const-wide/16 vAA,#+BBBB;将数值符号扩展为64位后赋值给寄存器vAA
const-string vAA,string@BBBB;通过字符串索引构造一个字符串并赋值给寄存器vAA
const-class vAA,type@BBBB;通过类型索引获取一个类引用并赋给寄存器vAA
const-class/jumbo vAAAA,type@BBBBBBBB;通过给定类型的索引获取一个类引用并赋给寄存器vAAAA,这条指令占用两个字节,值为0x00ff
助记符:monitor
指令:锁指令多用在多线程程序中对同一对象的操作。
monitor-enter vAA;为指定对象获取锁
monitor-exit vAA;释放指定对象的锁
助记符:check-cast、instace-of、new-instance
指令:实例的类型转换、检查和更新。
check-cast vAA,type@BBBB;将寄存器vAA中的对象引用转换成指定的类型,如果失败则抛出ClassCastException,如果类型B指定的是基本类型,对于非基本类型A来说,运行时始终会失败
instance-of vA,vB,type@CCCC;判断vB寄存器中的对象引用是否可以转换成指定的类型,如果可以vA的寄存器赋值为1,否则赋值为0
new-instance vAA,type@BBBB;构造一个指定类型对象的新实例,并将对象引用赋值给vAA寄存器,类型符type指定的类型不能是数组类
助记符:array-length、new-array、filed-new-array、fill-array-data、arrayop
指令:取数组长度、新建数组、数组赋值、数组元素取值与赋值。
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)的数组并填充数组内容,vA寄存器是隐含使用的,除了指定数组的大小外还指定了参数的个数,vC~vG是使用到的参数寄存器序列
助记符:throw
指令:抛出异常
throw vA;抛出vA寄存器中指定类型的异常
助记符:goto、packed-switch、sparse-switch、if-test、if-testz
指令:从当前地址跳转到指定的偏移处。
goto+AA;无条件跳转到指定偏移处,偏移量AA不能为0
packed-switch vAA,+BBBBBBBB;分支跳转指令,vAA寄存器为switch分支需要判断的值,BBBBBBBBB指向一个packed-swithc-payload格式的偏移表,表中的值是按规律递增的
sparse-switch vAA,+BBBBBBBB;分支跳转指令,vAA寄存器为switch分支需要判断的值,BBBBBBBBB指向一个sparse-swithc-payload格式的偏移表,表中的值无规律的偏移量
if-test vA,vB,+CCCC;条件跳转指令,比较vA寄存器和vB寄存器的值,如果比较结果满足就跳转到CCCC指定的偏移处,偏移量CCCC不能为0
if-eq vA,vB,+CCCC;if(vA==vB)则跳转
if-ne vA,vB,+CCCC;if(vA!=vB)则跳转
if-lt vA,vB,+CCCC;if(vA<vB)则跳转
if-ge vA,vB,+CCCC;if(vA>=vB)则跳转
if-gt vA,vB,+CCCC;if(vA>vB)则跳转
if-le vA,vB,+CCCC;if(vA<=vB)则跳转
if-testz vA,+CCCC;条件跳转指令,比较vA寄存器和0比较,如果比较结果满足或值为0就跳转到CCCC指定的偏移处,偏移量CCCC不能为0
if-eqz vA,+CCCC;if(!vA)则跳转
if-nez vA,+CCCC;if(vA)则跳转
if-ltz vA,+CCCC;if(vA<0)则跳转
if-gez vA,+CCCC;if(vA>=0)则跳转
if-gtz vA,+CCCC;if(vA>0)则跳转
if-lez vA,+CCCC;if(vA<=0)则跳转
助记符:cmpl-float、cmpg-float、cmpl-double、cmpg-double和cmp-log
指令:比较两个寄存器的值
cmpl-float vAA,vBB,vCC;比较两个单精度浮点数,vBB>vCC,则结果为-1,vBB==vCC,则结果为0,vBB<vCC,则结果为1,最终结果存放到vAA中
cmpg-float vAA,vBB,vCC;比较两个单精度浮点数,vBB>vCC,则结果为1,vBB==vCC,则结果为0,vBB<vCC,则结果为-1,最终结果存放到vAA中
cmpl-double vAA,vBB,vCC;比较两个双精度浮点数,vBB>vCC,则结果为-1,vBB==vCC,则结果为0,vBB<vCC,则结果为1,最终结果存放到vAA中
cmpg-double vAA,vBB,vCC;比较两个双精度浮点数,vBB>vCC,则结果为1,vBB==vCC,则结果为0,vBB<vCC,则结果为-1,最终结果存放到vAA中
cmp-long vAA,vBB,vCC;比较两个长整型数,vBB>vCC,则结果为1,vBB==vCC,则结果为0,vBB<vCC,则结果为-1,最终结果存放到vAA中
助记符:iinstaceop、sstaticop
指令:字段操作指令用来对对象实例的字段进入读写操作,字段的类型可以是Java中任何有效的数据类型。
1 普通字段指令
iget、iget-wide、iget-object等
iinstanceop vA,vB,field@CCCCC
2 静态字段指令
sget、sget-wide、sget-object等
`sstaicop vA,vB,field@CCCCC `
助记符:invoke
指令:调用实例的方法。
invoke-virtual;调用实例的虚方法
invoke-super;调用实例的父类方法
invoke-direct;调用实例的直接方法
invoke-static;调用实例的静态方法
invoke-interface;调用实例的接口方法
以下方式和上面的写法并无差别,只是后者在设置参数寄存器时使用了range来指定寄存器的范围。
invoke-virtual/range;调用实例的虚方法
invoke-super/range;调用实例的父类方法
invoke-direct/range;调用实例的直接方法
invoke-static/range;调用实例的静态方法
invoke-interface/range;调用实例的接口方法
方法调用指令的放回值需要用“move-result”指令来获取:
invoke-static {}, Landroid/os/Parcel:->obtain()Landroid/Parcel;
move-result-object v0
助记符:unop
指令:用于将一种类型的数据转换为另一种数据类型。
neg-int;整数求补
not-int;整数求反
long-to-int;长整型数转换为整型数
助记符:add、sub、mul、div、rem、and、or、xor、shl、shr、ushr
指令:算术运算:加、减、乘、除、模、移位。逻辑运算:与、或、非、抑或。
add等操作符后还可以添加后缀2addr、lit16和lit8等后缀
add-type vAA,vBB,vCC;vBB + vCC将结果保存到vAA
sub-type vAA,vBB,vCC;vBB - vCC将结果保存到vAA
mul-type vAA,vBB,vCC;vBB x vCC将结果保存到vAA
div-type vAA,vBB,vCC;vBB / vCC将结果保存到vAA
rem-type vAA,vBB,vCC;vBB % vCC将结果保存到vAA
and-type vAA,vBB,vCC;vBB AND vCC将结果保存到vAA
or-type vAA,vBB,vCC;vBB OR vCC将结果保存到vAA
xor-type vAA,vBB,vCC;vBB XOR vCC将结果保存到vAA
shl-type vAA,vBB,vCC;vBB << vCC将结果保存到vAA
shr-type vAA,vBB,vCC;vBB >> vCC将结果保存到vAA
ushr-type vAA,vBB,vCC;vBB >> vCC将结果保存到vAA
【Android Dalvik虚拟机好学易用系列】之二:Dalvik汇编语言
原文地址:http://blog.csdn.net/allenwells/article/details/45504335