Dalvik指令概述
书里写的实在是太差了。自己稍微总结一下。
字节码表示方式 Bytecode
位描述 Bitwise description
用于表示指令二进制码的数据布局。
[A|G|op BBBB F|E|D|C]
-
一个字母代表4bit数据(一发十六进制)
-
op表示8bit操作码(一个字节byte,两发十六进制)
-
Ø表示指令中此位必须为零
-
每16位一个空格(一个字word)
-
竖线分隔不同的数据
指令格式标识 Format IDs
用于表示指令的长度、参数类型。
N N a [s/i]
额外数据类型:
语法
用位描述和格式标示定义的,给人看的(human-oriented)指令语法。
op vAA, string@BBBB
-
逗号分隔参数
-
指令类型 op 为第一个word的low byte。高八位可以为参数,可以为空
-
vX 为寄存器,几个X就是寄存器标号(地址)大小
-
#+X 常量
-
+X 为相对(当前指令)的地址偏移量
-
@X 为常量池索引。 kind=[string, type, field, meth, site] site=call site
寄存器命名法
令函数foo()使用了M个寄存器,有N个参数。
指令列表
以下表格包含所有指令的列表。
原文:https://source.android.com/devices/tech/dalvik/dalvik-bytecode.html#instructions
以上表格的第一列的第二部分指令格式ID,对应的(给人看的)指令数据布局列表,见
原文:https://source.android.com/devices/tech/dalvik/instruction-formats.html#formats
第二个表格不用记,用的时候查表格就是了。
实现
-
dalvik.bytecode.Opcodes接口定义完整字节码列表。
-
源码位于 libcore/dalvik/src/main/java/dalvik/bytecode/Opcodes.java
-
dalvik/opcode-gen/bytecode.txt 用于生成以上接口的指令集
-
kitkat版本及以下的安卓源码,可在dalvik/vm/mterp/c找到指令实现
-
lollipop及以上版本,可在 art/runtime/interpreter/mterp/[arch] 下找到对应指令实现(汇编)
-
以kitcat的 OP_MOVE.cpp 为例。
INST_A宏:获取指令高八位的低4位。
INST_B:获取高八位的高4位。
GET_REGISTER:存值
fp[]:栈帧寄存器,函数的局部变量区,存储所有寄存器值。其索引为寄存器编号。
FINISH:调整PC寄存器,移动至此条指令后。
底层架构
-
部分寄存器映射到CPU寄存器,部分由调用栈模拟。
-
寄存器全部为32位,64位数据由相邻两个寄存器表示。
-
寄存器编号 v0-v65535,因为操作符为16位(v0000-vFFFF)
- 大部分函数使用的寄存器少于16个,因此16以下的寄存器,编号小于1字节,对应特殊指令(速度更快?)
-
寄存器个数在函数被调用、分配调用栈时预留对应空间,于函数头由 .register 指令指定。