从CPU说起
从CPU说起
最近以来,有感于接收的信息越来越零碎,越来越杂,不成体系,打算从开始理顺逻辑,囿于认知水平以及掌握的知识,难免有错误。
- CPU
一个典型系统的的硬件组成可由下图给出:
对于CPU来说,核心是PC寄存器(Program Counter,
程序计数器),其指向主存中的某条机器语言指令,寄存器文件中还包含其他寄存器,一般都用于传送数据以及算术逻辑运算。
对于典型的8086来说,寄存器文件包含16个通用寄存器,其中比较重要的有CS(Code Segment,代码段寄存器)、DS(Data Segment,数据段寄存器)以及IP(Instruction Pointer,指令指针寄存器),代码段与数据段以及附加段的概念是针对内存分段来说,程序在编译时,编译器会进行内存地址分配,CS与IP一起配合来完成CPU的指令寻址,进而完成指令解码以及执行,CS指向代码段的基地址,IP指向当前指令相对于基址的偏移地址。
对于ARM系列的Cortex-M3来说,其CPU组成如下:
共有R0-R15共16个寄存器,其中R0-R12都是通用寄存器(General-Purpose Register),用于操作数据,R13是堆栈寄存器,包含MSP(Main Stack Pointer,主堆栈指针)以及PSP(Process Stack Pointer,进程堆栈指针),但任一时刻只能选择使用一个,R14,链接寄存器(link register)用于保存调用子程序时的返回地址。
R15就是程序计数寄存器PC,指向当前执行的程序的地址。
一般,CPU在指令的要求下可能会执行以下操作:
加载:把一个字节或者字从主存复制到寄存器,以覆盖寄存器原来的内容;
存储:把一个字节或字从寄存器复制到主存的某个位置,以覆盖这个位置上原来的内容;
操作:把两个寄存器的内容复制到ALU,ALU对这两个字进行算术操作,同时将结果存放到一个寄存器;
跳转:从指令本身抽取一个字,并把这个字复制到程序计数器(PC)中,以覆盖原来的内容,实现程序跳转;
而不同的指令集描述了每条机器代码指令的效果,即如何实现上述四种操作。
在每次上电开始运行时,都要将部分或者全部的数据段以及代码段等内容从flash闪存或者rom中搬运到ram中,以供CPU读取数据与指令,从而完成程序执行,但在加电的瞬间,ram中空空如也,要实现程序的运行,就要靠引导程序。
在8086系列的CPU中,都是通过硬件设计来实现BIOS程序的跳转,即将CPU硬件逻辑设计为加电瞬间强行将CS、IP的值设置为某个特定值,从而完成程序跳转;
对于Cortex-M3来说,则要靠启动文件startup_xxxx.s,其全由汇编语言编写完成,主要完成设置CPU状态、关闭写缓冲和Cache、初始化内存控制器、设置CPU运行时钟、创建堆栈等,最后跳转到c语言中的Main函数;
上图为某启动文件的描述。可以看出,将PC初始化设置为Reset_Handler的入口地址,在最后一步操作中,跳转到main()函数。
- 总线、指令与流水线
- 存储设备以及缓存
- 编译、链接、库
受限于知识水平,难免有错误,见谅.