Арифметические команды ассемблера. Иллюстрированный самоучитель по Assembler Команды арифметического вычитания SUB и SBB

ADC Целочисленное сложение с переносом

Команда adc осуществляет сложение первого и второго операндов, прибаатяя к результату значение флага переноса CF. Исходное значение первого операнда (приемника) теряется, замещаясь результатом сложения. Второй операнд не изменяется. В качестве первого операнда команды adc можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами и представлять числа со знаком или без знака. Команда adc (совместно с командой add) обычно используется для сложения 32-разрядных чисел. Команда воздействует на флаги OF, SF, ZF, AF, PF и CF.

Пример 1

Mov AX,1125h adc AX,2C25h ;AX=3D4Bh, если CF был = 1 ;AX=3D4Ah, если CF был = 0
Пример 2 ; В полях данных: numlow dw 0FFFFh ;Младшая часть 2-го слагаемого numhigh dw 000Sh ;Старшая часть 2-го слагаемого;Число 0005FFFFh=393215 ;В программном сегменте: mov AX,000Sh ;Младшая часть 1-го слагаемого mov BX,0002h ;Старшая часть 1-го слагаемого;Число 00020005h=131077 add АХ,numlow ;Сложение младших частей. АХ=4, CF=1 adc BX, numhigh ;Сложение старших частей с;переносом.ВХ:АХ=0008:0004h. ;Число 00080004h=524292
Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Команда adc с 32-разрядными операндами может использоваться для сложения 64-разрядных целых чисел. Пример 3 ; В полях данных mem321 dd 0FFFFFFFFh ;Младшая часть 1-го слагаемого mem32h dd 98765432h ;Старшая часть 1-го слагаемого; В программном сегменте mov EAX,1 ;Младшая часть 2-го слагаемого mov EBX,0 ;Старшая часть 2-го слагаемого add EAX,mem321 ;Складываем младшие половины;Сумма=100000000Ь>32 бит;EAX=000000h, перенос adc EBX,mem32h ;Складываем старшие половины;и перенос. EBX=90000001h ;Сумма: 9876543300000000h
ADD Целочисленное сложение

Команда add осуществляет сложение первого и второго операндов. Исходное значение первого операнда (приемника) теряется, замещаясь результатом сложения. Второй операнд не изменяется. В качестве первого операнда команды add можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячей-ку памяти или непосредственное значение, однако не допускается опре-делять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами и представлять числа со знаком или без знака. Команду add можно использовать для сложения как обычных целых чи-сел, так и двоично-десятичных (с использованием регистра АХ для хра-нения результата). Если складываются неупакованные двоично- десятич-ные (BCD) числа, после команды add следует использовать команду ааа; если складываются упакованные числа, то команду daa. Команда воздействует на флаги OF, SF, ZF, AF, PF и CF. Пример 1

Mov BX,lFFEh mov CX,3 add BX,CX ;BX=2001h, CX=0003h
Пример 2 mov AX,25h add AX,12h ;AX=0037h
Пример 3 ; В полях данных: mem dw 128 ;B программном сегменте: add mem,100 ;mem=228
Пример 4 mov AX,0507h ;BCD распакованное 57 add AL,05h ;BCD 5, AX=050Ch aaa ;AX=0602h, BCD 62
Пример 5 mov AL,57h ;BCD упакованное 57 add AL,05h ;BCD 5, AL=5Ch daa ;AL=62h, BCD 62

Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример

Mov EAX,98765432h add EAX,11111111h ; EAX=A9876543h
AND Логическое И

Команда and осуществляет логическое (побитовое) умножение первого операнда на второй. Исходное значение первого операнда (приемника) теряется, замещаясь результатом умножения. В качестве первого операнда команды and можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами. Команда воздействует на флаги SF, ZF и PF. Правила побитового умножения:

