本文基于Android 7.1,不过因为从BSP拿到的版本略有区别,所以本文提到的源码未必与读者找到的源码完全一致。本文在提供源码片断时,将按照 <源码相对android工程的路径>:<行号> <类名> <函数名> 的方式,如果行号对不上,请参考类名和函数名来找到对应的源码。
可以参考我之前写过的文章:http://blog.csdn.net/doon/article/details/51691627
理解dex文件的基本格式
理解dex指令特点
要理解dex文件,首先要dex的指令特点。dex被称为是基于寄存器的虚拟机指令。这里的寄存器,不是指物理寄存器,而是指虚拟机虚拟出的寄存器。而且不同于有我们熟悉的编译性语言(如C/C++),dex指令在运行时,只需要寄存器,不需要堆栈。dex指令有如下特点:
- 一个函数拥有一组独立的寄存器 将每个函数的寄存器数量是不固定的,标记为V0~Vn-1,最多可以有65535个
- 一个函数的虚拟寄存器可以划分为三部分:
- 自变量区:保存的是函数内部用到的自变量
- 参数输入区:保存的是输入的参数值
- 输出参数区:被用于保存被调用函数的参数。因为输出参数区只用作参数输出,所以在虚拟机实现的时候,通常把调用函数的输出参数区与被调用函数的输入参数区重叠。
- 假设一个函数有M个参数,那么参数将占据 Vn-m ~ Vn-1,剩余部分将被内部变量占据
- 假如一个函数有自变量a,b,且a,b的作用域不重叠,那么它们可以占据同一个寄存器Vi
如下图:
字符串池
字符串在java和dex中都是非常重要的。不仅在编程中包含大量的常量字符,而且,java的类名、方法名、成员名等都是以字符串的形式保存下来的。
那么,字符串在dex中如何存储呢?了解java class文件结构的朋友一定也听说过,在class文件中有一个字符串池,保存了源码中存在的各种字符串以及各种名称。同样的,在dex文件中,也可以看到这样的