
- •140010, Г. Люберцы, Московской обл., Октябрьский пр-т, 403.
- •Глава 1. Архитектура реального режима
- •1.1. Память и процессор
- •Глава 1
- •Глава 1
- •1.2. Распределение адресного пространства
- •Глава 1
- •1.3. Регистры процессора
- •Глава 1
- •Глава 1
- •9 7H Шестнадцатернчное обозначение числа
- •Глава 1
- •1.4. Сегментная структура программ
- •Глава 1
- •Глава 1
- •Глава 1
- •1.5. Стек
- •Глава 1
- •1.6. Система прерываний
- •Глава 1
- •Глава I
- •1.7. Система ввода-вывода
- •Глава I
- •Глава 1
- •Глава 2. Основы программирования
- •2.1. Подготовка и отладка программы
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •2.2. Представление данных
- •Глава 2
- •Глава 2
- •2.3. Описание данных
- •Глава 2
- •Глава 2
- •2.4. Структуры и записи
- •Глава 2
- •Глава 2
- •2.5. Способы адресации
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •2.7. Вызовы подпрограмм
- •Глава 2
- •2.8. Макросредства ассемблера
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 3. Команды и алгоритмы
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •3.2. Циклы и условные переходы
- •Глава 3
- •Глава 3
- •3.3. Обработка строк
- •Глава 3
- •3.4. Использование подпрограмм
- •Глава 3
- •Глава 3
- •3.5. Двоично-десятичные числа
- •Глава 3
- •Глава 3
- •3.6. Программирование аппаратных средств
- •Глава 3
- •37Ah Порт управлсш!я
- •Глава 3
- •Глава 3
- •Глава 4. Расширенные возможности
- •4.1. Архитектурные особенности
- •Глава 4
- •4.2. Дополнительные режимы адресации
- •Глава 4
- •4.3. Использование средств 32-разрядных процессоров в программировании
- •Глава 4
- •Глава 4
- •Глава 4
- •4.4. Основы защищенного режима
- •Глава 4
- •Глава 4
- •Глава 4
- •Глава 4
- •Idiv Деление целых чисел со знаком
- •Imul Умножение целых чисел со знаком
- •In Ввод из порта
- •Inc Инкремент (увеличение на 1)
- •Int Программное прерывание
- •Into Прерывание по переполнению
- •Iret Возврат из прерывания
- •1 Lods Загрузка операнда из строки : lodsb Загрузка байта из строки lodsw Загрузка слова из строки
- •Операнд
- •Xadd память, регистр
- •Xchg Обмен данными между операндами
- •Xlat Табличная трансляция
- •Xor Логическое исключающее или
- •Содержание
Глава 2
Основы программирования
65
inc СН ;Плюс 1 к содержимому СН
push DS; ;DS сохраняется в стеке №
xchg ВХ.ВР ;ВХ и ВР обмениваются содержимым У
mov ES,AX ;Содержимое АХ пересылается в ES ||
Непосредственная адресация. Операнд (байт или слово) указывается в команде и после трансляции поступает в код команды; он может иметь любой смысл (число, адрес, код ASCII), а также быть представлен в виде символического обозначения.
mov AH,40h ;Число 40h загружается в АН
mov AL,'*" ;Код ASCII символа "*" загружается в AL
hit 21h ;Команда прерывания с аргументом 2Ш
limit = 528 ;Число 528 получает обозначение limit
mov CX,limit ;Число, обозначенное limit, загружается в СХ
Команда mov, использованная в последнем предложении, имеет два операнда; первый операнд определяется с помощью регистровой адресации, второй — с помощью непосредственной.
Важным применением непосредственной адресации является пересылка относительных адресов (смещений). Чтобы указать, что речь идет об относительном адресе данной ячейки, а не об ее содержимом, используется описатель onset (смещение):
;Сегмент данных mes db "Урок Г' ;Сегмент команд mov DX.oflset mes
;Строка символов
;Адрес строки засылается в DX
В приведенном примере относительный адрес строки mes, т.е. расстояние в байтах первого байта этой строки от начала сегмента, в котором она находится, заносится в регистр DX.
Прямая адресация памяти. Адресуется память; адрес ячейки памяти (слова или байта) указывается в команде (обычно в символической форме) и поступает в код команды:
;Сегмент данных me ml dw О тет2 db 230 ;Сегменг команд
inc meml
mov
mov
;Слово памяти содержит О ;Байт памяти содержит 230
;Содержимое слова meml увеличивается на 1 DX,meml ;Содержимое слова с именем meml загружается в DX AL,mem2 ;Содержимое байта с именем mem2 загружается в AL
Сравнивая этот пример с предыдущим, мы видим, что указание в команде имени ячейки памяти обозначает, что операндом является со-
держимое этой ячейки; указание имени ячейки с описателем onset — что операндом является адрес ячейки.
Прямая адресация памяти на первой взгляд кажется простой и наглядной. Если мы хотим обратиться, например, к ячейке meml, мы просто указываем ее имя в программе. В действительности, однако, дело обстоит сложнее. Вспомним, что адрес любой ячейки состоит из двух компонентов: сегментного адреса и смещения. Обозначения meml и mem2 в предыдущем примере, очевидно, являются смещениями. Сегментные же адреса хранятся в сегментных регистрах. Однако сегментных регистров четыре: DS, ES, CS и SS, Каким образом процессор узнает, из какого регистра взять сегментный адрес, и как сообщить ему об этом в программе'
Процессор различает группу кодов, носящих название префиксов. Имеется несколько групп префиксов: повторения, размера адреса, размера операнда, замены сегмента. Здесь нас будут интересовать префиксы замены сегмента.
Команды процессора, обращающиеся к памяти, могут в качестве первого байта своего кода содержать префикс замены сегмента, с помощью которого процессор определяет, из какого сегментного регистра взять сегментный адрес. Для сегментного регистра ES код префикса составляет 26h, для SS — 36U, для CS — 2Eh. Если префикс отсутствует, сегментный адрес берется из регистра DS (хотя для него тоже предусмотрен свой префикс).
Если в начале программы с помощью директивы assume указано соответствие сегменту данных сегментного регистра DS
assume DS:data
то команды обращения к памяти транслируются без какого-либо префикса, а процессор при выполнении этих команд берет сегментный адрес из регистра DS.
Если в директиве assume указано соответствие сегмента данных регистру ES assume ES:data
(в этом случае сегмент данных должен располагаться перед сегментом команд), то команды обращения к полям этого сегмента транслируются с добавлением префикса замены для сегмента ES. При этом предложения программы выглядят обычным образом; в них по-прежнему просто указываются имена полей данных, к которым производится обращение.
Однако в ряде случаев префикс замены сегмента должен указываться в программе в явной форме. Такая ситуация возникает, например, если Данные расположены в сегменте команд, что типично для резидентных обработчиков прерываний. Для обращения к таким данным можно, конечно, использовать регистр DS, если предварительно настроить его на сегмент команд, но проще выполнить адресацию через регистр CS, который и так уже настроен должным образом. Если в сегменте команд содержится поле данных с именем mem, то команда чтения из этого поля будет выглядеть следующим образом: