Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Тема 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 Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...