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

Команда MOVпересылает содержимое источника (второго операнда) на место приёмника (первого операнда) (табл. 5.10). Флаги команда не изменяет. Пересылаемая величина извлекается из команды, регистра или ячейки памяти, а записывается в регистр или ячейку памяти. Пересылать одной командой двойное слово запрещено.

Инструкции с кодами операций 8C и 8E обеспечивают загрузку и извлечение информации из сегментных регистров. Занесение информации в регистр CS запрещено, т.к. регистровая пара CS:IP определяет адрес команды, которая должна быть выполнена следующей. Поэтому для этой цели необходимо использовать любую инструкцию дальнего (межсегментного) перехода (см. раздел 5.5).

 

Табл. 10. Команда MOV.

Код Инструкция Описание
88 /r MOV r/m8, r8 Пересылка из r8 в r/m8.
89 /r MOV r/m16, r16 Пересылка из r16 в r/m16.
8A /r MOV r8, r/m8 Пересылка из r/m8 в r8.
8B /r MOV r16, r/m16 Пересылка из r/m16 в r16.
8C /r MOV r/m16, Sreg Пересылка из Sreg в r/m16.
8E /r MOV Sreg, r/m16 Пересылка из r/m16 в Sreg.
A0 ow MOV AL, m8 Пересылка из m8 в AL.
A1 ow MOV AX, m16 Пересылка из m16 в AX.
A2 ow MOV m8, AL Пересылка из AL в m8.
A3 ow MOV m16, AX Пересылка из AX в m16.
B0+rb MOV r8, imm8 Пересылка imm8 в r8.
B8+rw MOV r16, imm16 Пересылка imm16 в r16.
C6 /0 MOV r/m8, imm8 Пересылка imm8 в r/m8.
C7 /0 MOV r/m16, imm16 Пересылка imm16 в r/m16.

 

 

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

Например, записать число 100 в сегментный регистр DS можно так:

 

MOV АХ, 100

MOV DS, AX

 

Как правило, в команде MOV легко определить тип одного из операндов и размер пересылаемой величины, например:

 

MOV АХ, 300 ; пересылка слова

MOV AH, AL ; пересылка байта

 

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

 

MOV [AX], 0

 

Однако по этой команде нельзя определить, какого размера пересылаемый ноль, поскольку второй операнд может обозначать ноль размером в байт (00h) или размером в слово (0000h). Кроме того, адрес из регистра AX может быть также адресом ячейки как размером в байт, так и размером в слово (с одного и того же адреса могут начинаться ячейки разных размеров). Поэтому ассемблер зафиксирует ошибку, сообщая, что типы операндов неизвестны.

Для явного указания типов операндов команды используется оператор указания типа PTR:

 

<тип> PTR <выражение>

 

где <тип> – BYTE, WORD или DWORD, выражение может быть константным или адресным.

 

Если указано константное выражение, то оператор сообщает, что значение выражения (число) должно рассматриваться как величина указанного типа (размера); например, BYTE PTR 0 – ноль как байт, а WORD PTR 0 – ноль как слово.

Если в PTR указано адресное выражение, то оператор сообщает, что адрес, являющийся значением выражения, должен восприниматься ассемблером как адрес ячейки указанного типа, например: WORD PTR A – адрес A обозначает слово (байты с адресами A и A+1).

Вернемся к нашему примеру и запишем его корректно с использованием оператора PTR. При обнулении байта по адресу из регистра AX, то команда имеет вид:

 

MOV BYTE PTR [AX], 0 или MOV [AX], BYTE PTR 0

 

Если требуется переслать нулевое слово:

 

MOV WORD PTR [AX], 0 или MOV [AX], WORD PTR 0

 

Обычно принято уточнять тип операнда-адреса, а не тип непосредственного операнда.

Перестановку двух величин можно реализовать с помощью команды MOV, однако существует и специальная команда XCHG(табл. 11). Инструкция меняет местами содержимое своих операндов. Флаги команда не меняет.

 

Табл. 11. Команда XCHG.

Код Инструкция Описание
90+rw XCHG AX, r16 AX ↔ r16
90+rw XCHG r16, AX r16 ↔ AX
86 /r XCHG r/m8, r8 r/m8 ↔ r8
86 /r XCHG r8, r/m8 r8 ↔ r/m8
87 /r XCHG r/m16, r16 r/m16 ↔ r16
87 /r XCHG r16, r/m16 r16 ↔ r/m16

 

 

Например, для обмена содержимого регистров AX и BX следует записать:

 

MOV АХ, 124

MOV BX, 43

ХСHG AX, BX ; АХ=43, BX=124

 

