在阅读ARM核心文档时,我对此表示怀疑。 CPU如何区分读数据与数据总线,是将其作为指令执行还是作为可以操作的数据执行?
请参阅文件摘录 -
“数据进入处理器核心 通过数据总线。数据可能是 执行指令或数据 项目。”
在此先感谢您的启发! /女士
在阅读ARM核心文档时,我对此表示怀疑。 CPU如何区分读数据与数据总线,是将其作为指令执行还是作为可以操作的数据执行?
请参阅文件摘录 -
“数据进入处理器核心 通过数据总线。数据可能是 执行指令或数据 项目。”
在此先感谢您的启发! /女士
每个操作码将由N个字节的指令组成,然后期望随后的M个字节是数据(存储器指针等)。因此,CPU使用每个操作码来确定以下字节数是多少。
当然对于旧处理器(例如旧的8位类型,例如6502等),没有区别。您通常会将程序计数器指向内存中程序的开头,并从内存中的其他位置引用数据,但程序/数据存储为简单的8位值。处理器本身无法区分这两者。
完全有可能将程序计数器指向那些被视为数据的东西,事实上我记得我的教授所做的一个旧的大学教程 究竟 那个,我们不得不把错误指向他。他的回答是“但这是数据!它不能执行它!可以吗?”,此时我用有效的操作码填充我们的数据,以证明它确实可以。
每个操作码将由N个字节的指令组成,然后期望随后的M个字节是数据(存储器指针等)。因此,CPU使用每个操作码来确定以下字节数是多少。
当然对于旧处理器(例如旧的8位类型,例如6502等),没有区别。您通常会将程序计数器指向内存中程序的开头,并从内存中的其他位置引用数据,但程序/数据存储为简单的8位值。处理器本身无法区分这两者。
完全有可能将程序计数器指向那些被视为数据的东西,事实上我记得我的教授所做的一个旧的大学教程 究竟 那个,我们不得不把错误指向他。他的回答是“但这是数据!它不能执行它!可以吗?”,此时我用有效的操作码填充我们的数据,以证明它确实可以。
简单的答案 - 它没有。机器代码指令只是二进制数字,数据也是如此。更复杂的答案 - 您的处理器可能(或可能不)提供内存分段,这意味着尝试执行已指定为数据的内容会导致某种陷阱。这是“分段错误”的含义之一 - 处理器试图执行未标记为可执行代码的内容。
已知处理器的每次读取都是数据提取或指令提取。所有旧的和新的处理器都知道从数据提取中获取指令。从外部你可能会或可能不会告诉,通常不是除了哈佛架构处理器,当然,ARM不是。我最近一直在使用mpcore(ARM11),外部接口上有一些位告诉你一些关于它是什么类型的读取,主要是为了连接一个外部缓存,将它与你有mmu的知识结合起来和L1缓存打开,你可以告诉指令数据,但这是规则的例外。从内存总线的角度来看,它只是你不知道来自指令的数据的数据位,但启动该内存周期并等待结果的逻辑在它开始循环之前知道它是什么类型的获取以及它将要做什么获得它时的数据。
最初的ARM设计有一个用于执行指令的三阶段管道:
CPU的内部逻辑确保它知道它是在阶段1中获取数据(即,取指令),还是在阶段3(即由于“加载”指令引起的数据获取)。
现代ARM处理器有一个单独的总线用于获取指令(因此管道在获取数据时不会停止),以及一个更长的流水线(允许更快的时钟速度),但总的想法仍然是相同的。
我认为它归结为数据存储在程序中的位置和OS支持,以通知CPU它是代码还是数据。
与变量存储相比,所有代码都放置在图像的不同部分(以及静态数据,如常量字符串)。操作系统(和内存管理单元)需要知道这一点,因为它们可以通过简单地丢弃代码并从原始磁盘文件重新加载代码来替换内存(至少Windows是这样做的)。
所以,我认为CPU'知道'内存是数据还是代码。毫无疑问,我们现在拥有的现代管道CPU也有不同的读取内存的指令,以帮助CPU尽快处理它(例如,代码可能不会被缓存,数据总是被随机访问而不是在流中访问)
它仍然可以将程序计数器指向数据,但操作系统可以告诉CPU防止这种情况 - 请参阅NX位和Windows的“数据执行保护”设置(系统控制面板)
所以,我认为CPU'知道'内存是数据还是代码。毫无疑问,我们现在拥有的现代管道CPU也有不同的读取内存的指令,以帮助CPU尽快处理它(例如,代码可能不会被缓存,数据总是被随机访问而不是在流中访问)