前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >smali语言之locals和registers的区别

smali语言之locals和registers的区别

作者头像
乱码三千
发布2021-08-24 15:14:08
1.2K0
发布2021-08-24 15:14:08
举报
文章被收录于专栏:乱码三千乱码三千

介绍

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

作用

声明于方法内部(必须)

代码语言:javascript
复制
.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),如下:

代码语言:javascript
复制
.method public callMe(II)V
 	const-string v0,"1"
    const-string v1,"1"
 
   return-void
.end method

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

代码语言:javascript
复制
.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命名法只能给方法参数命名,不能给本地变量命名

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

代码语言:javascript
复制
.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个寄存器。当你引用参数的时候一定要记住,例如:你有一个非静态方法

代码语言:javascript
复制
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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 乱码三千 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 作用
  • .registers和locals基本区别
  • 参数是如何传递的?
    • 1.如果是非静态方法
      • 2.如果是静态方法
      • 关于寄存器命名规则
        • v命名法
          • p命名法
          • 总结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档