
- •Введение
- •1.1. Основные направления эволюции микрокомпьютеров
- •1.2. Основные сведения о компьютерах
- •1.3. Представление чисел
- •Заключение
- •Лекция 2 машинная организация процессора 80286
- •2.1. Введение
- •2.2. Структура памяти
- •2.3. Сегментация памяти
- •2.4. Структура ввода-вывода
- •2.5. Регистры
- •2.6. Операнды и режимы адресации операндов
- •2.7. Замечания о режимах адресации
- •Глава 3 базовая система команд процессора 80286
- •3.1. Нотация языка ассемблера
- •3.2. Команды передач данных
- •3.3. Арифметические команды
- •Лекция 6. Цепочечные команды
- •Лекция 7. Команды безусловной передачи управления
- •Лекция 8. Команды условной передачи управления
- •Лекция 9. Прерывания
- •Int n
- •Лекция 10. Флажковые команды
- •3.10. Команды синхронизации
- •3.11. Поддержка языков высокого уровня
- •3.12. Замечания о префиксах
- •3.13. Воздействие на флажки
- •Заключение
3.2. Команды передач данных
Процессор 80286 имеет четыре класса команд передач данных: общие передачи, аккумуляторные передачи, адресные передачи и флажковые передачи (см. табл. 3.1).
Таблица 3.1 Команды передач данных |
| |||
Мнемоника команды |
Описание команды | |||
Общие |
| |||
|
ИСТОЧНИК ПРИЁМНИК | |||
|
ИСТОЧНИК ПРИЁМНИК | |||
|
ИСТОЧНИК стек | |||
|
Стек ПРИЁМНИК | |||
|
Регистры стек | |||
|
Стек ругистры | |||
Аккумуляторные |
| |||
|
Порт AL или AX | |||
|
AL или AX Порт | |||
|
F(AL) AL | |||
Адресные |
| |||
|
Смещение ИСТОЧНИКА РЕГИСТР | |||
|
ИСТОЧНИК, ИСТОЧНИК +1 РЕГИСТР ИСТОЧНИК+2, ИСТОЧНИК+3 DS | |||
|
ИСТОЧНИК, ИСТОЧНИК +1 РЕГИСТР ИСТОЧНИК+2, ИСТОЧНИК+3 ES | |||
Флажковые |
| |||
|
SF, ZF, AF, PF, CF AH | |||
|
AH SF, ZF, AF, PF, CF | |||
|
Флажки стек | |||
|
Стек флажки |
Общие передачи. Командами общих передач являются MOV (переслать), XCHG (обменять), PUSH (включить в стек), POP (извлечь из стека), PUSHA (включить в стек всё) и РОРА (извлечь из стека всё). В качестве одного из операндов в этих командах допустим сегментный регистр, поэтому в сегментные регистры можно поместить новые значения, а старые их значения запомнить. Программист обычно не привлекает значения из сегментных регистров, поэтому во всех остальных командах использование сегментных регистров в качестве операндов не допускается. Команда MOV передает байт или слово из источника в приемник. Один из операндов ее может находиться в регистре или памяти, а другой - в регистре, сегментном регистре или в самой команде (непосредственный операнд). Примеры различных команд MOV показаны в табл. 3.2.
|
Таблица 3.2 Примеры команд MOV |
| |||
Передача данных |
Слово |
Байт |
| ||
Регистр в регистр |
MOV AX, BX |
MOV AH, BH |
| ||
Непосредственный операнд в регистр |
MOV CX, 850 |
MOV BL, 35 |
| ||
Память в регистр |
MOV DX, MEMW |
MOV CL, MEMB |
| ||
Регистр в память |
MOV MEMW, CX |
MOV MEMB, DL |
| ||
Регистр в сегментный регистр |
MOV ES, BX |
|
| ||
Сегментный регистр в регистр |
MOV AX, DS |
|
| ||
Память в сегментный регистр |
MOV SS, MEMW |
|
| ||
Сегментный регистр в память |
MOV MEMW, СS |
|
|
Команда XCHG осуществляет обмен байт или слов. Один из ее операндов может быть в регистре шли памяти, а другой - в регистре. Различий между приемником и источником нет. Примеры команд XCHG показаны . в табл. 3.3.
|
Таблица 3.3 Примеры команды XCHG |
| ||
Обмен данными |
Слово |
Байт | ||
Регистр с регистром |
XCHG CX, DX |
XCHG AL, AH | ||
Регистр с памятью |
XCHG BX, MEMW |
XCHG BL, MEMB |
Команда PUSH передает слово из источника в стек, а команда РОP осуществляет противоположное действие: она передает слово из стека в приемник. Стек - это область памяти, в которой размещается текущий сегмент стека. Регистр SP содержит смещение последнего включенного в стек слова; оно называется вершиной стека. По мере включения в стек новых слов они располагаются по меньшим адресам памяти; говорят, что стек растет в направлении уменьшения адресов. Команда PUSH начинается с декремента содержимого регистра SP на 2, т.е. адресует следующее свободное слово в стеке. Команда POP завершается инкрементом содержимого SP на 2, т.е. удаляет считанное слово из стека. На рис. 3.1. показано действие команд PUSH и POP.
Операндом команд PUSH и POP может быть сегментный регистр, 16-битный (несегментный) регистр или слово из памяти. Кроме того, в команде PUSH можно указывать непосредственный операнд, что не допускается в команде PUSH микропроцессора 8086. Поскольку извлечение слова из стека в команду не имеет смысла, в команде POP не может быть непосредственного операнда. Примеры команд PUSH и POP показаны в табл. 3.4.
|
Таблица 3.4 Примеры команд PUSH и POP |
| ||
Операнд |
Включение |
Извлечение | ||
Регистр |
PUSH AX |
POP BX | ||
Память |
PUSH MEMW |
POP MEMW | ||
Сегментный регистр |
PUSH DS |
POP ES | ||
Непосредственный операнд |
PUSH 895 |
| ||
Все регистры |
PUSHA |
POPA |
Сделаем одно замечание. Рассмотрим, что произойдет, если команда изменила содержимое регистра CS. Ясно, что при этом текущим сегментом кода станет новый сегмент. Однако обычный инкремент содержимого регистра IP образует в нем смещение следующей по порядку команды в предыдущем сегменте кода. Следовательно, комбинация CS и IP будет определять бессмысленный адрес памяти, а процессор попытается выбрать следующую команду по этому адресу. Мы приходим к выводу, что если команда, изменяющая содержимое регистра CS, не загрузит соответствую нее значение в регистр IP, процессор будет осуществлять бессмысленные передачи. По этой причине некоторые команды, которые допускают использование в качестве операнда сегментного регистра, не могут использовать один конкретный сегментный регистр - а именно, регистр CS. Примерами служат команды:
Имеются еще две команды включения в стек и извлечения из стека: PUSHA - включить в стек все регистры и РОРА - извлечь все регистры. Эти команды первоначально планировалось реализовать и в микропроцессоре 8086, но этого не было сделано и впервые они появились в процессоре 80186.
Команды PUSHA и РОРА являются эффективным средством подпрограммы или процедуры, позволяющим сохранить содержимое всех регистров (кроме сегментных регистров и регистра IP) в начале ее выполнения и восстановить его в конце. После сохранения содержимого регистров процедура может распоряжаться ими как угодно, а важная информация, бывшая в регистрах, будет возвращена вызывающей программе без изменений.
Команда PUSHA включает в стек регистры в таком порядке: АХ, СХ, DX, BX, SP, ВР, SI, DI. Включаемым значением регистра SP является то его значение, которое было в нем до выполнения команды PUSHA. При выполнении команды PUSHA происходит декремент содержимого регистра SP на 2 при включении в стек содержимого каждого регистра. Извлечение из стека, реализуемое командой РОРА, вызовет инкремент содержимого регистра SP на ту же величину, поэтому команде РОРА не требуется запомненное в стеке содержимое регистра SP и она его просто уничтожает.
Аккумуляторные передачи. Передачи этого класса реализуют команды IN (ввести), OUT (вывести) и XLAT (преобразовать). В этих командах ре гистры трактуются не так единообразно, как в предыдущих командах (за исключением сегментных регистров), так как операндом может быть только АККУМУЛЯТОР. Такая специализация аккумулятора позволяет уменьшить число байт в команде.
КомандаIN
передает данные (байт или слово) из
входного порта в аккумулятор (AL
или АХ). Аналогично команда OUT
передает данные из аккумулятора в
выходной порт. Номер порта разрешается
определять прямо в самой команде или
косвенно через регистр DX.
Отметим, что никакой другой регистр
нельзя привлекать для этой цели. Прямо
в команде можно определить 256 портов,
а через регистр DX
- 64К портов. В случае прямой адресации
портов не требуется предварительная
загрузка номера порта в регистр DX.
Косвенная адресация позволяет реализовать
обращения к последовательным портам в
программном цикле. Примеры команд IN
и OUT
показаны в табл. 3.5, а следующий фрагмент
иллюстрирует различия прямой и
косвенной адресации:
|
Таблица 3.5 Примеры команд IN и OUT |
| ||
Команда |
Слово |
Байт | ||
IN (прямой) |
IN AX, 1 |
IN AL, 10 | ||
OUT (прямой) |
OUT 50, AX |
OUT 30, AL | ||
IN (косвенный) |
IN AX, DX |
IN AL, DX | ||
OUT (косвенный) |
OUT DX, AX |
OUT DX,AL |
Команда XLAT преобразует значение в регистре AL: она заменяет его на байт из таблицы, адресуемой регистром ВХ (еще одна специальная функция РОНа), причем индексом таблицы служит исходное содержимое регистра AL. Эта команда удобна для преобразования из одного кода в другой. Рассмотрим, например, такое кодирование десятичных цифр:
-
Цифра
Код
0
11000
1
00011
2
00101
3
00110
4
01001
5
01010
6
01100
7
10001
8
10010
9
10100
Такое кодирование представляет некоторый практический интерес, так как каждый код содержит точно два единичных бита (иногда этот код называется кодом "2-из-5") и применяется в телефонии. Предположим, что необходимо преобразовать цифру 7 в код "2-из-5". Получается следующий фрагмент:
Собственно преобразование показано на рис. 3.2.
Отметим,
что в команде всегда используется
таблица, адресуемая регистром ВХ, и в
ней нет поля для указания конкретной
таблицы. Поэтому кажется несколько
странным, что в ассемблерной записи
команды XLAT
указан
операндTABLE.
Это сделано только для того, чтобы
ассемблер мог проконтролировать
нахождение таблицы TABLE
в доступном сегменте.
Адресные передачи. Адресные передачи реализуют команды LEA (загрузить эффективный адрес), LDS (загрузить указатель в DS) и LES (загрузить указатель в ES). Они позволяют программисту управлять механизмом адресации. Каждая из команд имеет два операнда: один - в памяти, а другой - в 16-битном регистре. Примеры команд:
Команда LEA вычисляет 16-битное смещение операнда-источника и загружает его в 16-битный регистр-приемник. Она удобна для передачи смещения переменной из одной части программы в другую, чтобы в этой другой части можно было при необходимости модифицировать значение переменной. Объекты, передаваемые между различными частями программы, называются параметрами, а различные части программы называются процедурами.
Рассмотрим пример применения команды LEA. Предположим, что одна из процедур отвечает за инкремент переменных. Другие части программы могут вызвать ее и заставить произвести инкремент конкретной переменной. Смещение переменной, инкремент которой необходимо произвести, можно передать процедуре инкремента как параметр, поместив его до вызова в определенный регистр, например ВХ. Именно для этого и предназначена команда LEA. В ней нужно указать регистр ВХ как приемник, а переменную - как источник. Команда загрузит смещение переменной в регистр ВХ. Разумеется, команду LEA нужно выполнить до вызова процедуры. Процедура же обратится к значению переменной, пользуясь косвенной адресацией через регистр ВХ, т.е. в виде [ВХ], Отметим, что при передаче процедуре инкремента, значения переменной, а не ее смещения, процедура знала бы значение, но не смогла бы изменить его.
КомандаLDS
передает четыре смежных байта из
источника в пару 16-битных регистров-приемников.
Источник должен находиться в памяти.
Одним из регистров будет 16-битный
регистр, указанный в команде, а вторым
- регистр DS.
Команда LES
выполняет аналогичную функцию, но вторым
регистром-приемником в ней является
регистр ES,
а не DS.
Фактические передаваемые данные
показаны на рис. 3.3. Команды LDS
и LES
служат эффективным средством установки
полного начального адреса (сегмент:смещение)
переменной, к которой могут обращаться
следующие команды. Комбинация начального
адреса сегмента и смещения называется
еще 32-битным
указателем или
просто указателем;
команды
LDS
и LES
передают указатель из памяти в регистры,
привлекаемые в режимах адресации
операндов Предположим, например, что
четыре смежных байта (первый из которых
имеет адрес POINTER)
содержат указатель однобайтной
переменной, как показано на рис. 3.4.
Следующие две команды передают
значение переменной в регистр AL:
Флажковые передачи. Команды этого класса обеспечивают доступ к флажкам процессора. К ним относятся команды LAHF (загрузить флажки в АН), SAHF (запомнить АН во флажках), PUSHF (включить в стек флажки) и POPF (извлечь из стека флажки).
Команда LAHF передает пять флажков SF, ZF, AF, PF и CF в определенные биты регистра АН, а команда SAHF реализует противоположную передачу. Указанные пять флажков выделены только потому, что они имелись в микропроцессоре 8080. (Команды LAHF и SAHF предусмотрены, в основном, для преобразования программ микропроцессора 8080 в эффективные программы для процессоров семейства 86.) Соответствие между битами регистра АН и флажками показано на рис. 3.5.
Команда PUSHF включает в слово стека все флажки процессора, а команда POPF извлекает слово из стека и передает его в регистр флажков. Соответствие между словом в стеке и флажками показано на рис. 3.6.