Первый операнд-бит 0101 Второй операнд-бит 0011 Бит результата 0001 Пример 1 mov AX,0FFEh and AX,5555h ;AX=0554h Пример 2 ; В полях данных: mem dw 0С003h ;В программном сегменте: mov AX,700Eh and AX,mem ;AX=4002h

Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример

Mov EDX, 0FA8 8 0 0 4 lh and EDX,0FF00000Fh ; EDX = FA000001h
386P+ ARPL
Коррекция запрашиваемого уровня привилегий селектора

Команда aprl сравнивает селектор с образцом, содержащим максимально допустимый уровень привилегий (обычно используется селектор CS) и устанавливает проверяемое значение в соответствии с меньшим из двух уровней привилегий. Если изменение уровня не потребовалось, флаг ZF сбрасывается, если потребовалось - устанавливается. В качестве первого операнда команды aprl может использоваться 16-разрядный регистр или слово памяти с проверяемым селектором; в качестве второго операнда - 16-разрядный регистр с селектором-образцом. 386+ BOUND
Проверка индекса массива на выход за границы массива

Команда bound проверяет, лежит ли указанный индекс, рассматриваемый, как число со знаком, внутри заданных вторым операндом границ. Если индекс выходит за границы массива снизу или сверху, генерируется прерывание с вектором 5. Первый операнд должен быть регистром, содержащим проверяемый индекс, второй - адресом поля памяти с двумя границами проверяемого массива. В команде bound допустимо использование как 16-битовых, так и 32-битовых операндов (но и первый, и второй операнды должны быть одного типа).

Команда ADC (Add with Carry) относится к группе команд целочисленной (или двоичной ) арифметики (Binary Arithmetic Instructions ) и производит целочисленное сложение двух знаковых или беззнаковых операндов (DEST и SRC ) и флага переноса EFLAGS.CF . Первый операнд (операнд-назначение , DEST ) может быть переменной в регистре или в памяти ( , r16 , r32 , r/m8 , r/m16 , r/m32 ). Второй операнд (операнд-источник , SRC ) — непосредственным значением (imm8 , imm16 , imm32 ), переменной в регистре или в памяти. При этом оба операнда одновременно не могут быть переменными в памяти.

Результат сложения командой ADC помещается на место первого операнда (DEST ). Флаги в регистре EFLAGS устанавливаются в соответствии с полученным результатом.

При сложении непосредственного значения imm8 или imm16 с двухбайтным или четырехбайтным операндом непосредственная величина прежде всего знакорасширяется до размера первого операнда, и только после этого выполняется сложение.

Команда ADC обычно используется в многобайтных или многословных (multi-word ) операциях сложения. В таком случае она идет вслед за командой ADD , которая возвращает сумму младших разрядов многобайтных (многословных) операндов, позволяя при сложении старших разрядов учитывать перенос. Например:

mov edx, 0 ; EDX = 0
mov eax, 0FFFFFFFFh ; первое 32-битное слагаемое помещаем в EAX
add eax, 0FFFFFFFFh ; второе 32-битное слагаемое - 0xFFFFFFFFh, производим сложение двух 32-битных операндов
adc edx, 0 ; EDX = EDX + CF, учитываем перенос
; EDX:EAX = 0000000lh:FFFFFFFEh - полученный 64-битный результат

Команда ADC позволяет манипулировать целочисленными операндами как в беззнаковом формате , так и в формате со знаком . При сложении данных со знаком флаг знака EFLAGS.SF будет отражать знак полученного результата. Флаг переполнения EFLAGS.OF установится в 1, если при сложении целочисленных значений со знаком , представленных в обратном коде или в дополнительном коде , произошло переполнение (перенос из старшего значащего разряда, которому соответствует бит, предшествующий разряду знака), то есть полученный результат превышает доступный размер операнда-назначения (DEST ). По сути, это аналогично тому, как флаг EFLAGS.CF отражает переполнение (перенос) при сложении беззнаковых операндов . Например, при сложении двух 32-битных значений, представленных в обратном коде , это может выглядеть следующим образом:

