Я до сих пор не понимаю, как IMUL работает в Ассамблее - PullRequest
0 голосов
/ 05 июля 2019

Я новичок в сборке, я только начал изучать ее, и я не понимаю, как на самом деле работает инструкция IMUL

Например, я работаю над этим фрагментом кода в visual studio:


Mat = 0A2A(hexadecimal)

__asm {

    MOV AX, Mat
    AND AL,7Ch
    OR AL,83h
    XOR BL,BL
    SUB BL,2
    IMUL BL
    MOV Ris5,AX
}

результат в Ris5 должен быть 00AA (в шестнадцатеричном формате), для первых двух строк все хорошо, от первой строки до 'SUB BL, 2' результаты AL= AB (AX = 0AAB), но затем, начиная с IMUL, я застрял.Я знаю, что IMUL выполняет умножение со знаком AL на регистр, байт или слово ... и сохраняет результат в AX (здесь), но я не могу найти тот же результат (00AA)

1 Ответ

3 голосов
/ 05 июля 2019
MOV AX, Mat    AX = 0x0A2A  (...00101010)
AND AL,7Ch     AX = 0x0A28  (...00101000)
OR AL,83h      AX = 0x0AAB  (...10101011)
XOR BL,BL      BL = 0x00
SUB BL,2       BL = 0xFE
IMUL BL        AX = 0xFFAB * 0xFFFE = 0x00AA
MOV Ris5,AX    Ris5 = 0x00AA

когда вы объединяете два N-битных числа, младшие N-биты не заботятся о знаковых и беззнаковых знаках, но когда вы дополняете числа, вы попадаете в умноженные со знаками и беззнаковыми команды, как вы увидите в некоторых наборах команд. Чтобы не потерять точность, нужно получить 2 * N числа битов, математика начальной школы:

   00000000aaaaaaaa
*  00000000bbbbbbbb
=====================

   AAAAAAAAAAaaaaaa
*  BBBBBBBBBBbbbbbb
====================

подписано против неподписанного с большой буквы, представляющей расширение знака

0xAB = 171 без знака = -85 со знаком

0xFE = 254 без знака = -2 со знаком

умножение без знака 171 * 254 = 43434 = 0xA9AA

умноженное со знаком -85 * -2 = 170 = 0x00AA

младший байт такой же, как и 8-битные операнды, и расширение знака не вступает в игру:

         bbbbbbbb *a[0]
        bbbbbbbb  *a[1]
       bbbbbbbb   *a[2]
      bbbbbbbb    *a[3]
     bbbbbbbb     *a[4]
    bbbbbbbb      *a[5]
   bbbbbbbb       *a[6]
+ bbbbbbbb        *a[7]
==================
 cyyyyyyyxxxxxxxx       

Если вы посмотрите столбцы, расширение х не будет затронуто расширением знака, поэтому одинаково для неподписанного и подписанного. На биты y влияют так же как на выполнение msbit c, который составляет 16-й бит результата.

Теперь инструмент не жалуется на этот синтаксис:

Mat = 0A2A(hexadecimal)

без h в конце или 0x или $ спереди, которое выглядит как восьмеричное, но А вызывает ошибку, если восьмеричное (или десятичное). Предполагая, что вы начинаете с 0x0A2A, я думаю, что вы хорошо понимаете.

...