首页 > 代码库 > arm上的参数列表传递的分析(以android为例)
arm上的参数列表传递的分析(以android为例)
对于pc上的可变参数列表,比较容易理解:参数全部存储在栈上。所以:va_list p定义一个指针,va_start(p, arg_a)获取参数列表地址,该地址就是va_start第二个参数对应数据之后的地址,,在栈上表现为:arg_a+sizeof(arg_a). 此后根据参数类型,使用va_arg依次从指定的参数列表地址取数据。
但时对于arm上,一个会使用寄存器传递参数的平台,又回怎样处理的呢?
通过写一个简单的示例程序:
int test(int a, ...){ va_list p; va_start(p, a); printf("%d", va_arg(p, int)); va_end(p); }
实际编译后如下:
.text:00000BE0 ; test(int, ...).text:00000BE0 EXPORT _Z4testiz.text:00000BE0 _Z4testiz ; CODE XREF: main+8p.text:00000BE0.text:00000BE0 var_1C = -0x1C.text:00000BE0 varg_r0 = -0x10.text:00000BE0 varg_r1 = -0xC.text:00000BE0 varg_r2 = -8.text:00000BE0 varg_r3 = -4.text:00000BE0.text:00000BE0 PUSH {R0-R3}.text:00000BE2 PUSH {R0-R2,LR}.text:00000BE4 LDR R0, =(unk_2168 - 0xBEE).text:00000BE6 ADD R3, SP, #0x20+varg_r2.text:00000BE8 LDR R1, [SP,#0x20+varg_r1].text:00000BEA ADD R0, PC ; format.text:00000BEC STR R3, [SP,#0x20+var_1C].text:00000BEE BLX printf.text:00000BF2 ADD SP, SP, #0xC.text:00000BF4 POP {R3}.text:00000BF6 ADD SP, SP, #0x10.text:00000BF8 BX R3.text:00000BF8 ; End of function test(int,...)
可以看到粗体部分,进行了2次push。而有所了解得程序员,我们知道一般只会push一次,即后面的那一个——用来保存寄存器状态和返回地址。
那么第一次是干什么呢?显然这和可变参数有关!
arm上使用寄存器传递参数时一般只是用r0~r3,因此,系统直接将其压入栈中!然后和一般函数一样的方式去保护可能会被覆盖的寄存器的状态。
将r0~r3压入栈中之后,如果还有更多的参数,则之前必须(应当)已经压入栈中,那么此时的状态就和pc上的类似了。如下所示
(高地址)
...
arg_5
arg_4
arg_3<---r3
arg_2<---r2
arg_1<---r1
arg_0<---r0
<需要保护的寄存器值>
...
(低地址)
arm上的参数列表传递的分析(以android为例)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。