zoukankan      html  css  js  c++  java
  • [转]smali语言之locals和registers的区别

    https://www.imgeek.org/article/825358911

    介绍

    对于dalviks字节码寄存器都是32位的,它能够表示任何类型,2个寄存器用于表示64位的类型(Long and Double)。

    作用

    声明于方法内部(必须)

    .method public getName()V
    .registers 6

    return-void
    .end method

    .registers和locals基本区别

    在一个方法(method)中有两中方式指定有多少个可用的寄存器。指令.registers指令指定了在这个方法中有多少个可用的寄存器,

    指令.locals指明了在这个方法中非参(non-parameter)寄存器的数量。然而寄存器的总数也包括保存方法参数的寄存器。

    参数是如何传递的?

    1.如果是非静态方法

    例如,你写了一个非静态方法LMyObject;->callMe(II)V。这个方法有2个int参数,但在这两个整型参数前面还有一个隐藏的参数LMyObject;也就是当前对象的引用,所以这个方法总共有3个参数。 假如在一个方法中包含了五个寄存器(V0-V4),如下:

    .method public callMe(II)V
    const-string v0,"1"
    const-string v1,"1"

    return-void
    .end method

    那么只需用.register指令指定5个,或者使用.locals指令指定2个(2个local寄存器+3个参数寄存器)。如下:

    .method public callMe(II)V
    .registers 5
    const-string v0,"1"
    const-string v1,"1"
    v3==>p0
    V4==>P1
    V5==>P2

    return-void
    .end method

    或者
    .method public callMe(II)V
    .locals 2
    const-string v0,"1"
    const-string v1,"1"
    return-void
    .end method

    该方法被调用的时候,调用方法的对象(即this引用)会保存在V2中,第一个参数在V3中,第二个参数在v4中。

    2.如果是静态方法

    那么参数少了对象引用,除此之外和非静态原理相同,registers为4 locals依然是2

    关于寄存器命名规则

    v命名法

    上面的例子中我们使用的是v命名法,也就是在本地寄存器后面依次添加参数寄存器,

    但是这种命名方式存在一种问题:假如我后期想要修改方法体的内容,涉及到增加或者删除寄存器,由于v命名法需要排序的局限性,那么会造成大量代码的改动,有没有一种办法让我们只改动registers或者locals的值就可以了呢, 答案是:有的

    除v命名法之外,还有一种命名法叫做p命名法

    p命名法

    p命名法只能给方法参数命名,不能给本地变量命名

    假如有一个非静态方法如下:

    .method public print(Ljava/lang/String;Ljava/lang/String;I)V

    以下是p命名法参数对应表:

    p0
    this

    p1
    第一个参数Ljava/lang/String;

    p2
    第二个参数Ljava/lang/String;

    p3
    第三个参数I

    如前面提到的,long和double类型都是64位,需要2个寄存器。当你引用参数的时候一定要记住,例如:你有一个非静态方法

    LMyObject;->MyMethod(IJZ)V

    方法的参数为int、long、bool。所以这个方法的所有参数需要5个寄存器。

    p0
    this

    p1
    I

    p2, p3
    J

    p4
    Z

    另外当你调用方法后,你必须在寄存器列表,调用指令中指明,两个寄存器保存了double-wide宽度的参数。

    注意:在默认的baksmali中,参数寄存器将使用P命名方式,如果出于某种原因你要禁用P命名方式,而要强制使用V命名方式,应当使用-p/--no-parameter-registers选项。

    总结

    • locals和registers都可以表示寄存器数量,locals指定本地局部变量寄存器个数,registers是locals和参数寄存器数量的总数,两者使用任选其一
    • 同时,寄存器命名一共分两种,一种是v命名法,另一种是p命名法

    v0
    the first local register

    v1
    the second local register

    v2
    p0
    the first parameter register

    v3
    p1
    the second parameter register

    v4
    p2
    the third parameter register

  • 相关阅读:
    【项目】项目17
    【项目】项目16
    【项目】项目15
    【项目】项目14
    【项目】项目13
    【项目】项目12
    【项目】项目11
    【项目】项目10
    【项目】项目9
    【项目】项目8
  • 原文地址:https://www.cnblogs.com/beansoft/p/15495922.html
Copyright © 2011-2022 走看看