1. 程式人生 > 其它 >[轉]smali語言之locals和registers的區別

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