为什么 x86 mul 和 div 指令仅采用源操作数?

Mic*_*eno 2 x86 assembly x86-64 instruction-set instructions

在 x86 汇编中,大多数指令具有以下语法:

operation dest, source
Run Code Online (Sandbox Code Playgroud)

例如,add看起来像

add rax, 10 ; adds 10 to the rax register
Run Code Online (Sandbox Code Playgroud)

但是助记符就像mul并且div只有一个操作数source- 被destination硬编码为rax. rax这迫使您在想要乘法或除法时随时设置并跟踪寄存器,如果您正在进行一系列乘法,这可能会变得很麻烦。

我假设存在与乘法和除法的硬件实现相关的技术原因。有没有?

fuz*_*fuz 5

mul和的目标寄存器div不是rax,而是rdx:rax。这是因为两条指令都返回两个结果;mul返回双宽度结果并div返回商和余数(在采用双宽度输入之后)。

x86 指令编码方案仅允许在传统指令中对两个操作数进行编码(div并且mul很旧,可以追溯到 8086)。只有一个操作数允许专用于另一操作数的位用作操作码的扩展,从而可以编码更多指令。由于divandmul指令使用得不太频繁,并且无论如何都必须对一个操作数进行硬编码,因此对第二个操作数进行硬编码被认为是一种很好的权衡。

这与辅助指令cbwcwdcwdecdq、联系在一起cdqecqo用于准备指令的操作数div

请注意,后来imul引入了指令的其他形式,允许在单字(而不是双字)乘法 (80386) 和常数乘法 (80186) 的常见情况下使用两个 modr/m 操作数。甚至后来,BMI2 引入了一种 VEX 编码mulx指令,允许三个可自由选择的操作数,其中一个源操作数可以是内存操作数。

  • @ecm 已更正! (2认同)