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

Глава 3

Далее старшая половина сегментного адреса заносится в регистр AL, и вызовом уже .знакомой нам функции BIOS OEh этот код выводится на экран. Затем таким же образом выводится младшая половина сегментного адреса. Наконец, после восстановления регистров ВХ и АХ (в обратном порядке по отношению к их сохранению) командой iret упраштение воз­вращается в прерванную программу, которой в данном случае является COMMAND.COM.

Вывод программы (ей для наглядности было дано имя TSR.COM) для конкретного прогона показан на рис, 3.8.

FACURRENT>tsr.con

F:4CURREMT>*=

123

3.2. Циклы и условные переходы

Циклы, позволяющие выполнить некоторый участок программы много­кратно, в любом языке являются одной из наиболее употребительных конст­рукций. В системе команд МП 86 циклы реализуются, главным образом, с помощью команды loop (петля), хотя имеются и другие способы организа­ции циклов. Во всех случаях число шагов в цикле определяется содержимым регистра СХ, поэтому максимальное число шагов составляет 64 К.

Рассмотрим простой пример организации цикла. Пусть в программе зарезервировано место для массива размером 10000 слов, и этот массив надо заполнить натуральным рядом чисел от 0 до 9999. Эти числа, запол­няющие последовательные элементы массива, иногда называют числа­ми-заполнителями. Соответствующий фрагмент программы будет выгля­деть следующим образом:

Рис. 3.8. Вывод программы 3-4.

Полученный результат далек от наглядности. Действительно, разделив сегментный адрес на две половины длиной в байт каждая, мы просто записали в видеобуфер эти числа. Каждое число размером в байт можно трактовать, как код ASCII какого-то символа При выводе числа на экран эти символы и отображаются. Изображение пикового туза соответствует коду 06, а знак равенства имеет код 3Dh (см. таблицу кодов ACSII на рис. 3.1). Таким образом, сегментный адрес находящейся в памяти резидент­ной программы оказался равен 063DU, что соответствует приблизительно 25 Кбайт. Так и должно быть, так как конфигурация компьютера, исполь­зованного для подготовки примеров, предусматривала хранение большей части DOS в расширенной памяти, в области НМА. В основной памяти в этом случае располагается кусочек DOS вместе с драйверами обслужива­ния расширенной памяти и частью программы COMMAND.COM общим объемом около 25 Кбайт.

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

30 36 33 44 68

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

Читатель может, подготовив рассмотренный пример, загрузить несколь­ко экземпляров программы и посмотреть, как изменяются в этом случае их начальные адреса.

;В сегменте данных array dw 10000 dup(O) ;В программном сегменте

mov BX,offset array

mov SI,0

mov AX,0

;Адрес массива

; И ндекс

;Начальное значение

;заполнителя

mov

mov

inc

add

loop

CX, 10000

[BX][SI],AX

AX

SI,2

fill

fill:

; Счетчик цикла

;3аполнитель пошлем в массив

;Инкремент заполнителя

;Модификация индекса

;Команда цикла

На этапе подготовки мы заносим в регистр ВХ относительный адрес начала массива, отождествляемый с его именем array, устанавливаем на-чатьное значение индекса элемента массива в регистре SI (с таким же успехом можно было взять DI) и начальное значение числа-заполнителя. Сам цикл состоит из трех команд — единственной содержательной ко­манды засылки числа-заполнителя в очередной элемент массива (по ад­ресу, который вычисляется, как сумма содержимого регистров ВХ и SI), а также модификации числа-заполнителя и индекса очередного элемента массива. Завершающей командой loop управление передастся на метку fill, и цикл повторяется столько раз, каково содержимое СХ, в данном случае 10000 шагов.

Следует обратить внимание на команду модификации индекса — в каждом шаге к содержимому SI добавляется 2, так как массив состоит из Двухбайтовых слов. Если бы нужно было заполнить байтовый массив, то в каждом шаге содержимое регистра цикла SI следовало увеличивать на 1.

Стоит отметить некоторые детали, связанные с механизмом выпол­нения команды loop. При реачизации этой команды процессор сначата уменьшает содержимое регистра СХ на 1, а затем сравнивает полученное число с нулем. Если СХ > 0, переход на указанную метку выполняется. Если СХ = 0, цикл разрывается и процессор переходит на команду, еле-

124