[轉]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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM