No *_* QA 4 x86 assembly bit-shift cpu-architecture cpu-registers
我正在深入研究 x86 ASM 中的左移和右移操作,例如shl eax, cl
来自 IA-32 英特尔架构软件开发人员\xe2\x80\x99s 手册 3
\n\n\n\n\n所有 IA-32\n 处理器(从 Intel 286 处理器开始)都会将移位计数屏蔽为 5 位,从而导致最大计数为 31。此屏蔽在所有操作模式\n 中完成(包括虚拟 8086模式)以减少指令的最大执行时间。
\n
我试图理解这个逻辑背后的原因。也许它以这种方式工作是因为在硬件级别上很难使用 1 个周期实现寄存器中所有 32(或 64)位的移位?
\n\n任何详细的解释都会有很大帮助!
\n编辑以更正声明:80386,(令我惊讶的是)确实有一个桶形移位器。
\n很高兴听到 286 被描述为“现代”:-)
\n8086 的运行时间SHL AX, CL为 8 个时钟 + 每位移位 4 个时钟。所以 if CL= 255 这是一条非常慢的指令!
所以 286 帮了大家一个忙,通过掩码将计数限制在 0..31。将指令限制为最多 5 + 31 个时钟。对于 16 位寄存器来说,这是一个有趣的折衷方案。
\n[我找到了《80186/80188 80C186/80C188硬件参考手册》(订单号270788-001),其中说这项创新首先出现在那里。 SHL等人运行了 5+n 个时钟(用于寄存器操作),与 286 相同。FWIW,186 还添加了 PUSHA/POPA、PUSH immed.、INS/OUTS、BOUND、ENTER/LEAVE、IMUL immed。和 SHL/ROL 等。我不知道为什么186看起来像是一个非人。]
对于 386,他们保留相同的掩码,但这也适用于 32 位寄存器移位。我找到了一份《80386程序员参考手册》(订单号230985-001),其中给出了所有寄存器移位的时钟计数为3。《Intel 80386硬件参考手册》(订单号231732-002)第2.4节“执行单元”说执行单元包括:
\n\n\n\xe2\x80\xa2 数据单元包含 ALU、八个 32 位通用寄存器的文件和一个 64 位桶形移位器(在一个时钟内执行多个位移位)。
\n
所以,我不知道为什么他们不将 32 位移位屏蔽为 0..63。在这一点上我只能提出荒谬的历史理论。
\n我同意,遗憾的是没有一个 (GPR) 移位对于任何计数 >= 参数大小都返回零。这需要硬件检查底部 6/5 之外的任何位设置,并返回零。作为妥协,也许只是 Bit6/Bit5。
\n[我还没有尝试过,但我怀疑使用PSLLQet al 是一项艰苦的工作——将计数和值打乱xmm,然后将结果再次打乱——与测试移位计数和屏蔽某些分支中的移位结果相比-自由时尚。]
无论如何……这种行为的原因似乎已经成为历史。
\n