Перестановка содержимого двух ячеек памяти недопустима. Если требуется провести такую перестановку, она реализуется через регистр. Следующий пример меняет местами значения байтовых переменных X и Y:

 

MOV AL, X ; AL=X

XCHG AL, Y ; AL=Y, Y=X

MOV X, AL ; X=Y (исходное значение)

 

Рассмотрим еще несколько примеров команды MOV:

 

A DW 10 DUP(0) ; одномерный массив A из 10-ти элементов размером слово

B DW A ; в переменной B хранится адрес переменной A

...

MOV BX, B ; помещение в регистр BX адреса 1-ого элемента

MOV DX, [BX] ; помещение в регистр DX значения переменной A

MOV AX, BX ; помещение в регистр AX адреса 1-ого элемента A

...

MOV BX, 4 ; индекс второго элемента массива

MOV DX, A[BX] ; модификация адреса по регистру BX

 

Модификация адреса может быть выполнена и для двумерного массива. Например, для матрицы 10x10:

 

A DW 10 DUP(10 DUP (0))

 

запись элемента [i,j] в регистр AX будет следующей (регистры SI и DI содержат индексы):

 

MOV AX, A[SI][DI]

 

Следует заметить, что следующие записи эквиваленты (A и B – некоторые регистры-модификаторы):

 

[A][B] = [A]+[B] = [A+B]

 

В рассмотренном примере для получения адреса переменной A мы ввели дополнительную переменную B. Однако для загрузки исполнительного адреса операнда в памяти существует специальная команда LEA(табл. 12). Полученный результат заносится в регистр общего назначения. Флаги команда не изменяет. В качестве первого операнда команды должен быть указан регистр общего назначения, а в качестве второго – адресное выражение.

 

 

Табл. 12. Команда LEA.

Код Инструкция Описание
8D /r LEA r16, m Загрузка в r16 исполнительного адреса ячейки m.

 

 

Команда LEA может ссылаться на операнд источника с помощью любого типа адресации, который можно указать байтом ModRegR/M. Поля Mod и R/M байта ModRegR/M используются при вычислении адреса. Поле Reg этого байта определяет регистр общего назначения, в который должен быть занесён адрес.

Во многих случаях команда LEA идентична команде MOV с непосредственным операндом. Например, следующие две команды выполняют одинаковое действие:

 

MOV BX, OFFSET A

LEA BX, A

 

В первом случае выполняется непосредственная пересылка, которая использует смещение переменной A относительно начала сегмента данных. Оператор OFFSET сообщает транслятору, что в регистр BX надо загрузить смещение адресного значения переменной A. Команда LEA вычисляет действительный адрес переменной A и помещает его в регистр BX.

Для загрузки в регистр BX адреса десятого байта массива, на который указывает регистр DI. Пример применение команды LEA следующий:

 

LEA BX, 10[DI]

 

Ассемблер обратится по адресу содержимого регистра DI, добавит смещение 10, и затем поместит это значение (адрес) в регистр BX. Аналогичной команды с непосредственным операндом MOV для выполнения той же функции не существует.

Механизм адресации микропроцессора 8086 требует определения сегмента и смещения каждой переменной. Такое действие можно выполнить с помощью команд загрузки дальнего указателя LDSи LES(табл. 13). По команде LDS (LES) в сегментный регистр DS (ES) и в указанный регистр общего назначения загружается дальний указатель, значение которого находится в указанной области памяти. Флаги команда не изменяет.

Табл. 13. Команды загрузки дальнего указателя.

Код Инструкция Описание
C5 /r LDS r16, m16:16 Загрузка дальнего указателя в DS:r16.
C4 /r LES r16, m16:16 Загрузка дальнего указателя в ES:r16.

 

 

Например, команда:

 

LDS SI, A

 

загружает регистровую пару DS:SI значениями сегмента и смещения, содержащимися в переменной A: в регистр SI помещается смещение, расположенное по адресу A, а в регистр DS – значение сегмента, расположенное по адресу A+2.

И последняя инструкция, используемая в операциях модификации адресов, XLAT(табл. 14). Инструкция перекодирует по таблице значение регистра AL. Команда помещает в регистр AL содержимое байта памяти по адресу, равному сумме содержимого регистров BX и AL. Флаги команда не меняет. Команда используется при перекодировке символов.

 

 

Табл. 14. Команда XLAT.

Код Инструкция Описание
D7 XLAT AL:= [BX+AL]

 

 

Предположим, имеется таблица кодировки символов размером до 256 байтов, и i-й элемент рассматривается как новый код символа с кодом i. Если начальный адрес таблицы поместить в регистр BX, а исходный код перекодируемого символа в регистр AL, то команда XLAT поместит в регистр AL новый код символа из i-ого элемента таблицы.