mov eax, operand1 ; EAX = operand1, первое 32-битное слагаемое помещаем в EAX
add eax, operand2 ; производим сложение двух 32-битных операндов в обратном коде
into ; переход к обработчику прерывания в случае переполнения

adc eax, 0 ; EAX = EAX + CF, учитываем перенос (необходимо для сложения в обратном коде)
; EAX = operand1 + operand2 - результат сложения в обратном коде
jns m1 ; переход, если результат положительный
xor eax, 7FFFFFFFh ; преобразование отрицательного значения в EAX к прямому коду
m1: ; EAX - результат сложения в прямом коде

Флаг вспомогательного (или дополнительного ) переноса EFLAGS.AF помогает манипулировать данными в двоично-десятичном формате (упакованный BCD-формат ). Он устанавливается, если при сложении возникает перенос из младшей тетрады в старшую тетраду младшего байта результата. Используя команду DAA сразу же вслед за командой ADC , можно произвести так называемую десятичную коррекцию результата сложения и получить сумму в таком же упакованном BCD-формате , как и исходные слагаемые.

Команда ADC с операндом-назначением (DEST ), являющимся переменной в памяти, может использоваться совместно с префиксом блокировки LOCK , который обеспечит атомарное исполнение команды.

Команды сложения - ADD, ADC

Команды ADD (add - сложить) и ADC (add with carry- сложить с переносом) могут складывать как 8-, так и 16-битовые операнды.

Команда ADD складывает содержимое операнда-источника и операнда-приемника и помещает результат в операнд-приемник.

Формат команды: ADD приемник, источник

В символической нотации ее действия можно описать следующим образом: приемник:= приемник + источник (в приемник записывается сумма содержимого приемника и источника).

Команда ADC делает то же, что и команда ADD, но складывает не два, а три слагаемых: приемник, источник и флаг переноса.

Формат команды: ADC приемник, источник + CF

В символической нотации ее действия можно описать как:

приемник:= приемник + источник + содержимое флага переноса.

Перенос при сложении двоичных чисел аналогичен переносу при сложении десятичных чисел в столбик. Когда ЭВМ складывает двоичные числа и сумма не помещается в операнде-приемнике, то генерируется перенос. Как известно, 8-битовый регистр может содержать значения без знака в диапазоне от 0 до 255. Если мы, например, выполним двоичное сложение чисел 250 и 10, то получим следующий результат:

1111 1010; двоичное представление числа 250.

0000 1010 ; двоичное представление числа 10.

1 0000 0100; двоичное представление суммы, равной 260.

Результат верен, но занимает 9 двоичных битов. Если использовались 8 - битовые регистры, то младшие 8 битов будут занесены в регистр-приемник, а девятый бит- во флаг переноса CF.

Теперь понятно, почему микропроцессор 8086 имеет две разные команды сложения. Одна из них (ADD) может складывать значения, представляемые байтами или словами, а также младшие части значений повышенной точности. Другая команда (ADC) используется для сложения старших частей значений повышенной точности.

Складываемые операнды могут находиться в памяти, регистре или иметь непосредственное значение. Например:

ADD АХ,MEM_WORD; прибавить содержимое ячейки памяти к регистру,

ADD MEM_WORD,AX; или наоборот, прибавить содержимое регистра к ячейки памяти.

ADD AL, 10; прибавить константу к содержимому регистра.

ADD MEM_BYTE,8H; сложить константу и содержимое ячейки памяти.

Допускается большинство возможных комбинаций, но нельзя складывать содержимое двух ячеек памяти или использовать в качестве приемника непосредственное значение (число).

Команды ADD и ADC могут воздействовать на следующие шесть флагов:

флаг переноса CF равен 1, если результат сложения не помещается в операн­де-приемнике, в противном случае он равен 0;

флаг четности PF равен 1, если результат имеет четное число битов со значением 1, в противном случае он равен 0;

AF равен 1, если результат сложения десятичных чисел требует коррекции;

