我的教科书似乎没有回答这个问题,只是它必须“解码”指令,因此它不会回答它是如何知道它首先有一条指令。
我对此的研究给出了两个答案:
1)它不能因为数据和指令在内存中看起来都一样,所以它必须使用程序计数器加载下一条指令,该指令可能会也可能不会通过寻址获取它所需的下一个数据。
2)某种东西以某种形式代码......
我正在试图弄清楚一种解释清楚的方法,所以我知道我能理解它。
答案 0 :(得分:0)
处理器获取并解码程序计数器指向的任何内存。
如果解码器不理解指令,则会抛出“无效指令”异常。然后它将跳转到异常处理程序(即OS),它将尝试理解无效指令。通常,它可能只是一个不受支持的指令,可以用软件处理(例如,浮点除法),然后执行可以从它停止的地方恢复。
但是,如果它是一个真正的无效指令,那么程序将会出现某种异常/崩溃错误(我相信“非法指令”在x86上)。
一种帮助将代码与数据分开的技术是将它们放在虚拟内存中的不同“页面”上。然后,操作系统可以将代码所在的页面标记为“只读”。以这种方式,试图覆盖代码的程序将抛出异常。某些系统允许更多保护,例如“执行错误” - 如果您尝试在此页面上执行代码,则抛出异常(此处有更多信息:http://www.tldp.org/LDP/tlk/mm/memory.html)。
事情可能有点奇怪,但是某些代码实际上需要由程序“修改”(又称“自修改代码”)。这很困难,因为您通常有单独的指令缓存和数据缓存。通常情况下,指令缓存对周围的世界一无所知 - 它不知道有人将新数据写入其包含的地址。对于某些平台,程序员的工作是在修改指令数据后刷新 i-cache,以便i-cache可以重新获取更新的指令。
最后,程序员/编译器的工作是确保PC永远不会跳转到任何非代码的地址。
(当然,恶意用户当然会尝试让PC跳转到他们的错误代码,但我会为另一个帖子保存堆栈缓冲区溢出攻击。)