为什么 8 位 MUL 组合成 AX 而 16 位和 32 位 MUL 将结果拆分为 [E]DX:[E]AX?
Why does 8-bit MUL combine into AX but 16 and 32-bit MUL leave their result split between [E]DX:[E]AX?
MUL CL
CL 为 BYTE 大小,等于 AX = AL * CL
MUL BX
BX为WORD大小,等于DX:AX = AX * BX
MUL EBX
EBX 是 DWORD 大小,等于 EDX:EAX = EAX * EBX
我想知道为什么 8 位大小的 MUL
指令在 AX
而不是 DL:AL
中给出结果?
是不是因为16位MUL可以EAX
,32位MUL可以RAX
,64位mul rcx
就不会了'是否有足够宽的单个寄存器来保存结果?
8086 有 16 位寄存器(AX、BX、...)。因此,8*8=16 加宽乘法(即,具有 8 位输入和 16 位结果)可以将其结果放入单个寄存器中。将它拆分为两个寄存器会很不方便,而且没有任何好处。
但是 16*16=32 加宽乘法无法将其结果放入单个寄存器中,因为没有 32 位寄存器。必须将其拆分为两个寄存器,并选择了 DX 和 AX。
同样,386 具有 32 位寄存器(EAX、EBX 等),因此其 32*32=64 加宽乘法必须对其结果进行拆分。 EDX:EAX 因与 8086 相似而被选中。
英特尔此时可以添加新版本的 16*16=32 MUL,将其结果留在单个 32 位寄存器中,例如 EAX,但他们选择不这样做,也许是为了兼容性或避免不必要的额外复杂性,或来自简单的惯性。所以 386 的 16*16=32 MUL
仍然将其结果拆分为 DX:AX,即使在 32 位模式下也是如此。
(但是,他们确实添加了带符号乘法 IMUL
指令的非扩展 32*32=32 形式,将其结果留在单个 32 位寄存器中。人们可以将其用于通过对输入进行符号扩展来进行有符号 16*16=32 乘法,为此还添加了方便的 MOVSX
。它可以用于 16*16=32 无符号乘法,通过对输入进行零扩展,如果一个知道乘积会小于2^31
.)
同样,x86-64 有 64 位寄存器。对于现有的乘法指令,他们保持相同的行为(因此 32*32=64 仍然将其结果拆分为 EDX:EAX 而不是使用单个 64 位寄存器),并且他们添加了 64*64=128 扩展再次相乘,必须拆分其结果,并将其留在 RDX:RAX 中。还有一个非扩展的 64*64=64 signed IMUL
将其结果留在单个 64 位寄存器中。
MUL CL
CL 为 BYTE 大小,等于AX = AL * CL
MUL BX
BX为WORD大小,等于DX:AX = AX * BX
MUL EBX
EBX 是 DWORD 大小,等于EDX:EAX = EAX * EBX
我想知道为什么 8 位大小的 MUL
指令在 AX
而不是 DL:AL
中给出结果?
是不是因为16位MUL可以EAX
,32位MUL可以RAX
,64位mul rcx
就不会了'是否有足够宽的单个寄存器来保存结果?
8086 有 16 位寄存器(AX、BX、...)。因此,8*8=16 加宽乘法(即,具有 8 位输入和 16 位结果)可以将其结果放入单个寄存器中。将它拆分为两个寄存器会很不方便,而且没有任何好处。
但是 16*16=32 加宽乘法无法将其结果放入单个寄存器中,因为没有 32 位寄存器。必须将其拆分为两个寄存器,并选择了 DX 和 AX。
同样,386 具有 32 位寄存器(EAX、EBX 等),因此其 32*32=64 加宽乘法必须对其结果进行拆分。 EDX:EAX 因与 8086 相似而被选中。
英特尔此时可以添加新版本的 16*16=32 MUL,将其结果留在单个 32 位寄存器中,例如 EAX,但他们选择不这样做,也许是为了兼容性或避免不必要的额外复杂性,或来自简单的惯性。所以 386 的 16*16=32 MUL
仍然将其结果拆分为 DX:AX,即使在 32 位模式下也是如此。
(但是,他们确实添加了带符号乘法 IMUL
指令的非扩展 32*32=32 形式,将其结果留在单个 32 位寄存器中。人们可以将其用于通过对输入进行符号扩展来进行有符号 16*16=32 乘法,为此还添加了方便的 MOVSX
。它可以用于 16*16=32 无符号乘法,通过对输入进行零扩展,如果一个知道乘积会小于2^31
.)
同样,x86-64 有 64 位寄存器。对于现有的乘法指令,他们保持相同的行为(因此 32*32=64 仍然将其结果拆分为 EDX:EAX 而不是使用单个 64 位寄存器),并且他们添加了 64*64=128 扩展再次相乘,必须拆分其结果,并将其留在 RDX:RAX 中。还有一个非扩展的 64*64=64 signed IMUL
将其结果留在单个 64 位寄存器中。