MUL指令不支持立即值

时间:2010-12-25 04:09:16

标签: assembly x86 immediate-operand

我已经阅读了一些教程和示例,但我无法理解MUL指令的工作原理。我已经毫无问题地使用了ADDSUB。显然,这条指令将其操作数乘以寄存器中的值。

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

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

mul     9

我明白了,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

6 个答案:

答案 0 :(得分:12)

MUL不能使用立即值作为参数。您必须将“9”加载到寄存器中,例如

 movl    $7, %eax
 movl    $9, %ecx
 mull    %ecx

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

英特尔网站上有一个很好的全面参考x86汇编指令,请参见此处

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

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

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

答案 1 :(得分:4)

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

答案 2 :(得分:3)

我不是专家,但我认为你的问题是mul在你的情况下不会接受直接操作数十进制常数9所以试着把9放在让我们说像这样的寄存器bx:

mov bx, 9
mul bx

要回答关于mul的问题,一般情况如下:

mul     reg/memory

并且做到了:

dx:ax := ax*reg/mem

因此,对于单词,它需要一个单独的操作数,它应该是一个寄存器或一个存储单元(存储该值要相乘,实际上是一个变量)并将它乘以ax然后取决于寄存器/存储器的长度(所以您给出的操作数)将其存储在ax或dx:ax或edx:eax

我希望我能在那里帮助你!

答案 3 :(得分:2)

如果查看MUL格式表,您会注意到它仅接受一个寄存器参数。但是,转到IMUL,您会发现它有很多形式可以接受立即数

6B /r ib         IMUL r16, r/m16, imm8   word register ← r/m16 ∗ sign-extended immediate byte.
6B /r ib         IMUL r32, r/m32, imm8   doubleword register ← r/m32 ∗ sign-extended immediate byte.
REX.W + 6B /r ib IMUL r64, r/m64, imm8   Quadword register ← r/m64 ∗ sign-extended immediate byte.
69 /r iw         IMUL r16, r/m16, imm16  word register ← r/m16 ∗ immediate word.
69 /r id         IMUL r32, r/m32, imm32  doubleword register ← r/m32 ∗ immediate doubleword.
REX.W + 69 /r id IMUL r64, r/m64, imm32  Quadword register ← r/m64 ∗ immediate doubleword.

因此,要将eax乘以9,您可以这样做

COPY Account FROM STDIN DELIMITER ',' REJECTED DATA '/path/to/rejections.txt' EXCEPTIONS '/path/to/exceptions.txt';

仔细观察,您还会发现这些版本没有扩大。实际上,当今mov eax, 7 imul eax, eax, 9 ; eax = eax*9 几乎专用于几乎所有乘法,因为非扩展乘法是the same for signed and unsigned values,而高级语言中的乘法也没有扩展(即,输出类型和输入操作数的类型是相同),除非您将操作数转换为更广泛的类型。结果,modern x86 CPUs are often optimized for imul的形式比imul

多得多

答案 4 :(得分:1)

我会给你一个链接到我最喜欢的易于阅读但完整的x86参考:http://www.ousob.com/ng/iapx86/ng1840d.php

答案 5 :(得分:0)

如何阅读英特尔手册以确定无法使用

首先下载英特尔手册。目前的下载页面为:http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html,但只有Google" intel x86手册"因为这必然会改变。

我们想要的是包含所有指令的组合卷2指令集参考A-Z。

在该手册中,找到DIV的文档。我们看到DIV指令列下具有以下格式:

  • DIV r/m8
  • DIV r/m16
  • DIV r/m32
  • DIV r/m64

r/mX表示它可以使用大小为X的寄存器或内存位置。

因此,没有形式需要immX,这是一个立即值或文字。

因此无法将该指令编码到处理器,现在我们知道唯一的方法是通过寄存器或内存。

寄存器更快,所以我们当然可以使用它们。