转载:https://blog.csdn.net/chun_1959/article/details/46604979
一、ARM寄存器:
寄存器类别 | 寄存器在汇编中的名称 | 各模式下实际访问的寄存器 | ||||||
用户 | 系统 | 管理 | 中止 | 未定义 | 中断 | 快中断 | ||
通用寄存器和程序计数器 | R0(a1) | R0 | ||||||
R1(a2) | R1 | |||||||
R2(a3) | R2 | |||||||
R3(a4) | R3 | |||||||
R4(v1) | R4 | |||||||
R5(v2) | R5 | |||||||
R6(v3) | R6 | |||||||
R7(v4) | R7 | |||||||
R8(v5) | R8 | R8_fiq | ||||||
R9(SB,v6) | R9 | R9_fiq | ||||||
R10(SL,v7) | R10 | R10_fiq | ||||||
R11(FP,v8) | R11 | R11_fiq | ||||||
R12(IP) | R12 | R12_fiq | ||||||
R13(SP) | R13 | R13_svc | R13_abt | R13_und | R13_irq | R13_fiq | ||
R14(LR) | R14 | R14_svc | R14_abt | R14_und | R14_irq | R14_fiq | ||
R15(PC) | R15 | |||||||
状态寄存器 | CPSR | CPSR | ||||||
SPSR | 无 | SPSR_abt | SPSR_abt | SPSR_und | SPSR_irq | SPSR_fiq |
其中ARM汇编器对ARM的寄存器进行了预定义,所有的寄存器和协处理器名都是大小写敏感的.预定义的寄存器如下:
1,Ro-R15和r0-r15
2,a1-a4(参数,结果或者临时寄存器,与r0-r3同意)
3,v1-v8(变量寄存器,与r4-r11同意)
4,sb和SB(静态基址寄存器,与r9同意)
5,sl和SL(堆栈限制寄存器,与r10同意)
6,fp和FP(帧指针,与r11同意)
7,ip和IP(过程调用中间临时寄存器,与r12同意)
8,sp和SP(堆栈指针,与r13同意)
9,lr和LR(连接寄存器,与r14同意)
10,pc和PC(程序计数器,与r15同意)
11,cpsr和CPSR(程序状态寄存器)
12,spsr和SPSR(程序状态寄存器)
13,f0-f7和F0-F7(FPA寄存器)
14,s0-s31和S0-S31(VFP单精度寄存器)
15,d0-d15和D0-D15(VFP双精度寄存器)
16,p0-p15(协处理器0-15)
17,c0-c15(协处理器寄存器0-15)
二、stack frame
stack我们都知道,每一个进程都有自己的栈。考虑进程执行时发生函数调用的场景,母函数和子函数使用的是同一个栈,在通常的情况下,我们并不需要区分母函数和子函数分别使用了栈的哪个部分。但是,当我们需要在执行过程中对函数调用进行backtrace的时候,这一信息就很重要了。
简单的说,stack frame就是一个函数所使用的stack的一部分,所有函数的stack frame串起来就组成了一个完整的栈。stack frame的两个边界分别由FP和SP来限定。
ARM架构中使用R12作为子程序间的scratch寄存器 (ATPCS中规定)。
可以将R12 用于保存SP,在函数返回时使用该寄存器出栈,记作ip。
或者又比如:
Uboot程序中主程序调用 cpu_init_crit函数,在这个cpu_init_crit函数中有下面的代码:
mov ip, lr
bl lowlevel_init
mov lr, ip
mov pc, lr
这个代码在调用lowlevel_init函数之前,先将lr存储在R12,之后在lowlevel_init函数调用返回之后使用mov lr,ip将之前保存的返回地址再一次存储到lr寄存器。
参考文献:
http://blog.csdn.net/scyangzhu/article/details/8018761
http://blog.csdn.net/fengyee_zju/article/details/8026490