рый 1 0 0 0 Синий 0 0 0 1 Ярко-синий 1 0 0 1 Зеленый 0 0 1 0 Ярко-зеленый 1 0 1 0 Голубой 0 0 1 1 Ярко-голубой 1 0 1 1 Красный 0 1 0 0 Ярко-красный 1 1 0 0 Сиреневый 0 1 0 1 Ярко-сиреневый 1 1 0 1 Коричневый 0 1 1 0 Желтый 1 1 1 0 Белый 0 1 1 0 Ярко-белый 1 1 1 1 Таким образом любые символы могут быть отображены на экране в oдном из 16 цветов. Фон любого символа может иметь один из первых восьми цветов. Если фон и текст имеют один и тот же цвет, то текст получается невидимым. Используя байт атрибута, можно получить также мигающие символы. Байт-атрибут Текстовой режим допускает использование байта атрибута, рассмотpенного в главе 9. В приведенной ниже таблице, атрибут BL обозначает мигание (BLinking), RGB - соответствен но красный, зеленый и синий цвет, I - выделение яркостью: Фон Текст Ассемблер для IBM PC. Глава 10 230 Атрибут: BL R G B I R G B Номера битов: 7 6 5 4 3 2 1 0 Мигание и выделение яркостью относится к тексту. Ниже приведены некоторые типичные атрибуты: Текст по фону Бит: 7 6 5 4 3 2 1 0 BL R G B I R G B Шест. Черный по черному 0 0 0 0 0 0 0 0 00 Синий по черному 0 0 0 0 0 0 0 1 01 Красный по синему 0 0 0 1 0 1 0 0 14 Голубой по зеленому 0 0 1 0 0 0 1 1 23 Светло-сиреневый по белому 0 1 1 1 1 1 0 1 7D Серый по зеленому, мигание 1 0 1 0 1 0 0 0 A8 Байт-атрибут используется аналагично показанному для черно-белого (BW) монитора. Тип монитора можно определить из программы с помощью команды INT 11H. Для BW монитора код 07 устанавливает нормальный атрибут. Для цветных мониторов мож но использовать любую из цветовых комбинаций. Цвет на экране сохраняется до тех пор, пока другая команда не изменит его. Для установки цвета можно использовать в команде INT 10H функции AH=06, AH=07 и AH=09. Например, для вывода пяти мигающих звездочек сетло-зеленым цветом на сиреневом фоне возможна следующая программа: MOV AH,09 ;Функция вывода на экран MOV AL,'*' ;Выводимый символ MOV BH,00 ;Страница 0 MOV BL,0DAH ;Атрибут цвета MOV CX,05 ;Число повторений INT 10H ;Вызвать BIOS ГРАФИЧЕСКИЙ РЕЖИМ ------------------------------------------------------------ Для генерации цветных изображений в графическом режиме используются минимальные точки растра - пиксели или пэлы (pixel). Цветной графический адаптер (CGA) имеет три степени разрешения: 1. Низкое разрешение (не поддерживается в ROM) обеспечива ет вывод 100 строк по 160 точек (т.е. четыре бита на точку). Каждая точка может иметь один из 16 стандартных цветов, как описано в предыдущем разделе "Цвета". Реализация данного режима включает прямую адресацию контролера Motorola 6845 CRT. Для этого используются два порта: шест.3D4 и 3D5. 2. Среднее разрешение для стандартной цветной графики обеспечивает 200 строк по 320 точек. Каждый байт в этом случае представляет четыре точки (т.е. два бита на точку). Ассемблер для IBM PC. Глава 10 231 3. Высокое разрешение обеспечивает 200 строк по 640 точек. Поскольку в данном случае требуется 16К байт памяти, высокое разрешение достигается только в черно-белом (BW) режиме. Каждый байт здесь представляет 8 точек (т.е. один бит на точку). Нулевое значение бита дает черный цвет точки, единичное - белый. Заметим, что в графическом режиме ROM содержит точечные образы только для первых 128 ASCII-кодов. Команда INT 1FH обеспечивает доступ к 1К байтовой области в памяти, определяющей остальные 128 символов. (8 байт на символ). Отображение графических байтов в видео сигналы аналогично, как для среднего, так и для высокого pазрешения. РЕЖИМ СРЕДНЕГО РАЗРЕШЕНИЯ ------------------------------------------------------------ При среднем разрешении каждый байт представляет четыре точки, пронумерованных от 0 до 3: Байт: |C1 C0|C1 C0|C1 C0|C1 C0| Пиксели: 0 1 2 3 В любой момент для каждой точки возможны четыре цвета, от 0 до 3. Ограничение в 4 цвета объясняется тем, что двухбитовая точка имеет 4 комбинации значений битов: 00, 01, 10 и 11. Можно выбpать значение 00 для любого из 16 возможных цветов фона или выбрать значение 01, 10, и 11 для одной из двух палитр. Каждая палитpа имеет три цвета: C1 C0 Палитра 0 Палитра 1 0 0 фон фон 0 1 зеленый голубой 1 0 красный сиреневый 1 1 коричневый белый Для выбора цвета палитры и фона используется INT 10H. Таким обpазом, если, например, выбран фон желтого цвета и палитра 0, то возможны следующие цвета точки: желтый, зеленый, красный и коричневый. Байт, содержащий значение 10101010, соответствует красным точкам. Если выбрать цвет фона - синий и палитру 1, то возможные цвета: синий, голубой, сиреневый и белый. Байт, содержащий значение 00011011, отображает синюю, голубую, сиреневую и белую точки. Прерывание BIOS INT 10H для графики Ассемблер для IBM PC. Глава 10 232 Функция AH=00 команды INT 10H устанавливает графический ркфим. Функция AH=11 команды INT 10H позволяет выбрать цвет палитры и вывести на экран графический символ. Код в регист ре AH определяет функцию: AH=00: Установка режима. Нулевое значение в регистре AH и 04 в pегистре AL устанавливают стандартый цветной графичес кий режим: MOV AH,00 ;Функция установки режима MOV AL,04 ;Разрешение 320х200 INT 10H Установка графического режима приводит к исчезновению курсора с экрана. Подробности по установке режима приведены в главе 9. AH=0BH: Установка цветовой палитры. Число в регистре BH определяет назначение регистра BL: BH=00 выбирает цвета фона и бордюра в соответствии с содержимым pегистра BL. Цвет фона от 1 до 16 соответствует шест. значениям oт 0 до F; BH=01 выбирает палитру соответственно содержимому регист ра BL (0 или 1): MOV AH,0BH ;Функция установки цвета MOV BH,01 ;Выбор палитры MOV BL,00 ; 0 (зеленый, красный, корич.) INT 10H ;Вызвать BIOS Палитра, установленная один раз, сохраняется, пока не будет отменена другой командой. При смене палитры весь экран меняет цветовую комбинацию. При использовании функции AH=0BH в текстовом режиме, значение, установленное для цвета 0 в палитре, определяет цвет бордюра. AH=0CH: Вывод точки на экран. Использование кода 0C в регистре AH позволяет вывести на экран точку в выбранном цвете (фон и палитра). Например, для разрешения 320х200 загрузим в регистр DX вертикальную координату (от 0 до 199), а в регистр CX - горизонтальную координату (от 0 до 319). В регистр AL поместим цвет точки (от 0 до 3): MOV AH,0CH ;Функция вывода точки MOV AL,цвет ;Цвет точки MOV CX,столбец ;Горизонтальная координата MOV DX,строка ;Вертикалькая координата INT 10H ;Вызвать BIOS AH=0DH: Чтение точки с экрана. Данная функция позволяет прочитать точку для определения ее цвета. В регистр DX должна быть загружена вертикальная координата (от 0 до 199), Ассемблер для IBM PC. Глава 10 233 а в регистр CX - горизонтальная (от 0 до 319). В регистре AH должно быть значение 0D. Функция возвращает цвет точки в регистре AL. ------------------------------------------------------------ ------------------------------------------------------------ Рис. 10.1 Вывод на экран в цветном графическом режиме. ПРОГРАММА: УСТАНОВКА ГРАФИЧЕСКОГО РЕЖИМА И ОТОБРАЖЕНИЕ ЦВЕТА ------------------------------------------------------------ Программа, приведенная на рис.10.1, использует команду INT 10H для установки графического режима, выбора зеленого фона и вывода на экран точек (40 строк по 320 столбцов). В программе происходит увеличение значения цвета на 1 для каждой строки. Так как в определении цвета участвуют только три правых бита, цвета повторяются через каждые семь строк. После выполнения программы дисплей остается в графическом режиме. Восстановление текстового режима возможно с помощью команды DOS MODE (MODE CO80) или пользовательской COM программой, в которой для этой цели используется команда INT 10H. ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ ------------------------------------------------------------ ъ Память объемом 16К для цветного дисплея позволяет хранить дополнительные страницы (экраны). Возможны четыре страницы для экранов на 80 столбцов или восемь страниц для экранов на 40 столбцов. ъ Графический режим обеспечивает низкое разрешение (не поддерживается в ROM), среднее разрешение (для цветной графики) и высокое разрешение (для черно-белой графи ки). ъ Точка растра (минимальный элемент графического изображения) представляется определенным числом бит в зависимости от графического адаптера и разрешающей способности (низкой, средней или высокой). ъ Для графики среднего разрешения на цветном графическом адаптере (CGA) можно выбрать четыре цвета, один из которых принадлежит к 16 возможным цветам, а три других формируют цветовую палитру. ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ ------------------------------------------------------------ 10.1. Сколько цветов возможно для фона и для текста на стандартном цветном адаптере (CGA) в текстовом режиме? Ассемблер для IBM PC. Глава 10 234 10.2. Напишите байты атрибуты в двоичном формате для а) сиреневого на ярко-голубом, б) коричневого на желтом, в)красного на сером с миганием. 10.3. Объясните разницу в количестве цветов, возможных при низком, среднем и высоком разрешении. 10.4. Напишите команды для вывода пяти символов карточной масти "бубны" в текстовом режиме ярко-зеленым цветом на сиреневом фоне. 10.5. Напишите команды для установки графического режима с разрешением а) 320х200 в адаптере CGA и б) 640х200 в адаптере EGA. 10.6. Напишите команды для установки синего фона в графичес ком режиме. 10.7. Напишите команды для чтения точки на 12 строке и 13 столбце в графическом режиме. 10.8. Модифицируйте программу на рис.10.1 для: а) графическо го режима на вашем мониторе; б) красного фона; в) строк с 10 по 30; г) столбцов с 20 по 300. Ассемблер для IBM PC. Глава 11 241 ГЛАВА 11. Команды обработки строк ------------------------------------------------------------ Команды обработки строк Цель: Ообъяснить назначение специальных цепочечных команд, используемых для обработки символьных данных. ВВЕДЕНИЕ ------------------------------------------------------------ Команды, показанные в предыдущих главах, оперировали одним байтом, или одним словом за одно выполнение. Часто, однако, бывает необходимо переслать или сравнить поля данных, которые превышают по длине одно слово. Например, необходимо сравнить описания или имена для того, чтобы отсортировать их в восходящей последовательности. Элементы такого формата известны как строковые данные и могут являтся как символьными, так и числовыми. Для обработки строковых данных ассемблер имеет пять команд обработки строк: MOVS переслать один байт или одно слово из одной области памяти в другую; LODS загрузить из памяти один байт в регистр AL или одно слово в регистр AX; STOS записать содержимое регистра AL или AX в память; CMPS сравнить содержимое двух областей памяти, размером в один байт или в одно слово; SCAS сравнить содержимое регистра AL или AX с содержимым памяти. Префикс REP позволяет этим командам обрабатывать строки любой длины. СВОЙСТВА ОПЕРАЦИЙ НАД СТРОКАМИ ------------------------------------------------------------ Цепочечная команда может быть закодирована для повторяю щейся обpаботки одного байта или одного слова за одно выполнение. Например, можно выбрать "байтовую" команду для обработки строки с нечетным числом байт или "двухбайтовую" команду для обработки четного числа байт. Ниже перечислены регистры, участвующие в цепочечных командах (для однобайтовых и двухбайтовых вариантов). Предположим, что регистры DI и SI содержат необходимые адреса: Команда Операнды Байт Слово MOVS DI,SI MOVSB MOVSW LODS AL,SI или AX,SI LODSB LODSW Ассемблер для IBM PC. Глава 11 242 STOS DI,AL или DI,AX STOSB STOSW CMPS SI,DI CMPSB CMPSW SCAS DI,AL или DI,AX SCASB SCASW Например, можно кодировать операнды для команды MOVS, но опустить их для MOVSB и MOVSW. Эти команды предполагают, что pегистры DI и SI содержат относительные адреса, указывающие на необходимые области памяти (для загрузки можно использо вать команду LEA). Регистр SI обычно связан с регистром сегмента данных - DS:SI. Регистр DI всегда связан с регистром дополнительного сегмента - ES:DI. Следовательно, команды MOVS, STOS, CMPS и SCAS требуют инициализации регистра ES (обычно адресом в регистре DS). REP: ПРЕФИКС ПОВТОРЕНИЯ ЦЕПОЧЕЧНОЙ КОМАНДЫ ------------------------------------------------------------ Несмотря на то, что цепочечные команды имеют отношение к одному байту или одному слову, префикс REP обеспечивает повторение команды несколько раз. Префикс кодируется непо средственно перед цепочечной командой, например, REP MOVSB. Для использования префикса REP необходимо установить начальное значение в регистре CX. При выполнении цепочечной команды с префиксом REP происходит уменьшение на 1 значения в регистре CX до нуля. Таким образом, можно обрабатывать строки любой длины. Флаг направления определяет направление повторяющейся операции: - для направления слева направо неоходимо с помощью команды CLD установить флаг DF в 0; - для направления справа налево необходимо с помощью команды STD установить флаг DF в 1. В следующем примере выполняется пересылка 20 байт из STRING1 в STRING2. Предположим, что оба регистра DS и ES инициализированы адресом сегмента данных: STRING1 DB 20 DUP('*') STRING2 DB 20 DUP(' ') ... CLD ;Сброс флага DF MOV CX,20 ;Счетчик на 20 байт LEA DI,STRING2 ;Адрес области "куда" LEA SI,STRING1 ;Адрес одласти "откуда" REP MOVSB ;Переслать данные При выполнееии команд CMPS и SCAS возможна установка флагов состояния, так чтобы операция могла прекратиться сразу после обнаружения необходимого условия. Ниже приведены модификации префикса REP для этих целей. REP - повторять операцию, пока CX не равно 0; Ассемблер для IBM PC. Глава 11 243 REPZили REPE - повторять операцию,пока флаг ZF показывает "равноили ноль".Прекратить операцию при флаге ZF, указывающему на не равно или не ноль или при CX равном 0; REPNE или REPNZ - повторять операцию, пока флаг ZF показывает "не равно или не ноль". Прекратить операцию при флаге ZF, указывающему на "равно или нуль" или при CX равным 0. Для процессоров 8086, 80286 и 80386, обрабатывающих слово за oдно выполнение, использование цепочечных команд, где это возможно, приводит к повышению эффективности работы программы. MOVS: ПЕРЕСЫЛКА СТРОК ------------------------------------------------------------ На рис.7.5 была показана программа для пересылки девяти байтового поля. Программа включала три команды для инициали зации и пять команд для цикла. Команда MOVS с префиксом REP и длиной в регистре CX может выполнять пересылку любого числа символов более эффективно. Для области, принимающей строку, сегментным регистром, является pегистр ES, а регистр DI содержит относительный адрес области, передающей строку. Сегментным регистром является регистр DS, а регистр SI содержит относительный адрес. Таким образом,в начале программы перед выполнением команды MOVS необходимо инициализировать регистр ES вместе с регистром DS, а также загрузить требуемые относительные адреса полей в регистры DI и SI. В зависимости от состояния флага DF команда MOVS производит увеличение или уменьшение на 1 (для байта) или на 2 (для слова) содержимого регистров DI и SI. Приведем команды, эквивалентные цепочечной команде REP MOVSB: JCXZ LABEL2 LABEL1: MOV AL,[SI] MOV [DI],AL INC/DEC DI ;Инкремент или декремент UNC/DEC SI ;Инкремент или декремент LOOP LABEL1 LABEL2: ... В программе на рис. 11.1 процедура C10MVSB использует команду MOVSB для пересылки содержимого десятибайтового поля NAME1 в поле NAME2. Первая команда CLD сбрасывает флаг направления в 0 для обеспечения процесса пересылки слева направо. В нормальном состоянии флаг DF обычно имеет нулевое значение и команда CLD используется из предосторожности. Ассемблер для IBM PC. Глава 11 244 Две команды LEA загружают регистры SI и DI относительными адресами NAME1 и NAME2 соответственно. Так как регистры DS и ES были ранее инициализированы адресом DATASG, то полные адреса полей NAME1 и NAME2 будут в регистрах ES:DI и DS:SI. (COM программа автоматически инициализирует регистры ES и DS). Команда MOV заносит в регистр CX значение 10 - длину полей NAME1 и NAME2. Команда REP MOVSB выполняет следующее: ъ Пересылает самый левый байт из поля NAME1 (адресованно го pегистрами ES:DI) в самый левый байт поля NAME2 (адресованного регистрами DS:SI). ъ Увеличивает на 1 адреса в регистрах DI и SI для следующего байта. ъ Уменьшает CX на 1. ъ Повторяет перечисленные действия (в данном случае 10 раз), пока содержимое регистра CX не станет равным нулю. Поскольку флаг DF имеет нулевое значение, команда MOVSB увеличивает адреса в регистрах DI и SI, и в каждой итерации процесс переходит на байт вправо, т.е. пересылает байт из NAME1+1 в NAME2+1 и т.д. Если бы флаг DF был равен 1, тогда команда MOVSB уменьшала бы адреса в регистрих DI и SI, выполняя процесс справа налево. Но в этом случае регистры SI и DI необходимо инициализировать адресами последних байтов полей, т.е. NAME1+9 и NAME2+9 соответственно. В процедуре D10MVSW (рис.11.1) используется команда MOVSW, пересылающая одно слово за одно выполнение. Так как команда MOVSW увеличивает адреса в регистрах DS и SI на 2, операция требует только пять циклов. Для процесса пересылки справа налево регистр SI должен быть инициализирован адресом NAME1+8, а регистр DI - NAME2+8. LODS: ЗАГРУЗКА СТРОКИ ------------------------------------------------------------ Команда LODS загружает из памяти в регистр AL один байт или в регистр AX одно слово. Адрес памяти определяется регистрами DS:SI. В зависимости от значения флага DF происходит увеличение или уменьшение регистра SI. Поскольку одна команда LODS загружает регистр, то практи ческой пользы от префикса REP в данном случае нет. Часто простая команда MOV полностью адекватна команде LODS, хотя MOV генерирует три байта машинного кода, а LODS - только один, но требует инициализацию регистра SI. Можно использо вать команду LODS в том случае, когда требуется продвигаться вдоль строки (по байту или по слову), проверяя загружаемый регистр на конкретное значение. Команды, эквивалентные команде LODSB: MOV AL,[SI] INC SI Ассемблер для IBM PC. Глава 11 245 На рис.11.1 процедура E10LODS демонстрирует использование команды LODSW. В примере обрабатывается только одно слово: первый байт из области NAME1 (содержащий As) заносится в регистр AL, а второй байт - в регистр AH. В результате в регистре AX получится значение sA. STOS: ЗАПИСЬ СТРОКИ ------------------------------------------------------------ Команда STOS записывает (сохраняет) содержимое регистра AL или AX в байте или в слове памяти. Адрес памяти всегда представляется регистрами ES:DI. В зависимости от флага DF команда STOS также увеличивает или уменьшает адрес в регистре DI на 1 для байта или на 2 для слова. Практическая польза команды STOS с префиксом REP - инициализация области данных конкретным значением, например, очистка дисплейного буфера пробелами. Длина области (в байтах или в cловах) загружается в регистр AX. Команды, эквивалентные команде REP STOSB: JCXZ LABEL2 LABEL1: MOV [DI],AL INC/DEC DI ;Инкремент или декремент LOOP LABEL1 LABEL2: ... На рис.11.1 процедура F10STOS демонстрирует использование команды STOSW. Операция осуществляет запись шест. 2020 (пробелы) пять раз в область NAME3, причем значение из регистра AL заносится в первый байт, а из регистра AH - во второй. По завершении команды регистр DI содержит адрес NAME3+10. CMPS: СРАВНЕНИЕ СТРОК ------------------------------------------------------------ Команда CMPS сравнивает содержимое одной области памяти (адресуемой регистрами DS:SI) с содержимыми другой области (адресуемой как ES:DI). В зависимости от флага DF команда CMPS также увеличивает или уменьшает адреса в регистрах SI и DI на 1 для байта или на 2 для слова. Команда CMPS устанавливает флаги AF, CF, OF, PF, SF и ZF. При использовании префикса REP в регистре CX должна находиться длина сравниваемых полей. Команда CMPS может сравнивать любое число байт или слов. ------------------------------------------------------------ ------------------------------------------------------------ Рис. 11.1. Использование цепочечных команд. Рассмотрим процесс сравнения двух строк, содержащих имена JEAN и JOAN. Сравнение побайтно слева направо приводит к следующему: Ассемблер для IBM PC. Глава 11 246 J : J Равно E : O Не равно (E меньше O) A : A Равно N : N Равно Сравнение всех четырех байт заканчивается сравнением N:N - pавно/нуль. Так как имена "не равны", операция должна пре кратиться, как только будет обнаружено условие "не равно". Для этих целей команда REP имеет модификацию REPE, которая повторяет сравнение до тех пор, пока сравниваемые элементы равны, или регистр CX не pавен нулю. Кодируется повторяющее ся однобайтовое сравнение следующим образом: REPE CMPSB На рис.11.1 в процедере G10CMPS имеются два примера использования команды CMPSB. В первом примере происходит сравнение содержимого полей NAME1 и NAME2. Так как ранее команда MOVSB переслала содержимое поля NAME1 в поле NAME2, то команда CMPSB продолжается на всех десяти байтах и завершается состоянием pавно/нуль: флаг SF получает значение 0 (положительно) и флаг ZF - 1(нуль). Во втором примере сравнивается поля NAME2 и NAME3. Ранее команда STOSW заполнила поле NAME3 пробелами, поэтому команда CMPB завершается после сравнения первых же байт с результатом "больше/неравно": флаг SF получает значение 0 (положительно) и флаг ZF - 0 (ненуль). Первый пример заканчивается с результатом "равно/нуль" и заносит 01 в регистр BH. Второй пример заканчивается с результатом "неравно" и заносит 02 в регистр BL. При трассировке команд с помощью отладчика DEBUG можно увидеть, что в конце процедуры G10CMPS регистр BX будет содержать значение 0102. Предупреждение! Показанные примеры используют команду CMPSB для сравнения одного байта за одно выполнение. При использовании команды CMPSW для сравнения одного слова, необходимо инициализиpовать регистр CX значением 5. Кроме того следует помнить, что команда CMPSW при сравнении слов переставляет байты. Например, сравнивая имена SAMUEL и ARNOLD команда CMPSW выбирает вместо SA и AR переставленные значения, т.е. AS и RA. В результате вместо "больше" получится "меньше", т.е. неправельный результат. Таким образом команда CMPSW работает правильно только при сравне нии строк, которые содержат числовые данные, определенные как DW, DD или DQ. SCAS: СКАНИРОВАНИЕ СТРОК ------------------------------------------------------------ Команда SCAS отличается от команды CMPS тем, что сканирует (просматривает) строку на определенное значение байта или слова. Команда SCAS сравнивает содержимое области Ассемблер для IBM PC. Глава 11 247 памяти (адресуемой pегистрами ES:DI) с содержимым регистра AL или AX. В зависимости от значения флага DF команда SCAS также увеличивает или уменьшает адрес в регистре DI на 1 для байта или на 2 для слова. Команда SCAS устанавливает флаги AF, CF, OF, PF, SF и ZF. При использовании префикса REP и значения длины в регистре CX команда SCAS может сканировать строки любой длины. Команда SCAS особенно полезна, например, в текстовых редакторах, где программа должна сканировать строки, выполняя поиск знаков пунктуации: точек, запятых и пробелов. На рис.11.1 процедура H10SCAS сканирует область NAME1 на строчную букву "m". Так как команда SCASB должна продолжать сканирование, пока результат сравнения - "не равно" или регистр CX не равен нулю, то используется префикс REPNE: REPNE SCASB Так как область NAME1 содержит слово "Assemblers", то команда SCASB находит символ "m" в пятом сравнении. При использовании отладчика DEBUG для трассировки команд в конце процедуры H10SCAS можно увидеть в регистре AH значение 03 для индикации того, что символ "m" найден. Команда REP SCASB кроме того уменьшит значение регистра CX от 10 до 06. Команда SCASW сканирует в памяти слово на соответствие значению в регистре AX. При использовании команд LODSW или MOV для пересылки слова в регистр AX, следует помнить, что первый байт будет в регистре AL, а второй байт - в регистре AH. Так как команда SCAS сравнивает байты в обратной последовательности, то oперация корректна. СКАНИРОВАНИЕ И ЗАМЕНА ------------------------------------------------------------ В процессе обработки текстовой информации может возникнуть необходимость замены определенных символов в тексте на другие, например, подстановка пробелов вместо различных редактирующих символов. В приведенном ниже фрагменте программы осуществляется сканирование cтроки STRING и замена символа амперсанд (&) на символ пробела. Когда команда SCASB обнаружит символ & (в примере это будет позиция STRING+8), то операция сканирования прекратит ся и регистр DI будет содержать aдрес STRING+9. Для получе ния адреса символа & необходимо уменьшить содержимое DI на единицу и записать по полученному адресу символ пробела. STRLEN EQU 15 ;Длина поля STRING STRING DB 'The time&is now' ... CLD MOV AL,'&' ;Искомый символ MOV CX,STRLEN ;Длина поля STRING LEA DI,STRING ;Адрес поля STRING REPNE SCASB ;Сканировать Ассемблер для IBM PC. Глава 11 248 JNZ K20 ;Символ найден? DEC DI ;Да - уменьшить адрес MOV BYTE PTR[DI],20H ;Подставить пробел K20: RET АЛЬТЕРНАТИВНОЕ КОДИРОВАНИЕ ------------------------------------------------------------ При использовании команд MOVSB или MOVSW ассемблер предполагает наличие корректной длины строковых данных и не требует кодирования операндов в команде. Для команды MOVS длина должна быть закодирована в операндах . Например, если поля FLDA и FLDB определены как байтовые (DB), то команда REP MOVS FLDA,FLDB предполагает повторяющуюся пересылку байтов из поля FLDB в поле FLDA. Эту команду можно записать также в следующем виде: REP MOVS ES:BYTE PTR[DI],DS:[SI] Однако загрузка регистров DI и SI адресами FLDA и FLDB oбязательна в любом случае. ДУБЛИРОВАНИЕ ОБРАЗЦА ------------------------------------------------------------ Команда STOS бывает полезна для установки в некоторой области oпределенных значений байтов и слов. Для дублирова ния образца, длина которого превышает размер слова, можно использовать команду MOVS с небольшой модификацией. Предположим, что необходимо сформировать строку следующего вида: ***---***---***---***---***--- . . . Вместо того, чтобы определять полностью всю строку, можно определить только первые шесть байтов. Закодируем образец непосредственно перед обрабатываемой строкой следующим образом: PATTERN DB '***---' DISAREA DB 42 DUP(?) . . CLD MOV CX,21 LEA DI,DISAREA LEA SI,PATTERN REP MOVSW В процессе выполнения команда MOVSW сначала пересылает первое слово (**) из образца PATTERN в первое слово области DISAREA, затем - второе слово (*-), потом третье (--): Ассемблер для IBM PC. Глава 11 249 ***---***--- | | PATTERN DISAREA К этому моменту регистр DI будет содержать адрес DISAREA+6, а pегистр SI - PATTERN+6, который также является адресом DISAREA. Затем команда MOVSW автоматически дублирует образец, пересылая первое слово из DISAREA в DISAREA+6, из DISAREA+2, в DISAREA+8, из DISAREA+4 в DISAREA+10 и т.д. В результате образец будет полностью продублирован по всей области DISAREA: ***---***---***---***---***--- . . . ***--- | | | | PATTERN DISAREA+6 DISAREA+12 DISAREA+42 Данную технику можно использовать для дублирования в области памяти любого образца любой длины. Образец должен быть расположен непосредственно перед принимающей областью. ПРОГРАММА: ВЫРАВНИВАНИЕ ВПРАВО ПРИ ВЫВОДЕ НА ЭКРАН ------------------------------------------------------------ COM-программа, изображенная на рис.1.2, иллюстрирует почти весь материал, приведенный в этой главе. Процедуры программы выполняют следующие действия: B10INPT Принимает имена длиной до 30 символов, вводимых вверху экрана. D10SCAS Использует команду SCASB для сканирования имен и об хода любого ввода, содержащего символ "звездочка". E10RGHT Использует команду MOVSB для выравнивания имен по правой границе, выводит имена в колонку в правой части экрана. Длина в поле ACTNLEN из списка параметров ввода используется для вычисления самого правого символа в имени, например: JEROME KERN OSCAR HAMMERSTEIN RICHARD ROGERS F10CLNM Использует команду STOSW для очистки области имени в памяти. ------------------------------------------------------------ ------------------------------------------------------------ Рис.11.2. Выравнивание вправо при выводе на экран. ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ ------------------------------------------------------------ Ассемблер для IBM PC. Глава 11 250 ъ Для цепочечных команд MOVS, STOS, CMPS и SCAS не забы- вайте инициализировать регистр ES. ъ Сбрасывайте (CLD) или устанавливайте (STD) флаг направ ления в соответствии с направлением обработки. ъ Не забывайте устанавливать в регистрах DI и SI необходи мые значения. Например, команда MOVS предполагает операнды DI,SI, а команда CMPS - SI,DI. ъ Инициализируйте регистр CX в соответствии с количеством байтов или слов, участвующих в процессе обработки. ъ Для обычной обработки используйте префикс REP для команд MOVS и STOS и модифицированный префикс (REPE или REPNE) для команд CMPS и SCAS. ъ Помните об обратной последовательности байтов в сравни ваемых cловах при выполнении команд CMPSW и SCASW. ъ При обработке справа налево устанавливайте начальные адреса на последний байт обрабатываемой области. Если, например, поле NAME1 имеет длину 10 байтов, то для побайтовой обработки данных в этой области справа налево начальный адрес , загружаемый командой LEA, должен быть NAME1+9. Для бработки слов начальный адрес в этом случае - NAME1+8. ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ ------------------------------------------------------------ 11.1. В данной главе приведены эквивалентные команды для а) MOVSB, б) LODSB и в)STOSB с префиксом REP. Напишите эквивалентные команды для обработки по словам а) MOVSW, б) LODSW и в) STOSW с префиксом REP. 11.2. Введите, ассемблируйте и выполните компановку программы, приведенной на рис.11.1. Не забудьте о инициализации регистра ES. Замените команды MOVSB и MOVSW для пересылки справа налево. Измените процедуру H10SCAS для сканирования поля NAME1 на слово "mb". Используя отладчик DEBUG для трассировки процедур, обратите веимание на содержимое сегмента данных и регистров. 11.3. Имеются следующие определения: DATASG SEGMENT PARA CONAME DB 'SPACE EXPLORERS INC.' PRLINE DB 20 DUP(' ') Используя цепочечные команды, выполните: а) пересылку данных из CONAME в PRLINE слева направо; Ассемблер для IBM PC. Глава 11 251 б) пересылку данных из CONAME в PRLINE справа налево; в) загрузку третьего и четвертого байтов области CONAME в регистр AX; г) сохранение содержимого регистра AX в область по адресу PRLINE+5; д) сравнение данных в областях CONAME и PRLINE (они должны быть не равны); е) сканирование областей CONAME и PRLINE, и поиск в ней символа пробел. Если символ будет найден, то переслать его в регистр BH. 11.4. Переделайте процедуру H10SCAS (рис.11.1) так, чтобы выполнялось сканирование поля NAME1 на символ "er". Обратите внимание, что символы "er" не встречаются в поле NAME1 как одно слово: /As/se/mb/le/rs/. Для решения этой проблемы возможны два варианта: а) использовать команду SCASW дважды, причем первая должна начинаться по адресу NAME1, а вторая - по адресу NAME1+1; б) использовать команду SCASB для поиска символа "е" и сравнить затем следующий байт на символ "r". 11.5. Определите поле, содержащее шест.значения 03, 04, 05 и B4. Продублируйте это поле 20 раз и выдайте результат на экран. Ассемблер для IBM PC. Глава 12 262 ГЛАВА 12. Арифметические операции I: Обработка двоичных данных ------------------------------------------------------------ Арифметические операции I: Обработка двоичных данных Цель: Дать сведения об операциях сложения, вычитания, умножения и деления двоичных данных. ВВЕДЕНИЕ ------------------------------------------------------------ Несмотря на то, что мы привыкли к десятичной арифметике (база 10), компьютер работает только с двоичной арифметикой (база 2). Кроме того, ввиду ограничения, накладываемого 16-битовыми регистрами, большие величины требуют специальной обработки. Данная глава дает сведения об операциях сложения, вычитания, умножения и деления для беззнаковых и знаковых данных. В главе приводятся много примеров и предупреждений о различных ловушках для опрометчивых исследователей мира микропроцессора. В следующей главе будут раскрыты операции преобразования между двоичными данными и ASCII кодами. СЛОЖЕНИЕ И ВЫЧИТАНИЕ ------------------------------------------------------------ Команды ADD и SUB выполняют сложение и вычитание байтов или слов, содержащих двоичные данные. Вычитание выполняется в компьютере по методу сложения с двоичным дополнением: для второго операнда устанавливаются обратные значения бит и прибавляется 1, а затем проиCXодит сложение с первым операндом. Во всем, кроме первого шага, операции сложения и вычитания идентичны. На рис. 12.1 представленны примеры команд ADD и SUB, обрабатывающие байты или слова. В процедуре B10ADD используется команда ADD для сложения байтов, а в процедуре C10SUB команда SUB вычитает слова. Примеры показывают все пять возможных ситуаций: сложение/вычитание регистр-регистр; сложение/вычитание память-регистр; сложение/вычитание регистр-память; сложение/вычитание регистр-непоср.значение; сложение/вычитание память-непоср.значение. ------------------------------------------------------------ ------------------------------------------------------------ Рис. 12.1 Примеры команд ADD и SUB. Поскольку прямой операции память-память не существует, данная oперация выполняется через регистр. В следующем примере к содержимому слова WORDB прибавляется содержимое слова WORDA, описанных как DW: Ассемблер для IBM PC. Глава 12 263 MOV AX,WORDA ADD AX,WORDB MOV WORDB,AX Переполнения Опасайтесь переполнений в арифметических операциях. Один байт содержит знаковый бит и семь бит данных, т.е. значения от -128 до +127. Результат арифметической операции может легко превзойти емкость однобайтового регистра. Например, результат сложения в регистре AL, превышающий его емкость, автоматически не переходит в регистр AH. Предположим, что регистр AL содержит шест.60, тогда результат команды ADD AL,20H генерирует в AL суумму - шест.80. Но операция также устанавливает флаг переполнения и знаковый флаг в состояние "отрицательно". Причина заключается в том, что шест.80 или двоичное 1000 0000 является отрицательным числом. Т.е. в результате, вместо +128, мы получим -128. Так как регистр AL слишком мал для такой операции и следует воспользоваться регистром AX. В следующем примере команда CBW (Convert Byte to Word - преобразовать байт в слово) преобразует шест.60 в регистре AL в шест.0060 в регистре AX, передавая при этом знаковый бит (0) через регистр AH. Команда ADD генерирует теперь в регистре AX правильный результат: шест.0080, или +128: CBW ;Расширение AL до AX ADD AX,20H ;Прибавить к AX Но полное слово имеет также ограничение: один знаковый бит и 15 бит данных, что соответствует значениям от -32768 до +32767. Рассмотрим далее как можно обрабатывать числа, превышающие эти пределы. Многословное сложение Максимальное возможное значение в регистре +32767 ограни чивает возможность компьютера для выполнения арифметических операций. Рассмотрим два способа выполнения арифметических операций. Первый способ - более прост, но специфичен, второй - сложнее, но имеет общий характер. ------------------------------------------------------------ ------------------------------------------------------------ Рис. 12.2. Сложение двойных слов. Ассемблер для IBM PC. Глава 12 264 На