Тема 2.9 Строковые операции. Другие команды
Тема 2. 9 Строковые операции. Другие команды Информатика и вычислительная техника / Организация ЭВМ и систем / 9. 1. Строковые операции Для обработки строковых данных имеются пять команд обработки строк: movs — переписать один байт или одно слово из одной области памяти в другую; lods — загрузить из памяти один байт или одно слово в регистр аккумулятор; stos — записать содержимое аккумулятора в память; cmps — сравнить содержимое двух байт или двух слов памяти; scas — сравнить содержимое аккумулятора с одним словом или с одним байтом памяти. Префикс REP позволяет этим командам обрабатывать строки любой длины. Каждая из этих команд не имеет операндов. Данные в них задаются неявно. В этих командах участвуют: · регистры ds, es, si и di; · флаг DF. Обозначим через [ds: si] содержимое байта (или слова), адрес которого задается сегментным регистром ds и индексным регистром si. Аналогично [es: di] обозначает содержимое байта, адрес которого определяется es и di. Команда movsb действует следующим образом: байт [ds: si] переписывается в [es: di]; 1) 2) если флаг DF равен 0, то si и di увеличиваются на 1, в противном случае оба регистра si и di уменьшаются на единицу. Команда movsw отличается от movsb тем, что во втором шаге регистры si и di либо оба увеличиваются на 2, либо оба уменьшаются на 2. Команда lodsb: 1) [ds: si] переписывается в AL; 2) если флаг DF равен 0, то si увеличивается на 1, а если DF=1, то si уменьшается на 1. Команда lodsw отличается тем, что на первом шаге переписывается в AX содержимое слова [ds: si], а на втором шаге si увеличивается или уменьшается на 2. Команда stosb: 1) AL переписывается в [es: di]; 2) если флаг DF равен 0, то di увеличивается на 1, иначе (в случае DF=1) di уменьшается на 1.
Команда stosw отличается тем, что на первом шаге в [es: di] переписывается AX, а на втором di увеличивается или уменьшается на 2. Команда cmpsb: 1) сравнивает байты [ds: si] с [es: di] и устанавливает флаги AF, CF, OF, PF, SF и ZF как команда вычитания [ds: si] – [es: di]; 2) если DF = 0, то si и di увеличиваются на 1, иначе si и di уменьшаются на 1. Команда cmpsw отличается тем, что сравниваются слова и на втором шаге si и di увеличиваются или уменьшаются на 2. Команда scasb: 1) сравнивает AL с [es: di], действует на флаги AF, CF, OF, PF, SF, ZF; 2) если DF =0, то di увеличивается на 1, иначе di уменьшается на 1. Команда scasw сравнивает AX со словом [es: di] и увеличивает или уменьшает di на 2. Префикс повторения. Если поставить перед строковой операцией префикс REP, то строковая операция будет повторяться, пока CX не равен 0. Регистр CX уменьшается на 1 после выполнения операции. Например, выполнение команд lea si, text1 lea di, text2 cld mov cx, 30 rep movsb приводит к копированию тридцати байт строки text1 в строку text2.
Предполагается, что text1 находится в сегменте, на который показывает ds, а text2 – es. Пример 1. Рассмотрим применение строковой операции stosb для изображения на экране российского флага. В следующей программе в es записывается адрес видеоадаптера, а в регистр di – начальное смещение 0. Затем с помощью команд mov cx, 19200 mov al, 15 rep stosb в видеопамять по адресам A0000h, A0001h, …, A0000h+19199 записываются байты, значения которых равны 15. Эти байты соответствуют 60 строкам экрана, окрашенным в белый цвет. Затем, команды mov cx, 19200 mov al, 1 rep stosb окрашивают аналогичным образом следующие 60 строк в синий цвет, а команды mov cx, 19200 mov al, 4 rep stosb – в красный. < 1 > title a03. com — Российский флаг < 2 > codesg segment < 3 > assume cs: codesg, ds: codesg, ss: codesg < 4 > org 100h < 5 > main proc near < 6 > mov ah, 0fh < 7 > int 10h < 8 > push ax < 9 > mov ax, 0013h < 10 > int 10h < 11 > mov ax, 0A000h < 12 > mov es, ax < 13 > mov di, 0 < 14 > mov cx, 19200 < 15 > mov al, 15; белый < 16 > rep stosb
< 17 > mov cx, 19200 < 18 > mov al, 1; голубой < 19 > rep stosb < 20 > mov cx, 19200 < 21 > mov al, 4; красный < 22 > rep stosb < 23 > mov ax, 0 < 24 > int 16h < 25 > pop ax < 26 > mov ah, 0 < 27 > int 10h < 28 > ret < 29 > main endp < 30 > codesg ends < 31 > end main Префикс повторения имеет следующие модификации: REPZ или REPE – повторять операции, пока флаг ZF равен 0; операция закончится, если CX=0 или ZF=1; после каждого выполнения операции CX уменьшается на единицу. PERNZ или REPNE – повторять операцию, пока флаг ZF равен 1; операция закончится, если CX=0 или ZF=0; после каждого выполнения операции регистр CX будет уменьшаться на 1. Пример 2. Пусть в сегменте данных определена строка символов text db 10 dup(‘ ‘); которая в процессе работы программы изменяется. Напишем подпрограмму поиска символа ‘a’ в этой строке, предполагая, что при ее вызове регистр es установлен на сегмент данных: finda proc cld mov cx, 10 lea di, text mov ah, 0; символ ‘a’ не найден mov al, ’a’ repne scasb jne a10 mov ah, 1; признак того, что ‘a’ найден a10: ret finda endp Если символ ‘a’ найден в строке, то подпрограмма возвращает ah = 1, а es: di будет адресом позиции, содержащей символ ‘a’. В противном случае подпрограмма возвращает ah = 0.
Тема 3 Макроопределения Многие задачи можно решать, используя макроопределение с аргументами или функцию. Что из них следует применять нам? На этот счет нет строгих правил, но есть некоторые соображения. Макроопределения должны использоваться скорее как хитрости, а не как обычные функции: они могут иметь нежелательные побочные эффекты, если вы будете неосторожны. Некоторые компиляторы ограничивают макроопределения одной строкой, и, по-видимому, лучше соблюдать такое ограничение, даже если ваш компилятор этого не делает. Выбор макроопределения приводит к увеличению объема памяти, а выбор функции - к увеличению времени работы программы. Так что думайте, что выбрать! Макроопределение создает " строчный" код, т. е. вы получаете оператор в программе. Если макроопределение применить 20 раз, то в вашу программу вставится 20 строк кода. Если вы используете функцию 20 раз, у вас будет только одна копия операторов функции, поэтому получается меньший объем памяти. Однако управление программой следует передать туда, где находится функция, а затем вернуться в вызывающую программу, а на это потребуется больше времени, чем при работе со " строчными" кодами.
Преимущество макроопределений заключается в том, что при их использовании вам не нужно беспокоиться о типах переменных (макроопределения имеют дело с символьными строками, а не с фактическими значениями). Так наше макроопределение SQUARE(x) можно использовать одинаково хорошо с переменными типа int или float. Обычно программисты используют макроопределения для простых действии, подобных следующим: #define MAX(X, Y) ( (X) > (Y)? (X): (Y)) #define ABS(X) ( (X) < 0? -(X): (X)) #define ISSIGN(X) ( (X) == '+' || (X) == '-'? 1: 0) (Последнее макроопределение имеет значение 1 (истинно), если X является символом алгебраического знака. ) Отметим следующие моменты: 1. В макроопределении нет пробелов, но они могут появиться в замещающей строке. Препроцессор " полагает", что макроопределение заканчивается на первом пробеле, поэтому все, что стоит после пробела, остается в замещающей строке.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|