флаг нуля ZF равен 1, если результат равен 0;

флаг знака SF равен 1, если результат отрицателен (старший бит равен 1), в противном случае он равен 0;

флаг переполнения OF равен 1, если слагаемое двух чисел одного знака превышает диапазон допустимых значений приемника в обратном коде, а сам приемник при этом меняет знак. Иначе флаг OF равен 0.

Команда увеличения значения приемника на единицу – INC

Команда INC (increment - прирастить) добавляет 1 к содержимому регистра или ячейки памяти, но в отличие от команды ADD не воздействует на флаг переноса CF. Формат команды: INC приемник .

Команда INC удобна для увеличения значений счетчиков в циклах команд. Ее можно использовать и для увеличения значения индексного регистра при доступе к последовательно расположенным ячейкам памяти. Операнд интерпретируется как число без знака.

Например:

INC CX; увеличить значение 16-битового

INC AL; или 8-битового регистра на единицу.

INC MEM_BYTE; увеличить значение байта

INC MEM_WORD; или слова памяти на единицу.

Не допускается использовать в качестве операнда непосредственное значение.

Команды вычитания - SUB, и вычитания с заемом SBB

Команды SUB (substract - вычесть) и SBB (substract with borrow - вычесть с заемом) аналогичны соответственно командам сложения ADD и ADC, только при вычитании флаг переноса CF действует как признак заема. Формат команды: SUB приемник,источник;

Команда SUB вычитает операнд -источник из операнда -приемника и помещает результат в приемник, в символической нотации:

приемник:= приемник – источник.

Команда SBB делает то же самое, но дополнительно вычитает из приемника значение флага переноса CF:

SUB приемник,источник – СF;

Приемник:= приемник - источник - содержимое флага переноса.

Как и в случае сложения, команды SUB и SBB выполняют две отдельные функции. Первая команда вычитает числа размером в байт или слово, а также младшие биты чисел повышенной точности (младшая часть числа расположена в регистре АХ, а старшая часть в регистре DX). Вторая команда вычитает старшие биты чисел повышенной точности. Например, команда SUB AX,CX; вычитает содержимое регистра СХ из содержимого регистра АХ и возвращает результат в регистр АХ.

Если размеры операндов превышают 16 бит, то необходимо применить следующую последовательность команд:

SUB АХ,CX; Вычесть младшие 16 бит;

SBB BX,DX; а затем старшие 16 бит.

Здесь мы вычитаем из 32-битового числа, помещенного в регистры АХ и ВХ, 32-битовое число, находящееся в регистрах СХ и DX. При вычитании содержимого регистра DX из содержимого регистра ВХ команда SBB учитывает возможность заема при выполнении первого вычитания.

SUB АХ, MEM; Вычесть из регистра содержимое ячейки памяти.

SUB MEM ,AX; Вычесть из ячейки памяти регистр.

SUB AL,1O; Вычесть константу из регистра.

SUB MEM_BYTE,OFh; Вычесть константу из ячейки памяти.

Нельзя непосредственно вычесть содержимое одной ячейки памяти из другой или использовать непосредственное значение как приемник.

Команды SUB и SBB могут воздействовать на шесть флагов следующим образом:

· устанавливают флаг переноса CF в 1, если требуется заем, в противном случае он равен 0;

· устанавливают флаг четности PF в 1, если результат вычитания имеет четное число битов со значением 1, в противном случае он равен 0;

· устанавливают вспомогательный флаг переноса AF в 1, если результат вычитания десятичных чисел требует коррекции, в противном случае он равен 0;

· устанавливают флаг нуля ZF в 1, если результат равен 0, в противном случае он равен 0;

· устанавливают флаг знака SF в 1, если результат отрицателен (старший бит равен 1), в противном случае флаг равен 0;

· устанавливают флаг переполнения OF в 1, если при вычитании результат превышает диапазон значений приемника в обратном коде, а сам приемник изменяет знак.

