码迷,mamicode.com
首页 > 其他好文 > 详细

Smali Registers

时间:2015-04-03 00:20:47      阅读:287      评论:0      收藏:0      [点我收藏+]

标签:

 

Smali Registers 


 

介绍Smali中Register相关知识

 

简介

Dalvik字节码中,register(寄存器)一定是32位,它可以用于存放任何类型的值。如果需要存放64位的数据(比如Long和Dobule),则需要两个寄存器。

指定一个方法中寄存器数目

有两种方法可以指定一个方法中用到的寄存器数目。.registers num指令用于指定该方法中用到的寄存器数目,.locals num指令可以指定该方法中非参数寄存器的数目。

参数是如何传递的

当函数被调用时,其参数被存放在最后几个寄存器中。假如一个函数有2个参数a,b,总共有5个寄存器(v0-v4), 那么最后两个寄存器v3和v4用于存放参数a和b

一个非static成员函数的第一个参数总是调用此函数的对象即this对象

例如,LMyObject;->callMe(II)V,callMe有两个参数其类型均为整形,另外他还有一个隐式参数其类型是LMyObject,所以改方法总共有三个参数。

假定此函数有5个寄存器(v0-v4),你可以用指令.registers 5或者.locals 2(2个local寄存器和3个参数寄存器)。当此函数被调用时,第一个参数是调用此函数的对象即this对象被存放在v2,第一个整形参数存放在v3,第二个整形参数存放在v4中。

对于static 成员函数和非static成员函数的差异在于static 成员函数的参数不包含this对象

寄存器命名

寄存器有两种命名形式普通形式vx以及参数寄存器px。P0代表第一个参数。我们现在再回到前面的例子,一个具有三个参数的函数,总共有5个寄存器,下表可以显示普通寄存器和参数寄存器的关系。

 

v0

第一个本地寄存器

v1

第二个本地寄存器

v2

p0

第一个参数寄存器

v3

p1

第二个参数寄存器

v4

p2

第三个参数寄存器

你可以使用任何一种命名方式。

引入参数寄存器命名的动机

参数寄存器引入是为了解决修改smali代码带来的麻烦。

假定你有一个方法具有几个参数,现在你需要增加一些code到此方法中,此时你需要比原来更多的寄存器。或许你认为这没有什么,我可以修改.registers指令增加寄存器个数。

不幸的事,事情并没有那么简单。请记住,函数的参数存放在最后几个寄存中。如果你.register num指令增加函数的寄存器数目,那么参数对应的寄存器编号就发生了改变。所以你在使用 .register num指令增加函数的寄存器数目的同时 必须对参数寄存器重新编号。

但是如果用px方式命名,并且对参数的引用都是用px,则当需要增加寄存器数目的时候,事情就变得简单了,因为p0始终是第一个参数。

注意:baksmali默认使用px方式命名参数寄存器,如果你一定要使用vx方式,你可以使用-p/--no-parameter-registers选项

Long/Double 类型的值

如前所述,long型(J)和double型(D)都是64位,需要两个寄存器来存放其值。当你使用这样的参数的时候请务必记住这一点。例如,有一个非静态成员函数LMyObject;->MyMethod(IJZ)V,此函数的参数是LMyObject;, int, long, bool,一共需要5个寄存器来存放所有的参数。

 

p0

this

p1

I

p2, p3

J

p4

Z

 

另外,以后用invoke-指令调用此方法时,你必须对double-wide参数的两个寄存器都要赋值。

 

原文: https://code.google.com/p/smali/wiki/Registers

Smali Registers

标签:

原文地址:http://blog.csdn.net/free555/article/details/44838971

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!