Assembly 对于可变长度指令,计算机如何知道所提取指令的长度?

Assembly 对于可变长度指令,计算机如何知道所提取指令的长度?,assembly,cpu-architecture,Assembly,Cpu Architecture,在并非所有指令长度都相同的体系结构中,计算机如何知道一条指令的读取量?例如,在英特尔IA-32中,有些指令是4字节,有些是8字节,那么它如何知道是读取4字节还是8字节呢?机器通电时的第一条红色指令是否具有已知大小,并且每条指令都包含下一条指令的大小?每条指令的第一个字节表示其长度。如果事情很简单,第一个字节将指示长度,但是 真正的问题是,由于现代无序处理器每个周期解码3或4条指令,它如何知道第二条、第三条、第四条指令从哪里开始 答案是,它以并行、暴力的方式解码当前16字节代码行中所有可能的起始点

在并非所有指令长度都相同的体系结构中,计算机如何知道一条指令的读取量?例如,在英特尔IA-32中,有些指令是4字节,有些是8字节,那么它如何知道是读取4字节还是8字节呢?机器通电时的第一条红色指令是否具有已知大小,并且每条指令都包含下一条指令的大小?

每条指令的第一个字节表示其长度。如果事情很简单,第一个字节将指示长度,但是

真正的问题是,由于现代无序处理器每个周期解码3或4条指令,它如何知道第二条、第三条、第四条指令从哪里开始


答案是,它以并行、暴力的方式解码当前16字节代码行中所有可能的起始点。我很确定这句话/猜测的来源是阿格纳·福格,但我找不到参考资料。我在谷歌上搜索了“Agner Fog指令解码可疑”,但显然是这样。

扩展Pascal的答案,在上,第一个字节表示解码的指令属于哪一类:

  • 1字节长度,这意味着它已经被读取并可以进一步处理

  • 1字节操作码,再加上几个字节(即所谓的ModRM和SIB字节),以指示以下是哪些操作数(寄存器、内存地址)及其操作数

  • 指令前缀,其中:

    • 修改指令的含义,(重复-
      REP
      ,锁定语义-
      LOCK
    • 指示下一个字节对原始8086 cpu的后续迭代中引入的指令进行编码,以将其操作数的大小扩展到32或64位,或完全重新定义操作码的含义
此外,根据CPU运行的模式,一些前缀可能有效,也可能无效:例如,
REX
VEX
前缀分别用于实现64位和向量指令,但它们仅在64位模式下被解释为这样
REX
,由于其格式,涵盖了原始指令集中的大量现有指令,这些指令不能再以64位的形式使用(我认为
VEX
前缀的工作原理类似,尽管我对此一无所知)。其字段表示以下指令操作数大小,或仅对64位可用的额外寄存器的访问(
R8
to
R15
XMM8
to
XMM15

如果您研究操作码的内部模式,您会注意到某些位一致地指示指令属于哪个类别,从而导致解码速度有点快


是另一种架构(流行于70年代末至80年代末),基于类似的原则,采用可变长度指令。对于第一次迭代,指令可能是按顺序解码的,因此指令的结尾表示下一个字节新指令的开始。您可能知道,生产这些产品的公司也生产了它的极性相反的产品,它成为当时速度最快(如果不是最快的话)的CPU之一,具有固定长度的指令,这一选择肯定是对当时迅速发展的流水线超标量技术的要求作出的反应。

首先,处理器不需要知道要获取多少字节,它可以获取一个方便的字节数,足以为典型或平均指令长度提供目标吞吐量。任何额外的字节都可以放在缓冲区中,以便在下一组要解码的字节中使用。取回的宽度和对齐方式相对于指令解码的支持宽度,甚至相对于管道后面部分的宽度,都存在权衡。获取比平均值更多的字节可以减少指令长度和与控制流指令相关的有效获取带宽变化的影响

(如果[predicted]在下一次提取后的一个周期内,目标才可用,并使用与指令提取对齐程度较低的目标减少有效提取带宽。例如,如果指令提取是16字节对齐的,这对于高性能x86-a执行的分支来说是常见的,目标是第16个[最后一个]块中的字节将导致实际上只提取代码的一个字节,而其他15个字节将被丢弃。)

即使对于固定长度的指令,每个周期获取多条指令也会带来类似的问题。某些实现(例如,MIPS R10000)将获取尽可能多的指令,即使这些指令未对齐,只要指令组不跨越缓存线边界即可。(我似乎记得,一个RISC实现包含两组Icache标记,允许获取跨越缓存块,但不跨越页面边界。)其他实现(例如POWER4)将获取对齐的代码块,即使是针对此类块中最后一条指令的分支。(对于POWER4,使用了包含8条指令的32字节块,但每个周期最多有5条指令可以通过解码。可以利用此多余的提取宽度,通过不执行提取的周期节省能量,并在未命中后为缓存块填充提供备用Icache周期,而Icache只有一个读/写端口。)

对于每个周期解码多条指令,有两种有效的策略:推测性并行解码或等待确定长度,并使用该信息将指令流解析为单独的指令。对于类似ISA的IBM的zArchitecture(s/360后代),16位包中的长度通常由第一个包中的两位决定,因此等待确定长度