【发布时间】:2017-05-04 21:02:08
【问题描述】:
我知道 imul 是有符号乘法,文档似乎表明三个操作数的语法是imulq dest, source1, source2。因此,该行将读取为:将存储在 %rbx 中的地址的内容与 %rax 中的值相乘,然后将其存储在内存位置 44 中,但这肯定不正确?
【问题讨论】:
-
您对 Intel 语法和 AT&T 语法感到困惑。
我知道 imul 是有符号乘法,文档似乎表明三个操作数的语法是imulq dest, source1, source2。因此,该行将读取为:将存储在 %rbx 中的地址的内容与 %rax 中的值相乘,然后将其存储在内存位置 44 中,但这肯定不正确?
【问题讨论】:
您正在使用imul 指令的三操作数变体,它在指令集参考中定义为IMUL r64, r/m64, imm8,意思是“将r/m64 的内容乘以imm8 并将结果存储在r64"。该指令还有另一个变体,它采用 32 位立即数,但在这种情况下,无法判断汇编器实际发出哪个变体。
现在,您的汇编器似乎正在使用 x86 汇编的 AT&T 语法。 GNU 汇编器默认使用它。它以相反的顺序指定指令的操作数而闻名。因此,imulq $44, (%rbx), %rax 会将存储在%rbx 中的地址处的内存内容乘以44,并将结果存储在%rax 中。
【讨论】:
我阅读操作数的顺序与文档描述的顺序不同。
其内容为:“获取存储在寄存器 rbx 内存地址中的有符号整数值,将其乘以 44,然后将结果放入寄存器 rax。”
或者简单地说:
imulq multiplier1, multiplier2, destination
【讨论】:
imulq multiplier2, multiplier1, destination。 AT&T 语法中的参数全部颠倒。当您查看英特尔的文档时,您需要扭转他们所说的内容。 (当然,在这种特殊情况下这并不重要,因为乘法是可交换的。)