Глава 4 - Набор команд микропроцессора 8088

В этой главе обсуждается набор команд микропроцессора 8088. В предыдущих главах было рассмотрено расположение регистров и механизмы адресации микропроцессора; в этой главе будут изучены операции, которые можно выполнять с помощью регистров.

Разобьем команды микропроцессора 8088 на несколько групп. Принадлежность команды к той или иной группе будет определяться функцией, которую она выполняет. В этой главе описываются группы команд и объясняется, как лучше всего ими пользоваться, но не будет приводиться оследовательного описания команд (такую задачу решает руководство по Макроассемблеру).

4.1. Пересылка данных

Команды пересылки данных обычно наиболее часто используются из всего набора команд любой ЭВМ, и микропроцессор 8088 - не исключение. Большая часть каждой задачи по обработке данных заключается в переносе информации из одного места в другое. Программа может выполнять некоторую обработку информации по мере того, как она пересылается, но громадная часть работы сводится только к пересылке. В этом разделе рассматривается основные команды пересылки данных микропроцессора 8088, а в разделе, посвященном обработке строк - остальная часть таких команд.

4.1.1. Команда пересылки

Команда MOV - основная команда пересылки данных, которая пересылает байт или слово данных из памяти в регистр, из регисрта в память, или из регистра в регистр. Команда MOV может также занести число, определенное программистом, в регистр или в память.

В действительности команда MOV - это целое семейство машинных команд микропроцессора 8088. Таблица, в которую сведены варианты всех машинных команд микропроцессора 8088, приведена в приложении А. Беглый просмотр этой таблицы показывает, что существует семь различных вариантов команды MOV, но программист использует каждую из этих команд с помощью единого названия операции MOV. Ассемблер порождает правильную машинную команду, основываясь на типах операндов, которые написал программист; и это одна из причин, по которой ассемблер требует для операндов назначения типов, т.е. ассемблер должен знать, что представляет собой каждый операнд - регистр, байт памяти, слово памяти, сегментный регистр, или что-нибудь еще. Такое назначение типов позволяет ассемблеру построить правильную машинную команду. В случае использования команды MOV ассемблер должен решить, какой из семи вариантов является подходящим, основываясь на операндах, написанных программистом.

На Фиг.4.1 представлены различные способы, которыми в микропроцессоре 8088 можно переслать данные из одного места в другое. Каждый прямоугольник означает здесь регистр или ячейку памяти. Стрелки показывают пути пересылки данных, которые допускает набор команд микропроцессора 8088. Основной путь - из памяти в регистры и наоборот. С данными, помещенными в регистры, можно работать с большей эффективностью, чем с данными в памяти, так как микропроцессор не делает обращения к памяти всякий раз, когда нужны данные. Кроме того, все команды микропроцессора 8088 могут указать только один операнд памяти. Поэтому, например, команда сложения ADD требует, чтобы по крайней мере один из операндов был в регистре. Микропроцессор 8088 не имеет возможности сложить одну ячейку памяти с другой с помощью одной команды.

НепосредственныеКонстанта
РегистрыAX, BX, CX, DX, SI, DI, BP, SP
ПамятьАдрес
Сегментные регистрыCS, DS, ES, SS

Фиг.4.1 Операции пересылки данных

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

Из Фиг.4.1 также ясно, что команда может переслать непосредственнйе данные в регистр или ячейку памяти. Записывать информацию в команду бессмысленно, так что поток данных для команды с непосредственным операндом имеет одно направление.

Наконец, команда MOV может записать сегментный регистр в память или регистр. Она может также загрузить сегментный регистр из памяти или из другого регистра. Однако не существует команды загрузки сегментного регистра данными с непосредственным операндом; это означает, что загружать сегментный регистр такими данными непроизводительно. Если в программе необходимо поместить известное значение в сегментный регистр, нужно сначала записать это значение в один из регистров или в ячейку памяти, а затем можно уже пересылать это значение в сегментный регистр. На Фиг. 4.2 показано, как это сделать.


Microsoft (R) Macro Assembler Version 5.00                1/1/80 04:00:28
Фиг. 4.2 Команда пересылки                                      Page  1-1
                                                                PAGE ,132

TITLE    Фиг. 4.2    Команда пересылки
0000                     CODE     SEGMENT
                         ASSUME   CS:CODE,DS:CODE
