Untitled Document

Ядерное оружие | Графика | Математика | Физика | Заказать диплом | Информатика | ТКМ | Электротехника | Атомная энергетика | Лекции

Иллюстрированный самоучитель по Ассемблеру начало

 

Обработка строк

Для работы со строками, или цепочками символов или чисел (т.е. попросту говоря, с массивами произвольных данных) в МП предусмотрен ряд специальных команд:

movs - пересылка строки;
cmps - сравнение двух строк;
seas - поиск в строке заданного элемента;
lods - загрузка аккумулятора (регистров AL или АХ) из строки;
stos - запись элемента строки из аккумулятора (регистров АХ или AL).

Эти команды очень удобны, однако их использование сопряжено с некоторыми трудностями, так как процессор, выполняя эти команды, неявным образом использует ряд своих регистров. Только если все эти регистры настроены должным образом, команды будут выполняться правильно. В результате включение в программу предложения с командой, например, movs, требует иной раз 6-7 дополнительных предложений, в которых осуществляется подготовка условий для правильного выполнения этой команды.
Хотя команды обработки строк, как правило, включаются в программу без явного указания операндов, однако каждая команда, в действительности, использует два операнда. Для команд seas и stos операндом-источником служит аккумулятор, а операнд-приемник находится в памяти. Для команды lods, наоборот, операнд-источник находится в памяти, а приемником служит аккумулятор. Наконец, для команд movs и cmps оба операнда, и источник, и приемник, находятся в памяти.
Все рассматриваемые команды, выполняя различные действия, подчиняются одинаковым правилам, перечисленным ниже. Операнды, находящиеся в памяти, всегда адресуются единообразно: операнд-источник через регистры DS:SI, а операнд-приемник через регистры ES:DI. При однократном выполнении команды обрабатывают только один элемент, а для обработки строки команды должны предваряться одним из префиксов повторения. В процессе обработки строки регистры SI и DI автоматически смещаются по строке вперед (если флаг DF = 0) или назад (если флаг DF = 1), обеспечивая адресацию последующих элементов. Каждая команда имеет модификации для работы с байтами или словами (например, movsb и movsw).
Таким образом, для правильного выполнения команд обработки строк необходимо (в общем случае) предварительно настроить регистры DS:SI и ES:DI, установить или сбросить флаг DF, занести в СХ длину обрабатываемой строки, а для команд seas и stos еще поместить операнд-источник в регистр АХ (или AL при работе с байтами).
Однако сама операция, после всей этой настройки, осуществляется одной командой, которая обычно даже не содержит операндов, хотя может иметь префикс повторения.
Стоит подчеркнуть, что строки, обрабатываемые рассматриваемыми командами, могут находиться в любом месте памяти: в полях данных программы, в системных областях данных, в ПЗУ, в видеобуфере. Например, с помощью команды movs можно скопировать массив данных из одной массивной переменной в другую, а можно переслать страницу текста на экран терминала. Рассмотрим несколько примеров использования команд обработки строк, ограничившись лишь теми фрагментами программ, которые имеют отношение к рассматриваемому вопросу.

Пример 3-6. Чтение из ПЗУ BIOS даты его выпуска

Заказать перевод

;В программном сегменте

main proc

mov AX,0F000h    ;Занесем в DS

mov DS,AX            ;Сегментный адрес ПЗУ BIOS

mov SI,0FFF5h      ;Смещение к интересующему нас полю

mov AX,data          ;Настроим RS

mov RS,AX            ;на сегмент данных программы

mov DI,offset bios ;Смещение к полю для хранения даты

mov CX,8               ;Перенести 8 байт

cld                           ;Движение по строке вперед

rep movsb              ;Перенос байтов

;Выведем полученную информацию на экран

mov AX,data         ; Теперь настроим DS

mov DS,AX           ;на сегмент данных программы

mov  AH,40h         ;Функция вывода

mov BX,1              ;Дескриптор экрана

