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

Арифметические команды любого микропроцессора привлекают к себе наибольшее внимание. Каждый заинтересован в выполнении арифметических вычислений, и именно эти команды проделывают такую работу. Хотя их немного, они выполняют большинство преобразований данных а микропроцессоре. В реальных же условиях арифметические команды занимают лишь малую часть всех исполняемых команд.

Команды пересылки используют большинство принципов работы команд микропроцессора 8088, а при изучении арифметических команд необходимо рассмотреть некоторые тонкости их выполнения.

4.4.1. Сложение

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


ADD     AX,BX

складывает содержимое регистра BX с содержимым регистра AX, и оставляет результат в регистре AX. Регистр флагов сообщает о том, был ли результат нулевым, отрицательным, имел ли четность, перенос или переполнение.

Фиг. 4.8 кратко иллюстрирует варианты команды ADD. Существуют две формы сложения, 8-битовое и 16-битовое. В различных формах сложения принимают участие различные регистры. Ассемблер следит за тем, чтобы операнды соответствовали друг другу. Содержимое байтового регистра (например, CH) не может быть прибавлено к ячейке памяти, которая не имеет тип BYTE. Если ячейка памяти является одним из операндов, она может быть либо операндом-результатом, либо неизменяемым операндом. Тем самым команда может прибавить содержимое регистра к ячейке памяти и возвратить результат в память. Одним из операндов может также быть непосредственное значение. На Фиг. 4.9 показан листинг ассемблера с накоторыми арифметическими командами.

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

AX AX AX AH AH AX
BX BX BX AL AL AH
CX CX CX BH BH BH
DX DX DX BL BL BL
SI SI SI CH CH CH
DI DI DI CL CL CL
BP BP BP DH DH DH
SP SP SP 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                     EXBYTE   LABEL     BYTE
0000                     EXWORD   LABEL     WORD
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 изменяла флаги, выполнить правильно второе сложение было бы гораздо труднее.