CPU如何预测二进制文件的二进制信息序列中的指令和数据限制?

问题描述 投票:0回答:1

CPU如何将指令与数据区分开?

CPU在执行代码时如何确定指令长度(从1字节到最大15字节不等)?如果假设cpu不能确定指令的长度,则可以将数据作为指令的一部分。在这种情况下,可能会出现不希望的结果,或者CPU不执行该指令(如果不在操作码表中)。 cpu如何确定是数据还是指令?

x86 cpu-architecture machine-code instruction-set illegal-instruction
1个回答
0
投票

不必预测。 在逻辑上,它一次解码一个字节,直到看到完整的指令。(或disp32或imm32的dword块,或指令的其他多字节部分由较早的字节暗示。)指令的长度为由前缀和操作码+ modrm + SIB字节表示。在查看了这些内容之后,CPU会确定要提取多少个指令字节。

但是真正的CPU只需要给出这样做的错觉,并且只要它们最终不属于应该执行的指令的一部分,只要它最终做对了事情,就可以查看后面的字节。

实际上,在实际的实现中,只要您最终做正确的事,就可以推测性地加载后面的字节没有问题。

例如L1指令缓存使用64字节的行,因此逻辑执行到达一个字节意味着整个64字节的内存块都将位于I缓存中,即使它在L1 D缓存中也是[[also相同行中其他字节上的数据加载指令。

当然,从L1I缓存中提取数据也不是一次是单个字节。在现代x86上,解码查看32或16字节的块以查找指令边界。例如让我们看一下P6系列,它没有uop缓存,因此它总是从L1I提取/解码。

Agner Fog's microarch PDF,在PPro / PII / PIII部分中:

6.2指令提取

从代码缓存中按对齐的16字节块中提取指令代码

成双精度可以容纳两个16字节块的缓冲区。双缓冲区的目的是为了使其可以解码跨越16字节边界的指令(即可整除的地址16)。代码将从双缓冲区传递到块中的解码器,我将调用IFETCH块(指令提取块)。 IFETCH块最长为16个字节。在在大多数情况下,指令提取单元使每个IFETCH块从一条指令开始边界,而不是16字节边界。但是,指令提取单元需要来自指令长度解码器的信息,以便知道指令在哪里边界是。如果无法及时获得此信息,则它可能会启动一个IFETCH块在16字节边界处。这种复杂性将在下面更详细地讨论。
预解码器流水线级然后找到指令边界(假设它们都是有效指令),然后(按照分支预测单元的预测),将3条指令的机器代码并行发送到3个解码器。 (Core2扩展为4个解码器,Skylake扩展为5个解码器,即使管道宽度保持在4 uop宽)。

如果某处有非法指令(或无条件的jmp或恰好被取走的jcc,则后来的“指令”是没有意义的,一旦发现这一事实便被丢弃。

https://www.realworldtech.com/nehalem/5/讨论了Nehalem中的解码阶段,Nehalem是P6系列微体系结构的最后一代。但是Agner Fog的描述可能对理解

CPU可以看一堆字节,然后仅使用逻辑上应作为指令执行的字节

。更为有用。
© www.soinside.com 2019 - 2024. All rights reserved.