smali 变量

2017-12-25  本文已影响0人  一江碎月

基础

Android 的变量都存储于寄存器中。变量分为 v 与 p 两种格式

  1. v 变量表示方法中非参数变量。

  2. p 变量表示方法中参数变量。

    • 如果方法是非静态方法,p0 表示 this

    • 如果方法是静态方法,p0 表示第一个参数。

  3. 寄存器都是 32 位。因此, double 与 long 类型的变量会占据两个寄存器,它们在存储时会使用两个连续的寄存器。

    private void test(int x){
        long a = 10000L;
        int b = 2;
    }
    

    该方法需要的 5 个寄存器。参数需要两个,变量 b 需要一个,变量 a 需要两个。

    变量 a 会使用 v0 和 v1 两个寄存器。变量 b 使用 v2 。

  4. boolean 类型的变量会被存储成 0 或 1 。其中 1 表示真,0 表示假。

表示

Lcom/demo/adapter/MainActivity;->test:Ljava/lang/String;

表示 MainActivity 类中的 String 类型的 test 变量。

类型

.registers : 声明在方法第一行,表示该方法使用到的寄存器的个数

.param : 表示该变量为参数变量

.local : 表示方法中非参数的变量

.field : 全局变量


赋值

  1. const-class vx,type_id : Class 对象赋值。 将 type_id 对应的类的 Class 对象赋值给 vx。

  2. 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 位。

整数赋值

  1. const/4 vx,lit4 : 将 4 位的常量赋值给 vx。也就是说 vx 的最大值是 15。

  2. const/16 vx,lit16:将 16 位的常量赋值给 vx

    • const-wide/16 vx, lit16 表示将一个 16 位的常量存储到 vx 与 vx+1 两个寄存器中 —— 即一个 long 类型的数据。
  3. const vx, lit32:将 32 位的常量赋值给 vx

    • const-wide/32 vx, lit32 表示将一个 32 位的常量存储到 vx 与 vx+1 两个寄存器中 —— 即一个 long 类型的数据。
  4. const-wide vx, lit64 : 将一个 64 位的数据存储到 vx 与 vx+1 两个寄存器中

  5. / 后的数值表示数值本身是多少位,由 const 与 const-wide 区分变量占多少位。

有些命令中,数值本身位数较低,而寄存器的位数较高。因此将数值填充到寄存器时,需要对数值进行扩展,该过程所进行的扩展都是 符号扩展 —— 根据原始数值的符号位决定对数值的高位补 0 还是补 1(如果数值为负数,则高位补 1 ;如果为正数,则高位补 0)

浮点数

参考官方链接

  1. const/high16 v0, lit16:将给定的 16 位常量(右零扩展为 32 位)移到指定的寄存器中

  2. const-wide/high16 vx,lit16:将 16 位常量右零扩展为 64 位后填充到 vx 和 vx + 1 寄存器中。 用于初始化双精度值

  3. 对于 float 数值,除第一个命令外,还使用 const vx,lit32 形式进行赋值。因为 float 是 32 位。

  4. 对于 double ,除第二个命令外,还可以使用 const-wide vx,lit64 形式进行赋值。

上一篇下一篇

猜你喜欢

热点阅读