Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
мпс с 1 по 294.doc
Скачиваний:
13
Добавлен:
16.04.2019
Размер:
6.2 Mб
Скачать

2.2.2. Команды арифметических операций

Команды данной группы приведены в табл. 2.16. При выполнении команд производится установка признаков OF, SF, ZF, AF, DF, CF в регистре EFLAGS в соответствии с табл. 2.17.

Таблица 2.16

Команды сложения, вычитания (ADD, SUB) и сложения, вычитания с переносом/заемом (ADC, SBB), учитывающие значение признака CF, имеют несколько модификаций для различ­ных вариантов адресации операндов. Отметим, что при операциях, использующих 16- или 32-разрядный операнд, хранящийся в регистре или памяти, и непосредственно заданный 8-раз­рядный операнд \tr\8, производится его знаковое расширение до разрядности слова или двой­ного слова.

При выполнении команды сравнения СМР производится вычитание содержимого адресуемых регистров и ячеек памяти без их изменения, и устанавливаются значения признаков в регистре EFLAGS, определяющих результат сравнения. При равенстве операндов устанавливается значение ZF = 1, при неравенстве -ZF = 0. Если при сравнении операндов

без знака уменьшаемое выше (больше) вычитаемого, то устанавливается значение CF = О, если уменьшаемое ниже (меньше) вычитаемого, то CF = 1. Если при сравнении операндов со знаком уменьшаемое больше вычитаемого, то устанавливаются значения SF = OF = 0 или SF = OF = 1; если меньше, то SF = О, OF = 1 или SF = 1, OF = 0.

Для умножения 8-, 16- или 32-разрядных операндов используются одноадресная ко­манда MUL и команда IMUL, имеющая одно-, двух- или трехадресную форму. Команда MUL служит для умножения без знаковых операндов, команда IMUL -для умножения операндов со знаком.

В одноадресных командах MUL и IMUL один из сомножителей и произведение размещаются в аккумуляторе: AL, АХ или ЕАХ в соответствии с разрядностью операндов. Так как разрядность произведения может вдвое превышать разрядность операндов, то для его размещения производится расширение аккумулятора AL -> АХ, АХ -> DX:AX, ЕАХ -> EDX: EAX. При этом 16-разрядное произведение 8-разрядных операндов заносится в AL (младшие разряды), АН (старшие разряды), 32-разрядное произведение - в АХ (млад­шие разряды), DX (старшие разряды), 64-разрядное произведение - в ЕАХ (младшие разряды), EDX (старшие разряды).

При двух- и трехадресной формах команды IMUL операндами служат 16- или 32-разрядные числа. Один операнд выбирается из регистра, в качестве второго операнда при двухадресной форме служит либо содержимое регистра или адресуемой ячейки памяти, либо непосредственный операнд im. При трехадресной форме содержимое регистра или ячейки памяти является вторым сомножителем, а непосредственный операнд-третьим. Если в качестве непосредственного операнда используется 8-разрядное число im8, то оно преобразуется до заданной разрядности (16 или 32) путем расширения знака. Произведение размещается в 16- или 32-разрядном регистре, указанном в поле операнда. Так как при этом старшие 16-го или 32-го разряда произведения теряются, то после умножения следу­ет проверять значение признака переполнения OF.

При выполнении команд MUL, IMUL признаки OF, CF устанавливаются в единицу, если разрядность результата превышает разрядность регистров, используемых для его разме­щения. Команды MUL, IMUL различаются условиями установки этих признаков. При выпол­нении без знакового умножения командой MUL устанавливаются значения OF = CF = 1, если старшая половина произведения не равна нулю, OF = CF = 0, если все разряды старшей половины равны нулю. При выполнении знакового умножения командой IMUL уста­навливаются значения OF = CF = 1, если старшая половина произведения не является расширением знака младшей половины, OF = CF = 0, если во всех разрядах старшей поло­вины повторяются значения старшего бита (знака) младшей половины.

Команды деления DIV и IDIV имеют только одноадресную форму, причем разрядность делимого, которое размещается в аккумуляторе с расширением, должна вдвое превышать разрядность делителя (8,16 или 32 разряда). Реализуемое при этом размещение делимо­го, результата и остатка указано в табл. 2.16. Знак остатка при выполнении команды IDIV устанавливается равным знаку делимого. Дробное частное округляется до целого значе­ния отбрасыванием его дробной части. Если делитель равен нулю или разрядность част­ного превышает разрядность аккумулятора (AL, АХ или ЕАХ), то выполняется прерывание типа #DE (ошибка деления).

