1. 什么是程序计数器

程序计数器:Program Counter(PC),Instruction Pointer(IP),是一个特殊的寄存器(register),用来存放 CPU 下一个将要执行指令的内存地址(Memory Address),注意它的功能是用来取得程序执行指令内存地址,并不是数据内存地址。

一般情况下,当系统重启后,PC 置为0,然后随着系统进程的运行,不断的开始计数。具体的,以一个系统进程为例,PC 开始初始化为0,(我们知道一个指令如果太长的话就会将它切为几段来放置在内存中)。

  • 开始 CPU 获取了 PC=0000H 这个内存地址的指令,同时 PC++,即存储下一条指令的地址。注意,我们唐常说的 PC 加1,其实是让 PC 增加为下一条指令的地址,并不是这个 PC 当前的地址加1,比如一个内存单元占用4个位,0x04,则如果当前 PC=0x40060, 则PC++ 意味着 0x40064
  • 判断机制判断此时这个指令知否完整
    • 若是不完整,则获取 PC 当前指向的内存地址的指令,且让 PC 加1(意味着 PC指向下一个内存地址),直到判断指令已经完整了。
    • 如果指令已经完整了,则对指令解码,
      • 如果指令中有要跳转的语句或分支、子程序,如条件句,函数,(如果是函数,需要保存当前PC 的状态,等函数运行结束后返回这个 PC状态),准备工作做完后则立刻设定 PC 为下一个要跳转过去的指令内存地址,接下来继续Fetch 后续的步骤。
      • 如果没有跳转的指令,意味着程序将会继续顺序执行,那么 CPU 将获取当前的 PC 指向的内存指令,并将 PC++。
  • 当一个指令(或许由好几个内存地址才能存下)完整获取后,PC 将进行下一步动作 或许继续加一获取 或许跳转到其他地址。

这样看来,由于程序指令是有顺序的,一般从上向下执行,遇到特殊指令会变化,则程序计数器一般总是加1让 CPU 获取顺序化的下一条指令;当有特殊指令,PC 会立刻变化,CPU 按照 PC 的变化后的内容获取指令。

2. 些许想法

  • 32位系统的最大内存地址是 232位,4G,其中部分给数据内存,部分给指令内存,由此即便有8G 的物理内存,4G 之外的不能被访问到。
  • CPU 对数据内存和指令内存 中数据和指令的获取方式不一样
    数据和指令都存在内存中,但是存储的区域不一样,访问的方式也不一样。数据内存的地址总是开始于某个地址,指令内存的地址总是开始于另一个地址,且不会有交集;另外,数据内存中的数据必须经过寄存器再到算数逻辑单元 ALU,指令内存中的指令可以直接倒 ALU 解码。

3. 参考

https://www.quora.com/What-is-the-difference-between-program-and-data-memory
https://stackoverflow.com/questions/10876372/difference-between-memory-address-registermar-and-program-counterpc
https://www.youtube.com/watch?v=ccf9ngGIb8c&t=333s
https://en.wikipedia.org/wiki/Program_counter
https://en.wikibooks.org/wiki/Microprocessor_Design/Program_Counter
https://www.quora.com/What-is-program-counter-and-its-role
https://blog.csdn.net/abcjennifer/article/details/5529647
http://p8gbnxign.bkt.clouddn.com/ProgramCounter.pdf