Команды общего назначения

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

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

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

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

masm

model small

.data

fls db 5

fid db 1

.code

start:

mov al,fls

mov fld,al

end start

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

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

mov ax,ds

mov es,ax

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

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

mov ax,[bх]

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

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

inc [bх]

dec [bx]

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

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

mov [bx] ,0

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

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

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

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

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

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

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

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

masm

model small

.data

tip dw 0

.code

start :

mov byte ptr (flp+l),0ffh

end start

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

 

Для двунаправленной пересылки данных применяют команду XCHG.

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

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

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

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