Арифметические команды любого микропроцессора привлекают к себе
наибольшее внимание. Каждый заинтересован в выполнении
арифметических вычислений, и именно эти команды проделывают такую
работу. Хотя их немного, они выполняют большинство преобразований
данных а микропроцессоре. В реальных же условиях арифметические
команды занимают лишь малую часть всех исполняемых команд.
Команды пересылки используют большинство принципов работы
команд микропроцессора 8088, а при изучении арифметических команд
необходимо рассмотреть некоторые тонкости их выполнения.
Команда ADD выполняет сложение указанных операндов, представленных
в двоичном дополнительном коде. Микропроцессор помещает результат
на место первого операнда после того, как сложит оба операнда.
Второй операнд не изменяется. Команда корректирует регистр флагов
в соответствии с результатом сложения. Например, команда
ADD AX,BX
складывает содержимое регистра BX с содержимым регистра AX, и
оставляет результат в регистре AX. Регистр флагов сообщает о том,
был ли результат нулевым, отрицательным, имел ли четность, перенос
или переполнение.
Фиг. 4.8 кратко иллюстрирует варианты команды ADD.
Существуют две формы сложения, 8=битовое и 16=битовое. В различных
формах сложения принимают участие различные регистры. Ассемблер
следит за тем, чтобы операнды соответствовали друг другу.
Содержимое байтового регистра (например, CH) не может быть
прибавлено к ячейке памяти, которая не имеет тип BYTE. Если ячейка
памяти является одним из операндов, она может быть либо
операндом=результатом, либо неизменяемым операндом. Тем самым
команда может прибавить содержимое регистра к ячейке памяти и
возвратить результат в память. Одним из операндов может также быть
непосредственное значение. На Фиг. 4.9 показан листинг ассемблера с
накоторыми арифметическими командами.
Команда сложения с переносом ADC - это та же команда ADD, за
исключением того, что в сумму включается флаг переноса. Для любой
формы команды ADD существует сравнимая с ней команда ADC.
ЪДДДДДДДДї ЪДДДДДДДДї ЪДДДДДДДДї
і AX і і AX і і AX і
і BX і і BX і і BX і
і CX і і CX і ДДДДДДД> і CX і
і DX і і DX і і DX і
АДДДДДДДДЩ АДДДДДДДДЩ АДДДДДДДДЩ
ЪДДДДДДДДї + ЪДДДДДДДДї ЪДДДДДДДДї
і SI і і SI і і SI і
і DI і і DI і і DI і
і BP і і BP і ДДДДДДД> і BP і
і SP і і SP і і SP і
АДДДДДДДДЩ АДДДДДДДДЩ АДДДДДДДДЩ
ЪДДДДДДДДї
і Память і
і(слова) і
АДДДДДДДДЩ
ЪДДДДДДДДДї
іНепосред-і
іственный і
АДДДДДДДДДЩ
ЪДДДДДДДДДї ЪДДДДДДДДДї ЪДДДДДДДДДї
і AH і і AH і і AH і
і AL і і AL і і AL і
і BH і і BH і і BH і
і BL і і BL і і BL і
і CH і і CH і і CH і
і CL і + і CL і і CL і
і DH і і DH і і DH і
і DL і і DL і і DL і
АДДДДДДДДДЩ АДДДДДДДДДЩ АДДДДДДДДДЩ
ЪДДДДДДДДДї ЪДДДДДДДДДї
і Память і ДДДДДДД> і Память і
і(слова) і і(слова) і
АДДДДДДДДДЩ АДДДДДДДДДЩ
ЪДДДДДДДДДї
іНепосред-і
іственный і
АДДДДДДДДДЩ
Фиг. 4.8 Операции сложения
Обе команды сложения, как ADD, так и ADC, устанавливают равным
1 флаг переноса, если произошел перенос из старшего разряда
результата. Команда ADD складывает два операнда, не обращая
внимания на флаг переноса, а команда ADC учитывает и флаг переноса.
Если флаг переноса равен 0, результат равен результату выполнения
команды ADD. Если же флаг переноса равен 1, то результат на 1
больше результата команды ADD. Таким образом, программа может
использовать флаг переноса для операций повышенной точности.
Microsoft (R) Macro Assembler Version 5.00 1/1/80 04:00:49
Фиг. 4.9 Арифметические команды Page 1-1
PAGE ,132
TITLE Фиг. 4.9 Арифметические команды
0000 CODE SEGMENT
ASSUME CS:CODE,DS:CODE
0000 EXBYTE LABEL BYTE
0000 EXWORD LABEL WORD
0000 03 1E 0000 R ADD BX,EXWORD ; BX <- BX + [EXWORD]
0004 29 0E 0000 R SUB EXWORD,CX ; [EXWORD] <- [EXWORD] - CX
0008 12 3E 0000 R ADC BH,EXBYTE ; BH <- BH + [EXBYTE] + Carry
000C 18 0E 0000 R SBB EXBYTE,CL ; [EXBYTE] <- [EXBYTE] - CL - Carry
0010 F7 1E 0000 R NEG EXWORD ; [EXWORD] <- -[EXWORD]
0014 FE 06 0000 R INC EXBYTE ; [EXBYTE] <- [EXBYTE] + 1
0018 4E DEC SI ; SI <- SI - 1
0019 81 C7 00C8 ADD DI,200 ; DI <- DI + 200
001D 83 EC 64 SUB SP,100 ; SP <- SP - 100
0020 83 D1 0A ADC CX,10 ; CX <- CX + 10 + Carry
0023 83 1E 0000 R 14 SBB EXWORD,20 ; [EXWORD] <- [EXWORD] - 20 - Carry
0028 3B C3 CMP AX,BX ; Установка флагов по AX - BX
002A 81 FE 01F4 CMP SI,500 ; Установка флагов по SI - 500
002E F6 26 0000 R MUL EXBYTE ; AX <- AL * [EXBYTE]
0032 F7 EB IMUL BX ; DX:AX <- AX * BX
0034 F7 36 0000 R DIV EXWORD ; AX <- DX:AX / [EXWORD]
0038 F6 FD IDIV CH ; AL <- AX / CH
003A 27 DAA ; Десятичное коррекция для сложения
003B 2F DAS ; Десятичное коррекция для вычитания
003C 37 AAA ; ASCII коррекция для сложения
003D 3F AAS ; ASCII коррекция для вычитания
003E D4 0A AAM ; ASCII коррекция для умножения
0040 D5 0A AAD ; ASCII коррекция для деления
0042 98 CBW ; AX <- расширенное по знаку AL
0043 99 CWD ; DX:AX <- расширенное по знаку AX
0044 CODE ENDS
END
Фиг. 4.9 Арифметические команды
Microsoft (R) Macro Assembler Version 5.00 1/1/80 04:00:54
Фиг. 4.10 Пример вычислений с повышенной точностью Page 1-1
PAGE ,132
TITLE Фиг. 4.10 Пример вычислений с повышенной точностью
0000 CODE SEGMENT
ASSUME CS:CODE,DS:CODE
0000 ???????? VALUE1 DD ? ; Область данных размером 32 разряда
0004 ???????? VALUE2 DD ?
;----- Сложение двух 32-разрядных чисел
0008 A1 0000 R MOV AX,WORD PTR VALUE1
000B 01 06 0004 R ADD WORD PTR VALUE2,AX ; Сложение младших 16 разрядов
000F A1 0002 R MOV AX,WORD PTR VALUE1+2
0012 11 06 0006 R ADC WORD PTR VALUE2+2,AX ; Сложение старших 16 разрядов
;----- Вычитание двух 32-разрядных чисел
0016 A1 0000 R MOV AX,WORD PTR VALUE1
0019 29 06 0004 R SUB WORD PTR VALUE2,AX ; Вычитание младшей части
001D A1 0002 R MOV AX,WORD PTR VALUE1+2
0020 19 06 0006 R SBB WORD PTR VALUE2+2,AX ; Вычитание старшей части
0024 CODE ENDS
END
Фиг. 4.10 Пример с повышенной точностью
Фиг. 4.10 иллюстрирует сложение пары 32=битовых чисел; в
примере складываются 32=битовые числа поля VALUE1 и поля VALUE2, а
результат помещается в поле VALUE2. Заметим, что один из операндов
должен быть помещен в регистр. В первом сложении используеся
команда ADD, так как текущее значение флага переноса несущественно
для первого сложения. После соответствующего размещения операндов
программа на Фиг. 4.10 выполняет второе сложение с помощью команды
ADC, с учетом флага переноса, установленного предыдущим сложением.
Это также хороший пример показывающий, почему команда MOV не
устанавливает никаких флагов. Если бы команда MOV изменяла флаги,
выполнить правильно второе сложение было бы гораздо труднее.