MUL指令不支持立即值

Tan*_*ock 8 x86 assembly immediate-operand

我已经阅读了一些教程和示例,但我无法理解MUL指令的工作原理.我已经习惯了ADD,SUB没有问题.显然,该指令将其操作数乘以寄存器中的值.

什么寄存器(eax,ebp,esp等)乘以第一个操作数?存储的结果是什么寄存器,所以我可以将其移动到堆栈中?对不起,我刚学习x86程序集.

当我尝试编译这一行时......

mul     9
Run Code Online (Sandbox Code Playgroud)

我明白了Error: suffix or operands invalid for 'mul'.谁能帮我吗?

    global  main
    main:
    push    ebp
    movl    ebp, esp
    sub     esp, byte +8
    mov     eax, 7
    mul     9
    mov     [esp], eax
    call    _putchar
    xor     eax, eax
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

Eug*_*ith 13

MUL不能使用立即值作为参数.你必须将'9'加载到寄存器中,比方说,

 movl    $7, %eax
 movl    $9, %ecx
 mull    %ecx
Run Code Online (Sandbox Code Playgroud)

这会将ex乘以ecx并将64位产品存储在edx:eax中.

有关英特尔网站上x86汇编指令的详细参考,请参见此处

http://www.intel.com/Assets/PDF/manual/253666.pdf

http://www.intel.com/Assets/PDF/manual/253667.pdf

但这可能是您现在需要的更多信息.

  • OP未使用EDX上半部分的结果。您至少应该*提及* x86确实具有立即乘法(在386之前的某个时间添加,因此32位代码始终可以依靠它)。`imul $ 9,%eax,%eax`。或更佳的是2的幂+ 1'lea(%eax,%eax,8),%eax`。 (2认同)

phu*_*clv 6

如果您查看MUL格式表,您会发现它只接受一个寄存器参数。然而,翻过来IMUL,你会发现它有很多形式可以立即接受

\n\n
\n6B /r ib          IMUL r16、r/m16、imm8   字寄存器 \xe2\x86\x90 r/m16 \xe2\x88\x97 符号扩展立即字节。\n6B /r ib          IMUL r32、r/m32、imm8   双字寄存器 \xe2\x86\x90 r/m32 \xe2\x88\x97 符号扩展立即字节。\nREX.W + 6B /r ib IMUL r64, r/m64, imm8   四字寄存器 \xe2\x86\x90 r/m64 \xe2\x88\x97 符号扩展立即数字节。\n69 /r iw          IMUL r16、r/m16、imm16  字寄存器 \xe2\x86\x90 r/m16 \xe2\x88\x97 立即数。\n69 /r id          IMUL r32, r/m32, imm32  双字寄存器 \xe2\x86\x90 r/m32 \xe2\x88\x97 立即双字。\nREX.W + 69 /r id IMUL r64, r/m64, imm32  四字寄存器 \xe2\ x86\x90 r/m64 \xe2\x88\x97 立即双字。\n
\n\n

所以要将 eax 乘以 9 你可以这样做

\n\n
mov eax, 7\nimul eax, eax, 9 ; eax = eax*9\n
Run Code Online (Sandbox Code Playgroud)\n\n

仔细观察,您还可以观察到这些版本是非扩展的。事实上,现在imul几乎专门用于所有乘法,因为非扩展乘法对于有符号和无符号值是相同的,并且高级语言中的乘法是非扩展的(即输出类型和输入操作数的类型相同)除非您将操作数转换为更宽的类型。因此,现代 x86 CPU 通常会针对其进行优化imul,并且它的形式也比mul

\n

  • 在这种 2 + 1 次幂的情况下,“lea eax, [eax + eax*8]”甚至比直接 imul 更好。但是,是的,+1,当OP显然没有使用高半结果时,我无法相信所有这些建议将“mov”放入寄存器的答案。 (2认同)

Mad*_*uja 3

http://siyobik.info/index.php?module=x86&id=210

目标操作数是位于寄存器 AL、AX 或 EAX 中的隐含操作数(取决于操作数的大小);源操作数位于通用寄存器或内存位置

结果存储在寄存器 AX、寄存器对 DX:AX 或寄存器对 EDX:EAX(取决于操作数大小)中,乘积的高位分别包含在寄存器 AH、DX 或 EDX 中。如果乘积的高位为0,则CF和OF标志被清零;否则,设置标志。

在你的来源中它应该是mul而不是mull