SP:堆栈指针寄存器-R13
用于异常模式时保护现场和恢复现场
LR:链接寄存器-R14
用于保存子程序返回地址
PC:程序计数器-R15
指向当前正在“取指”的指令。
指令分为三个阶段执行:1.取指(从存储器装载一条指令);2.译码(识别将要被执行的指令);3.执行(处理指令并将结果写回寄存器)。人们习惯性约定 将“正在执行的指令作为参考点”,称之为当前第一条指令,因此PC总是指向第三条指令,即第一条指令为当前“执行”的指令——>第二条(下一条要执行的)指令为正在“译码”的指令——>第三条指令为正在“取指”的指令,也就是PC指向的地方。
举例分析:
1.进入HAL_GPIO_Init函数之前LR = 0x2400F961 PC = 0x2400F970
2.进入HAL_GPIO_Init函数之时LR = 0x2400F979 PC = 0x24008954
3.退出HAL_GPIO_Init函数时LR = 0x2400F979 PC = 0x2400F978
案例汇总:
1.进入HAL_GPIO_Init函数之前LR = 0x2400F961 PC = 0x2400F970
2.进入HAL_GPIO_Init函数之时LR = 0x2400F979 PC = 0x24008954
3.退出HAL_GPIO_Init函数时LR = 0x2400F979 PC = 0x2400F978
进入函数时LR保存子程序返回地址LR = 0x2400F979,而PC = 0x24008954;退出函数时子程序返回地址LR = 0x2400F979被复制到PC,因此PC(指向当前正在取指的指令)变为PC = 0x2400F978,如此程序执行完子程序后实现返回。(可以看到LR一直是“基数”,至于PC为什么会比LR少1未做具体研究,期待大佬解答......)
细心的你可能已经发现了,在这过程中SP:堆栈指针寄存器-R13为什么一直没有变化 ?因为SP堆栈指针一般用于异常模式(中断)。当系统进入异常模式时,程序会把一般寄存器压入到SP堆栈中(所谓保护现场),当异常模式退出后,一般寄存器的值再出栈(所谓恢复现场),如此即可保证程序在异常和非异常模式下的状态的完整性。
参考:ARM中SP、LR、PC三个寄存器介绍_sp lr pc-CSDN博客
(PS:仅作为学习笔记,如有错误欢迎指正......)