Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Финогенов-основы_языка_ассемблера.doc
Скачиваний:
26
Добавлен:
17.09.2019
Размер:
3.35 Mб
Скачать

Глава 2

Основы программирования

67

mov AX,CS:mem

В этом случае транслятор включит в код команды префикс замены для сег­мента CS. Другие примеры команд с заменой сегмента будут приведены ниже.

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

смещениям.

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

mov AX,OB800h

mov ES,AX

mov byte ptr ES:0,'!'

mov byte ptr ES:2,T

;Сегментный адрес видеобуфера ;Отправим его в ES

;Огправим символ на 1-е знакоместо экрана ;Отправим символ на 2-е знакоместо экрана

Настроив регистр ES на сегментный адрес видеобуфера BSOOh, мы пересылаем код знака «!» сначала по относительному адресу 0 (в самое начало видеобуфера, в байт со смещением 0), а затем на следующее зна­коместо, имеющее смещение 2 (в нечетных байтах видеобуфера хранятся атрибуты символов, т.е. цвет символов и фона под ними). В обеих командах необходимо с помощью обозначения ES: указать сегментный регистр, который используется для адресации памяти. Встретившись с этим обо­значением, транслятор включит в код команды префикс замены сегмен­та, в данном случае код 26U.

В приведенном примере мы снова столкнулись с использованием ат­рибутивного оператора byte ptr, который позволяет в явной форме задать размер операнда. Однако если раньше этот оператор использовался, что­бы извлечь байт из данного, объявленного, как слово, то здесь его назна­чение иное. Транслятор, обрабатывая команду

mov byte ptr ES:0,T

не имеет возможности определить размер операнда-приемника. Разумеет­ся, видеобуфер, как и любая память, состоит из байтов, однако надо ли рассматривать эту память, как последовательность байтов или слов1 Ко­манда без явного задания размера операнда

mov ES:0,T

вызовет ошибку трансляции, так как ассемблер не сможет определить, надо ли транслировать это предложение, как команду пересылки в видео­буфер байта 2Ш, или как команду пересылки слова 00211г.

Между прочим, на первый взгляд может показаться, что в обсуждае-'мой команде достаточно ясно указан размер правого операнда, так как символ (в данном случае "!") всегда занимает один байт. Однако трансля­тор, встретив обозначение "!", сразу же преобразует его в код ASCII этого символа, т.е. в число 21h, и уже не знает, откуда это число произошло и какой размер оно имеет.

Стоит еще отметить, что указание в команде описателя word ptr

'f

{ mov word ptr ES:0,T

не вызовет ошибки трансляции, но приведет к неприятным результатам. В этом случае в видеобуфер будет записано слово 002 Ш, которое заполнит байт 0 видеобуфера кодом 2Ш, а байт 1 кодом ООН. Однако атрибут OOh обозначает черный цвет на черном фоне, и символ на экране виден не будет (хотя и будет записан в видеобуфер).

При желании можно избавиться от необходимости вводить описатель размера операнда. Для этого надо пересылать не непосредственное дан­ное, а содержимое регистра:

mov AL,'!' mov ES:0,AL

Здесь операндом-источником служит регистр AL, размер которого (1 байт) известен, и размер операнда-приемника определять не надо. Разу­меется, команда

mov ES:0,AX

заполнит в видеобуфере не байт, а слово.

Для адресации к видеобуферу в вышеприведенном примере использо­вался сегментный регистр дополнительных данных ES. Это вполне есте­ственно, так как обычно регистр DS служит для обращения к полям дан­ных программы, а регистр ES как раз и предназначен для адресации всего остального. Однако при необходимости можно было воспользоваться для записи в видеобуфер регистром DS:

mov AX,OB800h ;Сегментный адрес mov DS,AX видеобуфера в DS

mov byte ptr DS:0,T ;Символ в видеобуфер

Любопытно, что хотя обознбачение DS: здесь необходимо, трансля­тор не включит в код команды префикс замены сегмента, так как коман­да без префикса выполняет адресацию по умолчанию через DS.

Если, однако, по умолчанию бвыполняется адресация через DS, то нельзя ли опустить в последней команде обозначение сегментного регистра1 Нельзя, так как обозначение О5:число указывает, что число является не непосред­ственным операндом, а адресом операнда. Команда (неправильная)

mov 6,10

68