Флаги SF и OF имеют смысл только при вычитании чисел со знаком, а флаг AF- только при вычитании десятичных чисел.

Команда уменьшения содержимого приемника - DEC

КомандаDEC приемник (decrement-уменьшить) вычитает 1 из содержимого регистра или ячейки памяти, но при этом (в отличие от команды SUB) не воздействует на флаг переноса CF.

Команда DEC часто используется в циклах для уменьшения значения счетчика до тех пор, пока оно не станет нулевым или отрицательным. Ее можно использовать также для уменьшения значения индексного регистра или указателя при доступе к последовательно расположенным ячейкам памяти. Например:

DEC CX; Уменьшить значение 16-битового,

DEC AL; или 8-битового регистра.

DEC MEM_BYTE; Уменьшить значение байтовой,

DEC MEM_WORD; или словной ячейки памяти.

Команды деления - DIV, IDIV

КомандаDIV (divide - разделить) выполняет деление чисел без знака, а команда IDIV (integer divide - разделить целые числа) выполняет деление чисел со знаком. Эти команды имеют формат:

DIV источник ; где источник - делитель размером в байт или слово,

IDIV источник ;находящийся в регистре общего назначения или в ячейке памяти.

Обратите внимание на следующее:

1. Делимое по отношению к делителю должно иметь двойной размер.

2. Делимое всегда должно находиться в регистре АХ (при делении на 8-битовое число) или в регистрах DX и АХ (при делении на 16-битовое число).

3. Результаты команды возвращаются следующим образом:

· если операнд-источник представляет собой байт, то частное возвращается в регистр AL, а остаток в регистр АН;

· если операнд-источник представляет собой слово, то частное возвращается в регистр АХ, а остаток - в регистр DX.

Обе команды оставляют состояние флагов неопределенными, но если частное не помещается в регистре-приемнике (AL или АХ), то микропроцессор генерирует прерывание типа 0 (деление на 0).

4. Переполнение результата деления возникает при следующих условиях:

· делитель равен 0;

· при делении байтов без знака делимое, по меньшей мере, в 256 раз превышает делитель;

· при делении слов без знака делимое, по меньшей мере, в 65 536 раз превышает делитель;

· при делении байтов со знаком частное лежит вне диапазона -128 до +127;

· при делении слов со знаком частное лежит вне диапазона от

32768 до 32767.

Приведем несколько типичных примеров операций деления:

DIV BX; Разделить DX:AX на ВХ, без знака.

DIV MEM_BYTE; Разделить АХ на байт памяти, без знака.

IDIV DL; Разделить АХ на DL со знаком.

IDIV MEM WORD; Разделить DX:AX на слово памяти, со знаком.

Команды DIV и IDIV не позволяют прямо разделить на непосредственное значе­ние, так как процессор не может определить тип данных делителя.

Команды умножения - MUL, IMUL

Команда MUL (multiply-умножить) умножает числа без знака, a IMUL (integer multiply-умно­жить) умножает целые числа со знаком. Множимое и множитель у обеих команд должны быть данные одного типа, то есть байты, слова, двойные слова и т. д.

Эти команды имеют следующий формат:

MUL источник ; гдеисточник - регистр общего назначения,

IMUL источник ; или ячейка памяти размером в байт или слово.

В качестве первого операнда (множимого) команды MUL и IMUL используют содер­жимое регистра AL (при операциях над байтами) или регистра АХ (при операциях над словами). Произведение имеет двойной размер и возвращается следующим образом:

· умножение байтов -возвращает 16-битовое произведение в регистры АН (старший байт) и AL (младший байт);

· умножение слов -возвращает 32- битовое произведение в регистры DX (старшее слово) и АХ (младшее слово). Таким образом, размер произведения n - битных сомножителей равен 2n.

ADC Целочисленное сложение с переносом

