请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于程序计数器和指令缓存?

3.10这一课的图片讲解中,提到了程序计数器存储着下一条指令的地址,然后这个地址对应的指令会传到指令寄存器中,这个可以理解。但是我理解指令缓存也就是高速缓存,程序计数器中的地址也就代表着下一条指令所代表的地址,然后去高速缓存或者主存中获取指令。那么两个问题

  1. 程序计数器是如何知道下一条指令存在了哪个地址呢?还是说新的要执行的指令是依次存放在某个固定的内存位置,计数器只需要依次往后查看就可以了?
  2. 按道理大部分情况下,程序计数器只做地址+1,那计数器中的位数应该是有限的吧,达到这个最大值之后会怎么样?

正在回答 回答被采纳积分+3

2回答

从零开始的工程师 2020-01-15 00:34:53

以C语言举例,C语言编译时,会把汇编后生成的汇编代码和一份runtime(运行时)汇编代码链接在一起。runtime代码的工作,就是指定程序的入口地址(_main)和退出地址以及一系列的初始化操作。最终组成可执行文件

执行可执行文件时,操作系统会把可执行文件的内容加载到一片连续内存里去,然后跳转到该内存中代码段的第一条指令执行,即runtime代码的第一条机器指令。而这个跳转操作一般就是直接给程序计数器赋对应的地址值。然后就开始往下走了,每一个指令周期,指令计数器进行自增(除非遇到跳转、返回等写程序计数器的操作)。一般不会存在程序计数器自增到内存末尾还没跳转的,如果有,那就是编的代码有问题,而且当程序计数器存的地址是不可访问的内存地址时,应该会发生取指令异常中断,程序会跳到中断里去执行,不会继续。

如果一切无异常,则程序最后运行完毕,会返回到runtime代码,做一些资源回收的操作,并结束进程。

以前学单片机时有过一些模糊的概念,若以上内容有不正确的地方,欢迎指出。

1 回复 有任何疑惑可以回复我~
咚咚呛 2019-12-19 22:54:45

思考得挺细的,点赞。

程序在真正执行计算的时候,程序逻辑是加载到一片连续的内存的,这里用数据结构里面的列表来举一个例子:有int list[10] = {0,1,2,3,4,5,6,7,8,9},这个list就拥有连续一片的内存,大小为4Byte*10,list的首地址就是数据0的地址。而list的地址+1就是数据1的地址。(C语言)

第一个问题,需要执行的指令存放在连续的一片内存,只要知道给出首条指令的地址,就可以根据偏移知道后面的指令地址。

第二个问题,这里的加1应该理解为地址偏移+1而不是执行的指令数+1,就好比上面的例子,如果我需要读取5这个值,那么我可以通过list的地址+5,就来到数字5的地址,从而把它读取出来,当跳出这段逻辑的时候,+1的偏移操作,又会发生在新的一片内存。


这里的细节可能在理解C、C++语言的指针偏移等知识会比较好理解一些,不过也没关系,了解到这个程度已经很好了。希望对你有所帮助。

0 回复 有任何疑惑可以回复我~
  • 提问者 烈焰卡卡 #1
    老师我还是有一点疑问,第二个问题,地址偏移+1这个理解,就是地址位加1从5移到6这个地址,但是如果运行完9再+1,这时候怎么办?这时候下一个位置内存不一定存储的是指令,这时候该如何移到新的连续内存?
    对应第一个问题,新生成的指令是如何知道该存到当前这个连续内存存储到list中的哪个地址?还是每一组新的指令都开一片连续内存?这样的话是如何告知程序计数器该在何时转移来执行新的指令?
    回复 有任何疑惑可以回复我~ 2019-12-20 06:33:37
  • 咚咚呛 回复 提问者 烈焰卡卡 #2
    在计算机底层会有JMP这种指令,表示跳跃的意思,可以从一个地方跳到另外一个地方。程序指令是保存在物理内存的,当需要被执行时都会加载到CPU的缓存里面。
    回复 有任何疑惑可以回复我~ 2019-12-20 23:42:19
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信