Читать «Assembler. Программирование на языке ассемблера IBM PC» онлайн - страница 31

Unknown Author

Пусть, к примеру, имеются такие описания переменных:

X DB ? ; TYPE X - BYTE Y DW ? : TYPE Y = WORD

Как правило, в команде MOV легко узнается тип (размер) одного из операндов, он и определяет размер пересылаемой величины. Например:

MOV вн,о MOV х,0 MOV si,о MOV Y,О

; пересылка байта (ВН - байтовый регистр)

; то же самое (X описан как имя байтовой переменной) ; пересылка слова (SI - регистр размером в слово)

; то же самое (Y описан как имя переменной-слова)

Отметим, что здесь по второму операнду (0) нельзя определить, какого он размера: ноль может быть и байтом (00h), и словом (OOOOh).

Если можно определить размеры обоих операндов, тогда эти размеры должны совпадать (либо байты, либо слова), иначе ассемблер зафиксирует ошибку. Например:

MOV DI,ES MOV сн,х MOV DX,AL MOV BH,300

; пересылка слова ; пересылка байта ; ошибка (DX - слово, AL - байт)

; ошибка (ВН - байт, а 300 не может быть байтом)

Отметим, что при пересылках никаких преобразований байта в слово или слова в байт не производится.

3.2.2. Оператор указания типа (PTR)

А теперь рассмотрим ситуацию, когда по операндам команды MOV нельзя определить размер пересылаемой величины.

Забегая вперед, отметим, что если некоторый адрес А надо модифицировать, скажем, по регистру SI, то в ЯА это записывается так: A[SI], Исполнительный адрес в этом случае вычисляется по формуле Аисп=А+[Б1]. В частности, при А=0 эта запись имеет вид [SI] (0 не указывается) и задает исполнительный адрес, равный содержимому регистра SI: Ancn=[SI],

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

MOV [SI],о

Однако это не так. Дело в том, что по этой команде нельзя понять, какого размера ноль пересылается, поскольку второй операнд может обозначать ноль как размером в байт (00h), так и размером в слово (OOOOh), а что касается первого операнда, то адрес из регистра SI может быть адресом ячейки как; размером в байт, так и размером в слово (напомним, что с одного и того же адреса могут начинаться ячейки разных размеров).

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

Для этого в ЯА введен оператор указания типа PTR (от pointer, указатель), который записывается следующим образом:

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

где <тип> - это BYTE, WORD или DWORD (есть и другие варианты, но мы их пока не рассматриваем), а выражение может быть константным или адресным.

Если указано константное выражение, то оператор "говорит", что значение этого выражения (число) должно рассматриваться ассемблером как величина указанного типа (размера); например, BYTE PTR 0 - это ноЗгь как байт, a WORD PTR 0 - это ноль как слово (запись BYTE PTR 300 ошибочна, т. к. число 300 не может быть байтом). Отметим, что в этом случае оператор PTR относится к константным выражениям.