Команда adc осуществляет сложение первого и второго операндов, прибавляя к результату значение флага переноса CF. Исходное значение первого операнда (приемника) теряется, замещаясь результатом сложения. Второй операнд не изменяется. В качестве первого операнда команды adc

Операнды могут быть байтами или словами и представлять числа со знаком или без знака. Команда adc (совместно с командой add ) обычно используется для сложения 32-разрядных чисел. Команда воздействует на флаги OF, SF, ZF, AF, PF и CF.

Пример 1 :

Mov AX,1125h adc AX,2C25h; AX=3D4Bh, если CF был = 1 ;AX=3D4Ah, если CF был = 0

Пример 2 :

; В полях данных: numlow dw 0FFFFh; Младшая часть 2-го слагаемого numhigh dw 000Sh; Старшая часть 2-го слагаемого;Число 0005FFFFh=393215 ;В программном сегменте: mov AX,000Sh; Младшая часть 1-го слагаемого mov BX,0002h; Старшая часть 1-го слагаемого;Число 00020005h=131077 add АХ,numlow; Сложение младших частей. АХ=4, CF=1 adc BX, numhigh; Сложение старших частей с переносом. ВХ:АХ=0008:0004h. ;Число 00080004h=524292

Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Команда adc с 32-разрядными операндами может использоваться для сложения 64-разрядных целых чисел.

Пример :

; В полях данных mem321 dd 0FFFFFFFFh; Младшая часть 1-го слагаемого mem32h dd 98765432h; Старшая часть 1-го слагаемого; В программном сегменте mov EAX,1; Младшая часть 2-го слагаемого mov EBX,0; Старшая часть 2-го слагаемого add EAX,mem321; Складываем младшие половины;Сумма=100000000h>32 бит;EAX=000000h, перенос adc EBX,mem32h; Складываем старшие половины и перенос. EBX=90000001h; Сумма: 9876543300000000h

ADD Целочисленное сложение

Команда add осуществляет сложение первого и второго операндов. Исходное значение первого операнда (приемника) теряется, замещаясь результатом сложения. Второй операнд не изменяется. В качестве первого операнда команды add можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти.

Операнды могут быть байтами или словами и представлять числа со знаком или без знака. Команду add можно использовать для сложения как обычных целых чи-сел, так и двоично-десятичных (с использованием регистра АХ для хра-нения результата). Если складываются неупакованные двоично-десятичные (BCD) числа, после команды add следует использовать команду ааа; если складываются упакованные числа, то команду daa . Команда воздействует на флаги OF, SF, ZF, AF, PF и CF.

Пример 1 :

Mov BX,lFFEh mov CX,3 add BX,CX; BX=2001h, CX=0003h

Пример 2 :

Mov AX,25h add AX,12h; AX=0037h

Пример 3 :

; В полях данных: mem dw 128 ;B программном сегменте: add mem,100; mem=228

порты нумеруются от 0 до 0FFFFh. С каждым внешним устройством связан свой порт или несколько портов, их адреса заранее известны.

Запись и чтение порта осуществляется при помощи следующих команд:

(вывод):OUT

Номер порта n в этих командах может быть задан либо непосредственно, либо регистром DX.

Сценарий ввода вывода через порты существенно зависит от специфики того внешнего устройства, с которым ведется обмен, но обычно ЦП связан с внешним устройством через два порта: первый – порт данных, второй – порт управления и достаточно типичной является следующая процедура обмена:

ЦП записывает в порт управления соответствующую команду, а порт данных – выводимые данные;

внешнее устройство, считав эту информацию, записывает в порт управления команду «занято» и начинает непосредственно вывод (например, печать);

ЦП переходит либо в режим ожидания, опрашивая в цикле порт управления, либо занимается другой работой – до тех пор пока в порте управления не сменится сигнал «занято»;

внешнее устройство заканчивает вывод и записывает в порт управления сигнал об успешном завершении или об ошибке;

ЦП анализирует полученную информацию и продолжает свою

6. Арифметические команды

