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

Глава 7

Команды обмена данными

Линейные алгоритмы

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

Ввод из порта и вывод в порт

Команды работы с адресами памяти

Команды работы со стеком

Наверняка вы уже знакомы с понятием алгоритма, представляющего собой формализованное описание логики работы программы. Способы такой формализации весьма разнятся: от текстового описания последовательности действий до алгоритма развитых case-систем. Последовательность действий, описываемых алгоритмом, может быть:

-линейной — все действия выполняются поочередно, друг за другом;

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

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

Еще раз обратимся к функциональной классификации целочисленных машинных команд процессора. Из всей совокупности этих команд на линейных участках работают следующие группы:

-команды пересылки данных;

-арифметические команды;

-логические команды;

-команды управления состоянием процессора.

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

-собственно пересылки данных;

- ввода из порта и вывода в порт;

-работы с адресами и указателями;

-преобразования данных;

-работы со стеком.

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

К группе команд пересылки данных относятся следующие команды:

mov <операнд назначения>,<операнд-источник>

xchg <операнд1>,<операнд2>

MOV — это основная команда пересылки данных. Она реализует самые разнообразные варианты пересылки. Отметим особенности применения этой команды.

-Командой MOV нельзя осуществить пересылку из одной области памяти в другую. Если такая необходимость возникает, то нужно использовать в качестве промежуточного буфера любой доступный в данный момент регистр общего назначения. К примеру, рассмотрим фрагмент программы для пересылки байта из ячейки fls в ячейку fld:

masm

model small

.data

fls db 5

fid db ?

.code

start:

mov al . fls

movfld.al

endstart

Нельзя загрузить в сегментный регистр значение непосредственно из памяти.

Для такой загрузки требуется промежуточный объект. Это может быть регистр общего назначения или стек. Если вы посмотрите на листинг 5.1, то увидите в начале сегмента кода две команды MOV, выполняющие настройку сегментного регистра DS. При этом из-за невозможности напрямую загрузить в сегментный регистр значение адреса сегмента, содержащееся в предопределенной переменной @data, приходится использовать регистр общего назначения АХ.

- Нельзя переслать содержимое одного сегментного регистра в другой сегментный регистр. Это объясняется тем, что в системе команд нет соответствующего кода операции. Но необходимость в таком действии часто возникает. Выполнить такую пересылку можно, используя в качестве промежуточных все те же регистры общего назначения. Вот пример инициализации регистра ES значением из регистра DS:

mov ax.ds

mov es.ax

Но есть и другой, более «красивый» способ выполнения данной операции использование стека и команд PUSH и POP:

push ds ;поместить значение регистра ds в стек

pop es ;записать в es число из стека

-Нельзя использовать сегментный регистр CS в качестве операнда назначения.

Причина здесь простая. Дело в том, что в архитектуре процессора IA-32 пара CS:IP содержит адрес команды, которая должна выполняться следующей. Изменение командой MOV содержимого регистра CS фактически означало бы операцию перехода, а не пересылки, что недопустимо.

В связи с командой MOV отметим один тонкий момент. Пусть в регистре ВХ содержится адрес некоторого поля (то есть мы используем косвенную базовую адресацию). Его содержимое нужно переслать в регистр АХ. Очевидно, что нужно применить команду MOV в форме

mov a x , [ Ь х ]

Транслятор задает себе вопрос: что адресует регистр ВХ в памяти — слово или байт? Обычно в этом случае он принимает решение сам, по размеру большего операнда, но может и выдать предупреждающее сообщение о возможном несовпадении типов операндов.

Или другой случай — возможно, более показательный. Рассмотрим команды инкремента INC (увеличения операнда на 1) и декремента DEC (уменьшения операнда на 1):

inc [Ьх]

dec [bx]

Что адресуется регистром ВХ в памяти — байт, слово или двойное слово?

Допустим также, что требуется инициализировать поле, адресуемое регистром ВХ, значением 0. Очевидно, что одно из решений — применение команды MOV: mov [bx] ,0

И опять у транслятора вопрос: какую машинную команду ему конструировать? Для инициализации байта? Для инициализации слова? Для инициализации двойного слова?

Во всех этих случаях необходимо уточнять тип используемых операндов. Для этого существует специальный оператор ассемблера PTR (см. приложение). Правильно записать приведенные ранее команды можно следующим образом:

mov ax,word ptr[bx] ;если [bx] адресует слово в памяти

inc byte ptr[bx] ;если [bx] адресует байт в памяти

Ввод из порта и вывод в порт 149

dec dword ptr[bx] ;если [Ьх] адресует двойное слово в памяти

mov word ptr[bx],0 ;если [Ьх] адресует слово в памяти

Можно рекомендовать использовать оператор PTR во всех сомнительных относительно согласования размеров операндов случаях. Также этот оператор нужно применять, когда требуется принудительно поменять размерность операндов.

К примеру, требуется переслать значение Offh во второй байт поля flp:

masm

model small

.data

tip dw 0

.code

start:

mov byte ptr (flp+l),0ffh

end start

Несмотря на то что поле flp имеет тип WORD, мы сообщаем ассемблеру, что поле нужно трактовать как байтовое, и заставляем вычислить значение эффективного адреса второго операнда как смещение flp плюс единица. Тем самым мы получаем доступ ко второму байту поля flp.

Для двунаправленной пересылки данных применяют команду XCHG. Для этой операции можно, конечно, применить последовательность из нескольких команд MOV, но из-за того что операция обмена используется довольно часто, разработчики системы команд процессора посчитали нужным ввести отдельную команду обмена — XCHG. Естественно, что операнды должны иметь один тип. Не допускается (как и для всех команд ассемблера) напрямую обменивать между собой содержимое двух ячеек памяти. К примеру,

xchg ах,Ьх ;обменять содержимое регистров ах и Ьх

;обменять содержимое регистра ах и слова в памяти по адресу в [si]:

xchg ax,word ptr [si]

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