目录
内核
MCU(嵌入式微控制器)中的运算器和控制器合称为内核。
内核指令执行分为几步
① 将指令(程序)从存储器里读取出来,这一阶段称为取指(Instruction Fetch,IF Stage)
②搞清楚指令是做什么的,清楚指令要求内核做什么事情,具体包括搞清楚指令会用到哪些内核寄存器,是普通的数值运算还是对总线进行读取等等,这一阶段被称为指令解码(Instruction Decoding,ID Stage)
③ 执行指令要求的动作,比如进行数值运算或者存储器读写等等,这一阶段称为执行(Execution,EX)
EX阶段所做的事情主要分为两大类:数据的存取和数据的运算
数据存取
1)从外部存储器读取数据到内核寄存器——————(涉及针对总线(BUS)的“主动”访问)
2)将内核寄存器的数据写回外部存储器——————(涉及针对总线(BUS)的“主动”访问)
3)在内核寄存器之间进行数据的拷贝和移动——————(内核内部的操作)
数据运算
其功能的核心就是运算器,又被称为数字逻辑运算单元(ALU),本质上说,他是一个非常低级的计算器,只会做一些整数的加减法、逻辑与或非运算和非常呆板的运算。
函数调用是怎么实现的?
原理上,可以借助栈来实现函数返回地址的保存,具体步骤如下:
- 将返回点的地址压栈
- 修改PC指针,跳转到目标地址执行
- 返回时,直接将返回地址从栈中弹出到PC指针,实现函数的返回
内核对叶子函数的调用过程
- 将返回点的地址放入LR中(这是由跳转指令自动完成的)
- 修改PC指针,跳转到目标地址执行(这实际上也是同一条跳转指令完成的)
- 返回时,直接将LR的值赋值给到PC指针,实现函数的返回
针对非叶子函数的,更为通用的过程
- 将当前LR的值压栈
- 将返回点的地址放入LR中(这是由跳转指令自动完成的)
- 修改PC指针,跳转到目标地址执行(这实际上也是同一条跳转指令完成的)
- 返回时,直接将LR的值赋值给到PC指针,实现函数的返回
- 将先前保存在栈中的LR值出栈
中断/异常处理程序是如何得到执行的
- 将当前“返回点的地址”和LR的值进行压栈处理(内核自动完成)
- 将“退出令牌(EXC_RETURN)”放入LR中(内核自动完成)
- 修改PC指针,跳转到中断/异常处理程序的首地址处执行(内核自动完成);需要注意,中断处理程序中实现的函数调用仍然遵循普通的函数调用方法,并无特殊处理。
- 返回时,直接将LR的值赋值给到PC指针,由于当前LR内保存的是”退出令牌(EXC_RETURN)“,触发内核中断/异常处理模式(内核自动完成)
- 将先前保存在栈中的LR值和“返回点地址”出栈,其中“返回点地址”被弹出到PC指针中,从先前的中断点继续执行(内核自动完成)
计算器的使用
Windows自带简易
- 输入第一个操作数
- 选择所要做的运算
- 输入第二个操作数
- 单机等于号按钮“=”,获得结果
ALU的操作步骤
- 告诉ALU分别从哪两个内核寄存器中获取两个操作数
- 告诉ALU运算结果放到哪个内核寄存器中
- 选择所要做的运算
- 告诉ALU执行运算(相当于按下“=”),ALU会将运算结果输出到事先约定好的内核寄存器中去
通用寄存器的接口作用
习惯上,我们把ALU可以直接访问的寄存器称之为“通用寄存器”,这些通用寄存器在一起形成的集合,称之为“寄存器页”。
寄存器页是算数逻辑单元与外部地址空间进行数据交换的唯一接口。
寄存器页里保存了什么
通用寄存器Rn
栈顶指针SP
程序计数器PC
链接寄存器LR
内核状态寄存器SR