Все арифметические команды устанавливают флаги CF, AF, SF, ZF, OF и PF в зависимости от результат операции.

Двоичные числа могут иметь длину 8 и 16 бит. Значение старшего (самого левого бита) задает знак числа: 0 – положительное, 1 – отрицательное. Отрицательные числа представляются в так называемом дополнительном коде, в котором для получения отрицательного числа необходимо инвертировать все биты положительного числа и прибавить к нему 1. Пример:

6.1. Команды арифметического сложения ADD и ADC

Команда ADD выполнят целочисленное сложение двух операндов, представленных в двоичном коде. Результат помещается на место первого операнда, второй операнд не изменяется. Команда корректирует регистр флагов в соответствии с результатом сложения. Существуют две формы сложения: 8-битовое и 16-битовое. В различных формах сложения принимают участие различные регистры. Компилятор следит за тем, чтобы операнды соответствовали друг другу. На следующих рисунках иллюстрируются различные варианты команды ADD.

Рис. 6.2. 8-битовое сложение.

Рис. 6.1. 16-битовое сложение

Команда сложения с переносом ADC – это та же команда ADD, за исключением того, что в сумму включается флаг переноса CF, который прибавляется к младшему биту результата. Для любой формы команды ADD существует аналогичная ей команда ADC. Команда ADC часто выполняется как часть многобайтной или многословной операции сложения.

Примеры использования команд ADD и ADC:

ADD Count,1 ADC BX,4 ADD AX,BX ADC Count,DI

6.2. Команды арифметического вычитания SUB и SBB

Команда вычитания SUB – идентична команде сложения, за исключением того, что она выполняет вычитание, а не сложение. Для нее верны предыдущие схемы, если в них поменять знак «+» на «–», т. е. она из первого операнда вычитает второй и помещает результат на место первого операнда. Команда вычитания также устанавливает флаги состояния в соответствии с результатом операции (флаг переноса здесь трактуется как заем). Команда вычитания с заемом SBB учитывает флаг заема CF, то есть значение заема вычитается из младшего бита результата.

Примеры использования команд SUB и SBB:

SUB Count,1 SBB BX,4 SUB AX,BX SBB Count,DI

6.3. Команда смены знака NEG

Команда отрицания NEG – оператор смены знака. Она меняет знак двоичного кода операнда – байта или слова.

6.4. Команды инкремента INC и декремента DEC

Команды инкремента и декремента изменяют значение своего единственного операнда на единицу. Команда INC прибавляет 1 к операнду, а команда DEC вычитает 1 из операнда. Обе команды могут работать с байтами или со словами. На флаги команды влияния не оказывают.

6.5. Команды умножения MUL и IMUL

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

Рис. 6.4. Умножение байт.

Рис. 6.3. Умножение слов.

При умножении 8-битовых операндов результат всегда помещается в регистр AX. При умножении 16-битовых данных результат, который может быть длиною до 32 бит, помещается в пару регистров: в регистре DX содержатся старшие 16-бит, а в регистре AX – младшие 16-бит. Умножение не допускает непосредственного операнда.

Установка флагов командой умножения отличается от других арифметических команд. Единственно имеющие смысл флаги – это флаг переноса и переполнения.

Команда MUL устанавливает оба флага, если старшая половина результата не нулевая. Если умножаются два байта, установка флагов переполнения и переноса показывает, что результат умножения больше 255 и не может содержаться в одном байте. В случае умножения слов флаги устанавливаются, если результат больше 65535.

Команда IMUL устанавливает флаги по тому же принципу, т. е. если произведение не может быть представлено в младшей половине результата, но только в том случае если старшая часть результата не является расширением знака младшей. Это означает, что если результат положителен, флаг устанавливается как в случае команды MUL. Если результат отрицателен, то флаги устанавливаются в случае, если не все биты кроме старшего, равны 1. Например, умножение байт с отрицательным результатом устанавливает флаги, если результат меньше

Примеры использования команд умножения.

Loading...Loading...