Инструкция MUL не поддерживает непосредственное значение - PullRequest
8 голосов
/ 25 декабря 2010

Я прочитал несколько уроков и примеров, но я не могу понять, как работает инструкция MUL. Я использовал ADD и SUB без проблем. Таким образом, очевидно, эта инструкция умножает свой операнд на значение в регистре.

Какой регистр (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 ]

13 голосов
/ 25 декабря 2010

MUL не может использовать непосредственное значение в качестве аргумента. Вы должны загрузить «9» в регистр, скажем,

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

, который умножит eax на ecx и сохранит 64-битный продукт в edx: eax.

На веб-сайте Intel есть полный исчерпывающий справочник инструкций по сборке x86, см. Здесь

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

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

Но это, вероятно, гораздо больше информации, которая вам нужна сейчас.

4 голосов
/ 25 декабря 2010

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

3 голосов
/ 20 мая 2011

Я не эксперт, но я думаю, что ваша проблема в том, что mul не примет прямой операнд в вашем случае десятичной константы 9, поэтому попробуйте ввести 9, скажем, в регистр bx следующим образом:

mov bx, 9
mul bx

Чтобы ответить на ваш вопрос о mul в целом, он выглядит следующим образом:

mul     reg/memory

и делает это:

dx:ax := ax*reg/mem

То есть со словами он ожидает один операнд, который долженможет быть регистром или ячейкой памяти (где хранится значение, которое нужно умножить, по существу, на переменную), и умножает его на топор, а затем в зависимости от того, как долго регистр / память (т. е. операнд, который вы дали) хранит его в топоре или дх.: ax или edx: eax

Я надеюсь, что помог вам там приятель!

2 голосов
/ 29 января 2019

Если вы посмотрите на таблицу формата MUL, вы заметите, что она принимает только один параметр регистра.Однако перейдите к IMUL, и вы увидите, что существует множество его форм, которые принимают немедленное

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

. Таким образом, умножив eax на 9, вы можете сделать вот так

mov eax, 7
imul eax, eax, 9 ; eax = eax*9

Присмотритесь, и вы также увидите, что эти версии не расширяются.Фактически в настоящее время imul используется исключительно для почти всех умножений, потому что умножение без расширения равно одинаково для знаковых и беззнаковых значений , а умножение в языках высокого уровня не расширяется (т. Е. Тип вывода итипы входных операндов одинаковы), если вы не приведете операнды к более широкому типу.В результате, современные процессоры x86 часто оптимизируются для imul, а также имеют гораздо больше форм, чем mul

1 голос
/ 25 декабря 2010

Я дам вам ссылку на мою любимую легкую для чтения, но полную ссылку на x86: http://www.ousob.com/ng/iapx86/ng1840d.php

0 голосов

Как прочитать в руководстве Intel, чтобы увидеть, что это невозможно

Сначала загрузите руководство Intel. Текущая страница загрузки: http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html, но просто Google "intel x86 manual", так как он обязательно изменится.

Что нам нужно, так это справочник A-Z комбинированного набора инструкций тома 2, содержащий все инструкции.

В этом руководстве найдите документацию для DIV. Мы видим, что DIV имеет следующие формы в столбце Инструкция :

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

r/mX означает, что он может принимать регистр или ячейку памяти размера X.

Следовательно, не существует формы, которая принимает immX, что является непосредственным значением или буквальным.

Так что невозможно закодировать эту инструкцию процессору, и теперь мы знаем, что единственный путь - это пройти через регистры или память.

Регистры работают быстрее, поэтому мы, конечно, используем их, если это возможно.

...