Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции препода / Лекции для 3 курса.doc
Скачиваний:
83
Добавлен:
30.04.2013
Размер:
1.51 Mб
Скачать

3.2. Команды передач данных

Процессор 80286 имеет четыре класса команд передач данных: общие передачи, аккумуляторные передачи, адресные передачи и флажковые передачи (см. табл. 3.1).

Таблица 3.1 Команды передач данных

Мнемоника команды

Описание команды

Общие

MOV (переслать)

ИСТОЧНИК ПРИЁМНИК

XCHG (обменять)

ИСТОЧНИК ПРИЁМНИК

PUSH (включить в стек)

ИСТОЧНИК стек

POP (извлечь из стека)

Стек ПРИЁМНИК

PUSHA (включить в стек всё)

Регистры стек

POPA (извлечь из стека всё)

Стек ругистры

Аккумуляторные

IN (ввести)

Порт AL или AX

OUT (вывести)

AL или AX Порт

XLAT преобразовать)

F(AL) AL

Адресные

LEA (загрузить эффективный адрес в регистр

Смещение ИСТОЧНИКА РЕГИСТР

LDS (загрузить указатель в регистр и DS)

ИСТОЧНИК, ИСТОЧНИК +1 РЕГИСТР

ИСТОЧНИК+2, ИСТОЧНИК+3 DS

LES (загрузить указатель в регистр и ES)

ИСТОЧНИК, ИСТОЧНИК +1 РЕГИСТР ИСТОЧНИК+2, ИСТОЧНИК+3 ES

Флажковые

LAHF (загрузить флажки в AH)

SF, ZF, AF, PF, CF AH

SAHF (запомнить AH во флажках)

AH SF, ZF, AF, PF, CF

PUSHF (включить в стек флажки)

Флажки стек

POPF (извлечь из стека флажки)

Стек флажки

Общие передачи. Командами общих передач являются 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.

Соседние файлы в папке Лекции препода