В этой главе обсуждается набор команд микропроцессора 8088. В
предыдущих главах было рассмотрено расположение регистров и
механизмы адресации микропроцессора; в этой главе будут изучены
операции, которые можно выполнять с помощью регистров.
Разобьем команды микропроцессора 8088 на несколько групп.
Принадлежность команды к той или иной группе будет определяться
функцией, которую она выполняет. В этой главе описываются группы
команд и объясняется, как лучше всего ими пользоваться, но не будет
приводиться последовательного описания команд (такую задачу решает
руководство по Макроассемблеру).
Команды пересылки данных обычно наиболее часто используются из
всего набора команд любой ЭВМ, и микропроцессор 8088 - не
исключение. Большая часть каждой задачи по обработке данных
заключается в переносе информации из одного места в другое.
Программа может выполнять некоторую обработку информации по мере
того, как она пересылается, но громадная часть работы сводится
только к пересылке. В этом разделе рассматривается основные
команды пересылки данных микропроцессора 8088, а в разделе,
посвященном обработке строк - остальная часть таких команд.
Команда MOV - основная команда пересылки данных, которая пересылает
байт или слово данных из памяти в регистр, из регисрта в память,
или из регистра в регистр. Команда MOV может также занести число,
определенное программистом, в регистр или в память.
В действительности команда MOV - это целое семейство машинных
команд микропроцессора 8088. Таблица, в которую сведены варианты
всех машинных команд микропроцессора 8088, приведена в приложении
А. Беглый просмотр этой таблицы показывает, что существует семь
различных вариантов команды MOV, но программист использует каждую
из этих команд с помощью единого названия операции MOV. Ассемблер
порождает правильную машинную команду, основываясь на типах
операндов, которые написал программист; и это одна из причин, по
которой ассемблер требует для операндов назначения типов, т.е.
ассемблер должен знать, что представляет собой каждый операнд -
регистр, байт памяти, слово памяти, сегментный регистр, или
что=нибудь еще. Такое назначение типов позволяет ассемблеру
построить правильную машинную команду. В случае использования
команды MOV ассемблер должен решить, какой из семи вариантов
является подходящим, основываясь на операндах, написанных
программистом.
На Фиг.4.1 представлены различные способы, которыми в
микропроцессоре 8088 можно переслать данные из одного места в
другое. Каждый прямоугольник означает здесь регистр или ячейку
памяти. Стрелки показывают пути пересылки данных, которые допускает
набор команд микропроцессора 8088. Основной путь - из памяти в
регистры и наоборот. С данными, помещенными в регистры, можно
работать с большей эффективностью, чем с данными в памяти, так как
микропроцессор не делает обращения к памяти всякий раз, когда нужны
данные. Кроме того, все команды микропроцессора 8088 могут указать
только один операнд памяти. Поэтому, например, команда сложения ADD
требует, чтобы по крайней мере один из операндов был в регистре.
Микропроцессор 8088 не имеет возможности сложить одну ячейку памяти
с другой с помощью одной команды.
ЪДДДДДДДДДДДДДДДДДДДДї
і і
і Непосредственные і
АДДДДДДВДДДДДДВДДДДДДЩ
ЪДДДДДДДДДДї і і ЪДДДДДДДДДДДї
і і і і і Регистры і
і Г<ДДДДДДДДДДДЩ АДДДДДДДДДДД>ґ AX і
і і і BX і
і Память Г<ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД>ґ CX і
і і і DX і
і Г<ДДДДДДДДДДДї ЪДДДДДДДДДДД>ґ SI і
і і і і і DI і
і і і і і BP і
і і і і і SP і
АДДДДДДДДДДЩ v v АДДДДДДДДДДДЩ
ЪДДДДДДБДДДДДДБДДДДДДДї
і Сегментные регистры і
і CS DS ES SS і
АДДДДДДДДДДДДДДДДДДДДДЩ
Фиг.4.1 Операции пересылки данных
В самой команде MOV может содежаться новое содержимое регистра.
Такая форма операнда называется непосредственным оперндом; данные
находятся в самой команде и не требуют вычисления адреса. Вы можете
рассматривать эту форму адресации как специальный тип, при котором
операнд находится в самой команде, а не где=то в другом месте
памяти или в регистре. Кроме команд пересылки, у микропроцессора
8088 есть и команды обработки данных с непосредственным операндом.
Из Фиг.4.1 также ясно, что команда может переслать
непосредственнйе данные в регистр или ячейку памяти. Записывать
информацию в команду бессмысленно, так что поток данных для команды
с непосредственным операндом имеет одно направление.
Наконец, команда MOV может записать сегментный регистр в память
или регистр. Она может также загрузить сегментный регистр из памяти
или из другого регистра. Однако не существует команды загрузки
сегментного регистра данными с непосредственным операндом; это
означает, что загружать сегментный регистр такими данными
непроизводительно. Если в программе необходимо поместить известное
значение в сегментный регистр, нужно сначала записать это значение
в один из регистров или в ячейку памяти, а затем можно уже
пересылать это значение в сегментный регистр. На Фиг. 4.2 показано,
как это сделать.
icrosoft (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 Команды пересылки данных