0000                     EXWORD   LABEL     WORD
0000                     EXBYTE   LABEL     BYTE
0000    8B C3                     MOV       AX,BX       ; Регистр BX --> Регистр AX
0002    8B D8                     MOV       BX,AX       ; Регистр AX --> Регистр BX
0004    8B 0E 0000 R              MOV       CX,EXWORD   ; Память --> Регистр
0008    89 16 0000 R              MOV       EXWORD,DX   ; Регистр --> Память
000C    8A 2E 0000 R              MOV       CH,EXBYTE   ; Память --> Регистр (байт)
0010    88 36 0000 R              MOV       EXBYTE,DH   ; Регистр --> Память (байт)
0014    BE 03E8                   MOV       SI,1000     ; Непосредственное --> Регистр
0017    B3 17                     MOV       BL,23       ; Непосредственное --> Регистр (байт)
0019    C7 06 0000 R 07D0         MOV       EXWORD,2000 ; Непосредственное --> Память
001F    C6 06 0000 R 2E           MOV       EXBYTE,46   ; Непосредственное --> Память (байт)
0024    A1 0000 R                 MOV       AX,EXWORD   ; Память --> Аккумулятор
0027    A0 0000 R                 MOV       AL,EXBYTE   ; Память --> Аккумулятор (байт)
002A    A3 0000 R                 MOV       EXWORD,AX   ; Аккумулятор --> Память
002D    A2 0000 R                 MOV       EXBYTE,AL   ; Аккумулятор --> Память (байт)
0030    8E 1E 0000 R              MOV       DS,EXWORD   ; Память --> Сегментный регистр
0034    8E D8                     MOV       DS,AX       ; Регистр --> Сегментный регистр
0036    8C 1E 0000 R              MOV       EXWORD,DS   ; Сегментный регистр --> Память
003A    8C C0                     MOV       AX,ES       ; Сегментный регистр --> Регистр
                         ;-----   Непосредственное значение в сегментный регистр
003C    B8 ---- R                 MOV       AX,CODE     ; Взять непосредственное значение
003F    8E D8                     MOV       DS,AX       ; Загрузить его в сегментный регистр
0041                     CODE     ENDS
                         END

                       Фиг. 4.2 Команды пересылки

На Фиг. 4.2 изображен листинг ассемблера некоторых возможных вариантов команды MOV. Единственная команда ассемблера MOV порождает несколько различных машинных команд. Рассматривая Фиг.4.2, обратите внимание на синтаксис команды MOV. Команда MOV имеет два операнда: источник и результат. В команде они следуют друг за другом, источник следует за результатом. Первая команда на рисунке MOV AX, BX пересылает содержимое регистра BX в регистр AX. Следующая команда обратна предыдущей, содержимое регистра AX пересылается в регистр BX. Команда MOV не меняет источник, т.е. команда

MOV AX, BX

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

Как было замечено, существует несколько различных вариантов команд пересылки на машинном языке. Объектный код на Фиг. 4.2 иллюстрирует эти варианты. Если вас интересует структура машинного языка, вы можете сравнить объектный код с описанием машинного языка в приложении А. Такое сравнение поможет выяснить значение отдельных битов в машинном коде. Например, вы сможете увидеть значения данных с непосредственным операндом в командах. К счастью, для того, чтобы писать программы на ассемблере, вам не требуется точно знать, как работает ассемблер.

Если вы хотите достичь наибольшей возможной эффективности программ, вам надо изучить объектный код на Фиг. 4.2. Число байтов команды непосредственно связано с количеством времени, необходимого для выполнения этой команды. Например, команда пересылки, которая берет непосредственное значение и посылает его в память, занимает 6 байт. Набор команд микропроцессора 8088 содержит несколько команд, оптимизированных для работы с аккумулятором AX либо AL. Использование этих команд поможет вам сэкономить время и место в программах, где это важно.

Последние две команды на Фиг. 4.2 показывают, как занести непосредственное значение в сегментный регистр. Любой другой регистр, в примере это регистр AX, может временно содержать непосредственное значение перед его записью в сегментный регистр.

Есть и другеи команды, которые переносят данные. Пример на Фиг. 4.3 иллюстрирует эти команды.


Microsoft (R) Macro Assembler Version 5.00                  1/1/80 04:00:33
Фиг. 4.3 Команды пересылки данных                                 Page  1-1
                                                                  PAGE ,132

TITLE   Фиг. 4.3 Команды пересылки данных
0000                     CODE     SEGMENT
                         ASSUME   CS:CODE, DS:CODE
0000                     EXDWORD  LABEL     DWORD
0000                     EXWORD   LABEL     WORD
0000                     EXBYTE   LABEL     BYTE
0000    87 D9                     XCHG      BX,CX        ; Регистр BX <--> Регистр CX
0002    87 1E 0000 R              XCHG      BX,EXWORD    ; Регистр BX <--> Память
0006    93                             
 XCHG      AX,BX         ;
Регистр AX <--> Регистр BX
0007    E4 20                     IN        AL,020H      ; Порт 20H --> AL
0009    EC                        IN        AL,DX        ; Порт (DX) --> AL
000A    E6 21                     OUT       021H,AL      ; AL --> Порт 021H
000C    EE                        OUT       DX,AL        ; AL --> Порт (DX)
000D    8D 36 0000 R              LEA       SI,EXWORD    ; Адрес(EXWORD) --> SI
0011    C5 36 0000 R              LDS       SI,EXDWORD   ; M(EXDWORD) --> SI
                                                         ; M(EXDWORD+2) --> DS
0015    C4 3E 0000 R              LES       DI,EXDWORD   ; M(EXDWORD) --> DI
                                                         ; M(EXDWORD+2) --> ES
0019    9F                        LAHF                   ; Флаги --> AH
001A    9E                        SAHF                   ; AH --> Флаги
001B    D7                        XLAT      EXBYTE       ; M(BX+AL) --> AL
001C                       CODE   ENDS
                           END

                           Фиг. 4.3 Команды пересылки данных