1 寄存器的分类
CPU寄存器(通用寄存器)
通用寄存器(ARM中有37个)是CPU的组成部分,CPU的很多活动都需要通用寄存器的支持和参与。
- 专用指令执行、数据运算、变量处理、参数传递
外设寄存器(SFR)
SFR(special function register,特殊功能寄存器)不在CPU中,而存在于CPU的外设中,我们通过访问外设的SFR来编程操控这个外设,这就是硬件编程控制的方法。
- 用于控制外设的行为和工作方式
- 寄存器值的配置需要根据芯片手册完成
对于外设寄存器来说:
寄存器属于CPU外设的硬件组成部分。
CPU可以像访问内存一样访问寄存器。
寄存器是CPU的硬件设计者制定的,目的是留作外设被编程控制的“活动开关”。
正如汇编指令集是CPU的编程接口API一样,寄存器是外设硬件的软件编程接口API。使用软件编程控制某一硬件,其实就是编程读写该硬件的寄存器。
编程操作寄存器类似于访问内存。
寄存器中每个bit位都有特定含义,因此编程操作时需要位操作。
单个寄存器的位宽一般和CPU的位宽一样,以实现最佳访问效率。
编程访问寄存器的方法
汇编方式:
ldr r1, =0xE0200280
str r0, [r1]
mov r0, #0
C语言方式:
int p = (int )0x30008000;
*p = 16;
2 处理器中的关键寄存器
PC - 程序计数器(指令指针 IP)
- 每执行一条指令,PC中的值就会发生变化
- PC时钟保存下一条CPU要执行的指令地址
SP - 栈指针(Stack Pointer)
- 始终指向栈空间的顶端,实现LIFO特性
- 保存中断断点、保存函数调用返回点、保存CPU现场数据等
PC 和 SP的使用案例 - 函数调用
函数调用相关的寄存器
函数调用栈信息
如上为linux系统的栈帧,window系统下的栈帧与linux系统下的栈帧略有差异:被调用保存的寄存器信息linux系统下位于old ebp下面,windows系统下则位于局部变量下。如下举例为windows系统。
函数调用相关汇编代码(intel格式)
// C代码
#include <stdio.h>
void first(int a);
void second(int a);
int main(void)
{
first(10);
return 0;
}
void first(int a)
{
printf("a = %d\n", a);
a = 100;
second(a);
}
void second(int a)
{
printf("a = %d\n", a);
}
// C代码对应的汇编代码
void first(int a)
{
00A613D0 push ebp
00A613D1 mov ebp,esp
00A613D3 sub esp,0C0h
00A613D9 push ebx
00A613DA push esi
00A613DB push edi
00A613DC lea edi,[ebp-0C0h]
00A613E2 mov ecx,30h