Команды CBW/CWDE и CWD/CDQ осуществляют преобразование хранящегося в акку­муляторе байта (AL), слова (АХ) или двойного слова (ЕАХ) соответственно в одинарное, двой­ное или четверное слово (16,32 или 64 разряда) путем расширения знакового разряда. При выполнении команд CBW, CWDE расширенный операнд остается в аккумуляторе: AL в АХ или АХ в ЕАХ. При выполнении команд CWD, CDQ расширение АХ, ЕАХ производится в регистры DX или EDX, куда заносится старшая половина (расширенный знак) результата. Команды CBW, CWD реализуются, когда процессор работает в режимах реальных адресов или виртуального 8086 (обработка 16-разрядных слов). Команды CWDE, CDQ выполняются в защищенном режиме (обработка 32-разрядных слов). Эти операции обычно производятся перед выполнением команды IDIV для образования из 8-, 16- или 32-разрядных операндов делимого удвоенной разрядности.

Команды ААА, AAS, AAM, AAD обеспечивают получение правильного результата арифметических операций над неупакованными двоично-десятичными числами (от 0 до 9), значение которых представляется одним байтом. Такое представление чисел используется в коде ASCII (КОИ-7), который в младшей тетраде содержит двоичный код соответствующего десятичного числа (0 - 9), а в старшей тетраде - код 0011. Для получения правильного результата перед обработкой таких чисел в старшей тетраде устанавливается код 0000. Результат арифметических операций над двоично-десятичными числами размещается в ре- гистре АХ. После сложения, вычитания, умножения выполняются команды коррекции ААА, AAS, ДАМ, пос­ле чего в младшей тетраде регистра AL образуется двоичный код младшего десятичного разряда результата, а в младшей тетраде регистра АН - двоичный код старшего разряда результата. Например, после умножения чисел 9 и 7, которые в неупакованной двоично-деся­тичной форме задаются кодами 0000 1001 и 0000 0111, в регистре AL будет содержаться произведение 001111111 =63, которое после коррекции с помощью команды ААМ будет представлено в регистре АХ в следующем виде: (АН) = 00000110, (AL) = 00000111 (соответ­ственно 6 и 3 в двоично-десятичном коде). Команда AAD, в отличие от ААА, AAS, ААМ, выпол­няется перед командой DIV. При этом двоично-десятичное число, старший десятичный разряд которого расположен в регистре АН, а младший - в регистре AL, преобразуется таким образом, чтобы после команды DIV содержимое AL, АН представляло младший и старший десятичные разряды частного в неупакованной двоично-десятичной форме.

Команды DAA и DAS осуществляют коррекцию результата сложения и вычитания чисел в упакованной двоично-десятичной форме. При этом старшая и младшая тетрады байта содержат двоичные коды старшего и младшего разряда двухразрядного десятичного чис­ла. Например, число 63 в данной форме будет представлено в регистре AL кодом 01100011. После сложения упакованных двоично-десятичных чисел 63=0110 0011 и 18 = 00011000 в регистре AL будет получен код 01111011, который после выполнения команды DAA преобразуется в двоично-десятичную форму 10000001 = 81. При выполнении команд DAA и DAS учитывается значение признака переноса между тетрадами AF. После их выполне­ния устанавливается AF = 0. Следует отметить, что при использовании двоично-десятич­ного представления чисел соответствующие команды коррекции должны выполняться и после команд INC, DEC.

Команда NEG изменяет знак операнда, преобразуя его в дополнительный код. Комп­лексная команда XADD осуществляет обмен содержимым между регистром и регистром или ячейкой памяти, после чего выполняет их сложение, результат которого размещается в регистре или ячейке памяти.

Данная группа команд включает также комплексные команды сравнения/пересылки CMPXCHG, CMPXCHG8B. Команда CMPXCHG производит сравнение содержимого аккумулятора (AL, АХ или ЕАХ) и заданного в команде регистра или ячейки памяти г/т. В случае их равенства устанавливается значение признака ZF = 1, и содержимое регис­тра или ячейки памяти пересылается в 8-, 16- или 32-разрядный регистр, указанный в команде. В случае неравенства устанавливается значение ZF = 0, и содержимое регис­тра или ячейки памяти г/т пересылается в аккумулятор AL, АХ или ЕАХ (в зависимости от заданной разрядности). Команда CMPXCHG8B оперирует с 8-байтными (счетверенны­ми) словами. Она сравнивает значение счетверенных слов, хранящихся в паре регистров EDX:ECX и адресованной ячейке памяти. При их равенстве устанавливается значение ZF = 1, и по указанному адресу в ячейку памяти пересылается содержимое пары регист­ров ECX:EDX. При неравенстве устанавливается значение ZF = 0, и содержимое адресо­ванной ячейки памяти пересылается в пару регистров EDX:ECX. Отметим, что при вы­полнении команды CMPXCHG производится установка всех признаков в соответствии с результатом сравнения, а при выполнении команды CMPXCHG8B устанавливается толь­ ко признакZF (см. табл. 2.17).