В этой главе обсуждается набор команд микропроцессора 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 |
Память | Адрес |
Сегментные регистры | 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:CODE0000 EXWORD LABEL WORD0000 EXBYTE LABEL BYTE0000 8B C3 MOV AX,BX; Регистр BX --> Регистр AX0002 8B D8 MOV BX,AX; Регистр AX --> Регистр BX0004 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:CODE0000 EXDWORD LABEL DWORD0000 EXWORD LABEL WORD0000 EXBYTE LABEL BYTE0000 87 D9 XCHG BX,CX; Регистр BX <--> Регистр CX0002 87 1E 0000 R XCHG BX,EXWORD; Регистр BX <--> Память0006 93 XCHG AX,BX;Регистр AX <--> Регистр BX0007 E4 20 IN AL,020H; Порт 20H --> AL0009 EC IN AL,DX; Порт (DX) --> AL000A E6 21 OUT 021H,AL; AL --> Порт 021H000C EE OUT DX,AL; AL --> Порт (DX)000D 8D 36 0000 R LEA SI,EXWORD; Адрес(EXWORD) --> SI0011 C5 36 0000 R LDS SI,EXDWORD; M(EXDWORD) --> SI; M(EXDWORD+2) --> DS0015 C4 3E 0000 R LES DI,EXDWORD; M(EXDWORD) --> DI; M(EXDWORD+2) --> ES0019 9F LAHF; Флаги --> AH001A 9E SAHF; AH --> Флаги001B D7 XLAT EXBYTE; M(BX+AL) --> AL001C CODE ENDS END Фиг. 4.3 Команды пересылки данныхКоманда замены
Команда замены XCHG просто меняет местами содержимое двух ячеек. Эта команда может поменять местами содержимое двух регистров, или регистра и памяти. При этом в качестве операндов не могут использоваться сегментные регистры.
Команда XCHG заменяет три команды пересылки и не требует промежуточной ячейки памяти. Если бы команда замены не существовола, программе потребовалось бы три пересылки, чтобы обменять значения в регистре AX и в регистре BX. Сначала она должна была бы переслать содержимое регистра AX в рабочую ячейку, затем переслать содержимое регистра BX в регистр AX, и наконец, переслать содержимое рабочей ячейки в регистр BX. Команда XCHG одна выполняет эту операцию.
Команды ввода и вывода
Для выполнения операций ввода и вывода микропроцессор 8088 имеет команды IN и OUT соответственно. Каждое устройство ввода-вывода IBM PC имеет один или больше встроенных регистров, с которыми могут работать эти команды. Каждое устройство ввода-вывода имеет адрес для каждого регистра в устройстве. Это адресное пространство отличается от адресного пространтва памяти; всего существует 256, или 65536 адресов ввода-вывода, доступных микропроцессору 8088. В IBM PC - 512 из этих адресов назначены системному каналу ввода-вывода и могут использоваться различными адаптерами. Другие 256 адресов используются на системной плате для управления подключенными туда устройствами ввода-вывода.
Команда IN пересылает данные из устройства ввода-вывода в регистр AL. Эта команда может указать адрес устройства ввода-вывода двумя различными способами. Если адрес устройства находится в пределах 0 - 255, он может содержаться в команде как непосредственное значение. Если адрес больше 255, команда сообщает это косвенно. В случае косвенной команды адрес устройства ввода-вывода содержится в регистре DX. Регистр DX может содержать адреса всех устройств ввода-вывода, включая те, номера которых меньше 256.
Аналогично работает команда OUT, за исключением того, что она записывает регистр AL в регистр устройства ввода-вывода. Адреса в команде OUT указываются так же, как и в команде IN.
Команды IN и OUT также могут пересылать слова в устройства ввода-вывода и из них. В случае работы со словами источником и приемником является регистр AX. Так как у микропроцессора 8088однобайтовая внешняя шина, устройства ввода-вывода IBM PC работают только с байтами при любых операциях ввода-вывода. Это означает, что операции ввода-вывода слов не используются в персональной ЭВМ. Однако пословные операции ввода-вывода имеют смысл в системе с микропроцессором 8086, который имеет тот же набор команд.