mov CX,8              ;Вывести 0 байт

mov DX,offset bios  ;Смещение в строке

int 21h                      ; Вызов DOS

;В сегменте данных

bios db 8 dup (')      ;Поле для хранения даты

Известно, что в ПЗУ BIOS, сегментный адрес которого составляет F000h (см. рис. 1.5), наряду с программами управления аппаратурой компьютера, хранятся еще и некоторые идентификаторы. Так, в восьми байтах ПЗУ, начиная с адреса F000h:FFFSh, записана в кодах ASCII дата разработки ПЗУ. В примере 3.6 выполняется чтение этой даты, сохранение ее в памяти и вывод на экран для контроля. Поскольку интересующая нас дата хранится в ПЗУ BIOS в кодах ASCII, никаких преобразований содержимого этого участка ПЗУ перед выводом на экран не требуется.
В программе осуществляется настройка всех необходимых для выполнения команды movs регистров (DS:SI, ES:DI, CX и флага DF) и одной командой movsb с префиксом rep содержимое требуемого участка ПЗУ переносится в поле bios. Перенос строки байтами подчеркивает ее формат (в строке записаны байтовые коды ASCII), однако в нашем примере, при четном числе переносимых байтов, более эффективно осуществить перенос по словам. В этом варианте команда movs будет фактически повторяться не 8 раз, а только 4. Для этого достаточно занести в СХ число 4 (вместо 8) и использовать вариант команды niovsw.
Для выполнения команды movs нам пришлось настроить сегментный регистр DS на сегмент BIOS. Если в дальнейшем предполагается обращение к полям данных программы, как это имеет место в примере 3-6, в регистр DS следует занести сегментный адрес сегмента данных. После этого, настроив остальные регистры для вызова функции 40h, прочитанную из BIOS строку можно вывести на экран.
В рассмотренном примере неявно предполагалось, что программа будет в дальнейшем как-то использовать полученную из BIOS информацию. Если задача программы заключается просто в выводе на экран даты выпуска BIOS, то нет необходимости сначала копировать эту дату из BIOS в поля данных программы, а потом выводить ее на экран. Можно было поступить гораздо проще: настроив регистр DS на сегмент BIOS, а регистр DX на адрес строки с датой, вызвать функцию 40h и вывести на экран текст непосредственно из сегмента BIOS. Тогда содержательная часть программы сократится в два раза и примет такой вид:

mov AX,0F00h       ;Настроим DS

mov DS,AX            ;на сегмент BIOS

mov AH,40h           ;Функция вывода

mov BX,1               ;Дескриптор экрана

mov CX,8               ;Вывести 8 байт

mov DX,0FFFSh    ;Смещение к дате

int 21h                     ;Вызов DOS

Приведенный фрагмент не имеет отношения к данному разделу, так как в нем уже нет команд обработки строк. В то же время он подчеркивает важность сегментных регистров и гибкость сегментной адресации. Функция 40h ожидает найти адрес выводимой на экран строки в регистрах DS:DX, и никакие другие регистры в этом случае использовать нельзя. С другой стороны, эти регистры можно настроить на любой участок памяти и вывести на экран (а также и на принтер, в файл или в последовательный порт) данные откуда угодно.
Рассмотрим теперь пример работы с командами lods и stos, которые можно использовать как по отдельности, так и в паре друг с другом. Эти команды очень удобны, в частности, для прямого обращения к видеопамяти.
К экрану, как и к любому другому устройству, входящему в состав компьютера, можно обращаться тремя способами: с помощью функций DOS (прерывание 21h), с использованием прерывания BIOS (для управления экраном используется прерывание 10h) и, наконец, путем прямого программирования аппаратуры, в данном случае видеобуфера (видеопамяти). Функции DOS позволяют выводить только черно-белый текст и имеют ряд других ограничений (нельзя очистить экран, нет средств позиционирования курсора); при использовании прерывания BIOS все эти ограничения снимаются, однако программирование с помощью средств BIOS весьма трудоемко; наконец, прямая запись в видеопамять, предоставляя возможность вывода цветного текста в любую точку экрана, является процедурой очень простой и, к тому же, повышает скорость вывода (по сравнением с использованием системных средств) в десятки и сотни раз. Прямое обращение к видеобуферу удобно использовать, например, в обработчиках прерываний, где запрещен вызов функций DOS и имеются ограничения на обращение к средствам BIOS.
Пусть по ходу программы необходимо вывести в нижнюю строку экрана предупреждающее сообщение. Для этого в программу надо включить следующие предложения:

Пример 3-7. Вывод на экран прямой записью в видеопамять

;В полях данных, адресуемых через DS

msg db 'Измерения закончены'

msg_len=$-msg              ;Длина строки

  ;В программном сегменте

mov SI,offset msg            ;DS:31->выводимая строка

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

mov ES,AX                      ;Будем адресовать через ES

mov DI,25*80*2              ;Смещение к последней строке экрана

mov CX,msg_len              ;Счетчик цикла вывода символов

eld                                 ;DF=0 , движение по строке

                                     ; и по экрану вперед

mov AH,31h                    ;Атрибут символов-синий по

                                    ; голубому

outher: lodsb                  ;Взять символ из строки в AL

show                              ; Вывод на экран символа

                                      ; из AL и его атрибута из AH

loop outser                      ; Цикл

Регистры DS:SI настраиваются на адрес начата выводимой строки; регистры ES:DI - на адрес требуемой позиции в видеобуфере. В регистр СХ надо поместить длину строки в байтах, а флаг DF сбросить, чтобы двигаться по строке вперед. На экран будет выводиться содержимое регистра АХ, в младшем байте которого должен находиться код ASCII выводимого символа, а в старшем байте - атрибут символа, т.е. код цвета символа (в младшем полубайте) и код цвета фона (в старшем полубайте). В примере число 31h образует синие символы по бирюзовому фону. При желании можно выбрать другую комбинацию цветов, выбрав ее с помощью табл. 3.1.

Таблица 3.1. Коды цветов стандартной цветовой палитры                                                                                                                                            

Код  Цвет   Код  Цвет
0h Черный    8h       Серый
1h  Синий   9h  Голубой
2h  Зеленый  10h  Салатовый
3h   Бирюзовый    11h Светло-бирюзовый
4h Красный    12h   Розовый
5h Фиолетовый 13h  Светло-фиолетовый
6h Коричневый14h  Желтый
7h     Белый  15h   Ярко-белый

Выбирая цвета, следует иметь в виду, что при стандартной настройке видеосистемы для цвета фона можно использовать лишь значения из левого столбца таблицы; выбор любого яркого цвета из правого столбца приведет в выводу мерцающего символа. Например, атрибут символа Bill образует синий мерцающий символ на бирюзовом фоне (а не синий символ на светло-бирюзовом фоне).
Содержательную часть цикла вывода образуют две команды lodsb и stosw. Первая команда загружает в регистр AL код очередного символа, вторая выводит его вместе с атрибутом, хранящемся в АН, на экран. При этом после каждого выполнения команды lodsb содержимое SI увеличивается процессором на 1, смещая адресацию к следующему символу строки; в то же время каждое выполнение команды stosw увеличивает DI на 2 (потому что команда stosw работает со словами), смещая адресацию на экране на 2 байт, т.е. как раз к позиции следующего символа.
Примеры использования команд cmps и seas можно найти в Приложении.

Физика лабы
Элементарная математика Кратные интегралы Математический анализ
Векторный анализ Аналитическая геометрия Пределы функции Изучение функции Конспекты по математике Комплексные числа Дифференциальные уравнения Определенные интегралы Лекции по высшей математике Исследование функций Вычисление объема с помощью интегралов Алгеброические структуры