Я извлекаю уроки 80386 из блока ПК paul caurter
mul source
- Если операнд является измеренным байтом, он умножается на байт в регистре AL, и результат хранится в 16 битах AX.
отлично.
- Если источник является 16-разрядным, он умножается на слово в AX, и 32-разрядный результат хранится в DX:AX.
Q1: Почему DX:AX? Почему это не может сохранить в EAX / EDX?
imul
действительно сбивает с толку
imul dest, source1
imul dest, source1, source2
У меня есть проблема в понимании таблицы.
Q2: в 2-й записи таблицы. Снова, почему DX:AX. Почему не EAX или EDX?
Теперь рассмотрите следующий фрагмент кода:
imul eax ; edx:eax = eax * eax
mov ebx, eax ; save answer in ebx
mov eax, square_msg ; square_msg db "Square of input is ", 0
call print_string ; prints the string eax
mov eax, ebx
call print_int ; prints the int stored in eax
call print_nl ; prints new line
Q3: Его previsously сказанный это The notation EDX:EAX means to think of the EDX and EAX registers as one 64 bit register with the upper 32 bits in EDX and the lower bits in EAX.
Таким образом, ответ также хранится в edx, правильно? в вышеупомянутом коде мы не рассматривали EDX, который мы просто отсылаем к EAX, Как это все еще работает?
Q4: у меня есть проблема с отдыхом всех записей в таблице. худший результат умножения случая двух n укусил числа (n = 16.08.32, биты) 2n биты. Каким образом его хранение результата двух умножения на 16/32 бита приводит к регистру того же размера самого?
Q1/Q2: Набор команд x86 сохраняет свою 16-битную историю. При 16-битном умножении ответ хранится в DX:AX. Так оно и есть, потому что так оно и было в 16-битной стране.
Q3: Код, который вы показали, имеет ошибку при попытке вычислить квадрат числа больше 2^16, потому что код игнорирует старшие 32 бита результата, сохраненного в edx
.
Q4: Я думаю, что вы можете неправильно прочитать таблицу. 8-битные умножения хранятся в 16-битном результате; 16-битные умножения хранятся в 32-битном результате; 32-битные умножения хранятся в 64-битном результате. На какую именно строку Вы ссылаетесь?
.Существует множество различных вариантов битового кода imul instruction.2.
Вариант, на который вы наткнулись, это 16-битное умножение. Он умножает регистр AX с тем, что вы передаете в качестве аргумента для имитации, и сохраняет результат в DX:AX.
Один 32-битный вариант работает как 16-битное умножение, но записывает регистр в EDX:EAX. Для использования этого варианта достаточно использовать 32-битный аргумент.
Например:
; a 16 bit multiplication:
mov ax, [factor1]
mov bx, [factor2]
imul bx ; 32-bit result in DX:AX
; or imul word [factor2]
; a 32 bit multiplication:
mov eax, [factor1]
mov ebx, [factor2]
imul ebx ; 64-bit result in EDX:EAX
На 386 или более поздней версии вы также можете записать imul
в виде двух операндов. Это делает его гораздо более гибким и легким в работе. В этом варианте вы можете свободно выбирать любые 2 регистра в качестве исходного и конечного, и процессор не будет тратить время на написание полуфинального результата нигде. И не уничтожит EDX.
mov ecx, [factor1]
imul ecx, [factor2] ; result in ecx, no other registers affected
imul ecx, ecx ; and square the result
Или для подписанных 16-битных входов в соответствии с вашим имулом
. (используйте movzx для неподписанных входов)
movsx ecx, word [factor1]
movsx eax, word [factor2] ; sign-extend inputs to 32-bit
imul eax, ecx ; 32-bit multiply, result in EAX
imul eax, eax ; and square the result
Этот вариант имула был введен с 386, и доступен в 16- и 32-битных размерах операндов. (И размер 64-битного операнда в 64-битном режиме).
В 32-битном коде всегда можно предположить, что доступны 386 инструкций типа imul reg, reg/mem
, но его можно использовать в 16-битном коде, если Вас не волнуют старые CPU.
286 ввел 3-операционный и немедленный вид.
imul cx, bx, 123 ; requires 286
imul ecx, ebx, 123 ; requires 386
Q1/Q2: Я думаю, что причина историческая. До того, как 32-битный вариант был опцией, не было ни воска, ни редактора. 32-битная функциональность была добавлена для обратной совместимости.
Q3: биты низкого порядка будут в eax. Это единственные, о которых вы беспокоитесь, если только не произойдет переполнение в старшие биты.
Q4: Определенно нечетная таблица. Думаю, вы ее поняли.
A1: mul
изначально присутствовал на процессорах 8086/8088/80186/80286, на которых не было E** (E для расширенного, i. e. 32-битные) регистры.
A2: См. A1.
Поскольку моя работа в качестве программиста ассемблерного языка перешла в семейство Motorola 680x0 до того, как эти 32-битные Intels стали обычным я остановлюсь на этом :-)
.