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

X86 CPU如何预测二进制文件的二进制信息序列中的指令和数据限制?,x86,cpu-architecture,machine-code,instruction-set,illegal-instruction,X86,Cpu Architecture,Machine Code,Instruction Set,Illegal Instruction,CPU如何区分指令和数据 CPU在执行代码时如何确定指令长度(从1字节到最大15字节不等)?如果cpu不确定指令的长度,它可能会将数据作为指令的一部分。在这种情况下,可能会出现不期望的结果,或者cpu不执行该指令(如果不在操作码表中)。cpu如何确定它是数据还是指令 它不需要预测从逻辑上讲,它一次解码一个字节,直到看到完整的指令。(或disp32或imm32的dword块,或先前字节暗示的指令的其他多字节部分)。指令的长度由前缀和操作码+modrm+SIB字节暗示。在查看这些数据之后,CPU肯定

CPU如何区分指令和数据


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

它不需要预测从逻辑上讲,它一次解码一个字节,直到看到完整的指令。(或disp32或imm32的dword块,或先前字节暗示的指令的其他多字节部分)。指令的长度由前缀和操作码+modrm+SIB字节暗示。在查看这些数据之后,CPU肯定知道需要再提取多少指令字节

但是真正的CPU只需要给出这样做的假象,就可以查看后面的字节,只要它最终做了正确的事情,如果它们不是应该执行的指令的一部分。

在实际实现中,只要您最终做了正确的事情,就可以推测性地加载后面的字节

e、 g.一级指令缓存使用64字节行,因此逻辑执行达到一个字节意味着整个64字节内存块将在I-cache中,即使它也在一级D-cache中,因为您在同一行的其他字节上加载了一些数据指令

当然,从L1I缓存获取也不是一次一个字节。在现代x86上,decode查看32或16字节的块以查找指令边界。e、 g.让我们看看P6系列,它没有uop缓存,所以它总是从L1I获取/解码

从PPro/PII/PIII部分:

6.2指令获取

指令代码以对齐的16字节块的形式从代码缓存中提取到双字节缓存中 可以容纳两个16字节块的缓冲区。双缓冲区的目的是使其 可以解码跨越16字节边界的指令(即地址可分割 截至16日)。代码从双缓冲区以块的形式传递到解码器,我将 调用IFETCH块(指令获取块)。IFETCH块的长度最多为16字节。在里面 大多数情况下,指令提取单元使每个IFETCH块从一条指令开始 边界,而不是16字节边界。但是,取指令单元需要 来自指令长度解码器的信息,以了解指令的位置 边界是有限的。如果该信息无法及时获得,则可能会启动IFETCH块 在16字节的边界上。下面将更详细地讨论这种复杂性

然后,预解码器流水线阶段找到指令边界(假设它们都是有效指令),然后(根据分支预测单元所做的预测)将3条指令的机器码并行发送到3个解码器。(Core2扩宽到4个解码器,Skylake扩宽到5个解码器,即使管道宽度保持在4 uops宽)

如果某个地方有非法指令(或无条件的
jmp
,或碰巧执行的
jcc
),那么以后的“指令”将毫无意义,一旦发现该事实就会被丢弃。


讨论Nehalem中的解码阶段,Nehalem是P6系列微体系结构的最后一代。但是Agner Fog的描述在理解CPU如何查看一堆字节,然后只使用逻辑上应该作为指令执行的字节方面可能更有用从逻辑上讲,它一次解码一个字节,直到看到完整的指令。(或disp32或imm32的dword块,或先前字节暗示的指令的其他多字节部分)。指令的长度由前缀和操作码+modrm+SIB字节暗示。在查看这些数据之后,CPU肯定知道需要再提取多少指令字节

但是真正的CPU只需要给出这样做的假象,就可以查看后面的字节,只要它最终做了正确的事情,如果它们不是应该执行的指令的一部分。

在实际实现中,只要您最终做了正确的事情,就可以推测性地加载后面的字节

e、 g.一级指令缓存使用64字节行,因此逻辑执行达到一个字节意味着整个64字节内存块将在I-cache中,即使它也在一级D-cache中,因为您在同一行的其他字节上加载了一些数据指令

当然,从L1I缓存获取也不是一次一个字节。在现代x86上,decode查看32或16字节的块以查找指令边界。e、 g.让我们看看P6系列,它没有uop缓存,所以它总是从L1I获取/解码

从PPro/PII/PIII部分:

6.2指令获取

指令代码以对齐的16字节块的形式从代码缓存中提取到双字节缓存中 可以容纳两个16字节块的缓冲区。双缓冲区的目的是使其 可以解码跨越16字节边界的指令(即地址可分割 截至16日)。代码从双缓冲区以块的形式传递到解码器,我将 调用IFETCH块(指令获取块)。IFETCH块的长度最多为16字节。在里面 大多数情况下,指令提取单元使每个IFETCH块从一条指令开始 边界,而不是16字节边界。但是,取指令单元需要 来自指令长度解码器的信息,以便