基础
Android 的变量都存储于寄存器中。变量分为 v 与 p 两种格式
v 变量表示方法中非参数变量。
-
p 变量表示方法中参数变量。
如果方法是非静态方法,p0 表示 this
如果方法是静态方法,p0 表示第一个参数。
-
寄存器都是 32 位。因此, double 与 long 类型的变量会占据两个寄存器,它们在存储时会使用两个连续的寄存器。
private void test(int x){ long a = 10000L; int b = 2; }
该方法需要的 5 个寄存器。参数需要两个,变量 b 需要一个,变量 a 需要两个。
变量 a 会使用 v0 和 v1 两个寄存器。变量 b 使用 v2 。
boolean 类型的变量会被存储成 0 或 1 。其中 1 表示真,0 表示假。
表示
Lcom/demo/adapter/MainActivity;->test:Ljava/lang/String;
表示 MainActivity 类中的 String 类型的 test 变量。
类型
.registers : 声明在方法第一行,表示该方法使用到的寄存器的个数
.param : 表示该变量为参数变量
.local : 表示方法中非参数的变量
.field : 全局变量
赋值
const-class vx,type_id : Class 对象赋值。 将 type_id 对应的类的 Class 对象赋值给 vx。
-
const-string vx,string_id: 字符串赋值。将 string_id 指向的字符串赋值给 vx。
string_id 也可以直接替换成具体的 String。此时表示将 String 赋值给 vx。
除 const-string 外,还有 const-string/jumbo,它与 const-string 一样,只不过它支持的字符串引用数更大。
数字赋值
赋值时,命令有 const 与 const-wide 两种。其中 const 表示该变量为 32 位,const-wide 表示该变量为 64 位。
整数赋值
const/4 vx,lit4 : 将 4 位的常量赋值给 vx。也就是说 vx 的最大值是 15。
-
const/16 vx,lit16:将 16 位的常量赋值给 vx。
- const-wide/16 vx, lit16 表示将一个 16 位的常量存储到 vx 与 vx+1 两个寄存器中 —— 即一个 long 类型的数据。
-
const vx, lit32:将 32 位的常量赋值给 vx。
- const-wide/32 vx, lit32 表示将一个 32 位的常量存储到 vx 与 vx+1 两个寄存器中 —— 即一个 long 类型的数据。
const-wide vx, lit64 : 将一个 64 位的数据存储到 vx 与 vx+1 两个寄存器中
/ 后的数值表示数值本身是多少位,由 const 与 const-wide 区分变量占多少位。
有些命令中,数值本身位数较低,而寄存器的位数较高。因此将数值填充到寄存器时,需要对数值进行扩展,该过程所进行的扩展都是 符号扩展 —— 根据原始数值的符号位决定对数值的高位补 0 还是补 1(如果数值为负数,则高位补 1 ;如果为正数,则高位补 0)
浮点数
参考官方链接
const/high16 v0, lit16:将给定的 16 位常量(右零扩展为 32 位)移到指定的寄存器中。
const-wide/high16 vx,lit16:将 16 位常量右零扩展为 64 位后填充到 vx 和 vx + 1 寄存器中。 用于初始化双精度值。
对于 float 数值,除第一个命令外,还使用 const vx,lit32 形式进行赋值。因为 float 是 32 位。
对于 double ,除第二个命令外,还可以使用 const-wide vx,lit64 形式进行赋值。