ARM程序调用规则(ATPCS)分析

研究的是V4版本ARM内核的函数调用规则。

MDK4.2、J-Link armV4.34、J-Link硬件仿真器V8版本。

ATPCS规定寄存器的使用规则如下:
1.子程序通过R0~R3来传递参数

2.子程序使用R4~R11来保存局部变量

3.寄存器R12用作scratch寄存器,记为ip(发现Linux内核中的汇编直接使用ip这个

符号)

4.R13为SP

5.R14为LR

6.R15为PC


截取自己工程中的代码片段:

ARM程序调用规则(ATPCS)分析_第1张图片

这是在函数中调用uartInit()。

可以发现在正式跳转到子函数

BL uartInit

之前还执行了三步操作。

MOV R2,#_...

LDR R1,[PC,#...]

MOV R0,R2

首先第一条执行第一条命令可以获得uartInit函数的第一个参数UART1,但暂时将

参数保存在R2中,最后通过

MOV R0,R2

将第一个参数保存在R0寄存器中。

然后通过LDR执行第二条执行,将第二个参数保存在R1寄存器中。

通过计算可以知道R1中的值是0x4000009c

这个就是程序中定义的cUartArg变量的内存地址

ARM程序调用规则(ATPCS)分析_第2张图片

第三个参数为NULL,所以不用执行。参数保存到R0、R1后开始跳转到子函数执行

ARM程序调用规则(ATPCS)分析_第3张图片

可以发现函数在执行子函数代码之前显示将R4~R6以及R14寄存器保存在栈中,然后再将

R0、R1、R2的值赋值给R4~R6,因为在函数中形参是局部变量,ATPCS规则规定子程序

要使用R4~R11寄存器来保存局部变量,所以这里进行了赋值操作。并且在跳转的时候也将

LR寄存器进行了设置。

所有这些操作完毕然后执行子程序代码。

最后函数的返回值通过R0寄存器进行传递。


当参数大于4个时通过堆栈来传递参数。
更加具体的解释参考杜春雷<ARM体系结构与编程>


你可能感兴趣的:(编程,c,汇编,null,linux内核)