Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / GL16.doc
Скачиваний:
16
Добавлен:
20.05.2014
Размер:
103.94 Кб
Скачать

Xorax,ax; Счетчик несовпадающих элементов

mov si, OFFSET s1

mov di, OFFSET s2

comp:repecmpsb; Повторять, пока совпадение

jefin; Исчерпали строки — закончить

Incax; Нашли совпадение — увеличить счетчик

orcx,cx; Строки исчерпаны?

jnecomp; Нет — продолжим сравнение

fin: mov ax, 4C00h

Int 21h

END start

Для строк, указанных в программе, количество несовпадений равно 1.

Пример. В строке отыскать адрес последнего вхождения буквы 'z'.

string db "asdzbxzar",0

...

mov ax, @data

mov es, ax

cld

mov al,0

mov di, OFFSET string

movcx, -1

repnescasb; Найти конец строки

decdi; Переместить указатель на 0

std; Поиск в направлении уменьшения адресов

mov al, 'z'

mov cx, -1

repnescasb

Incdi; Вернуть указатель на найденный символ

; В DI— адрес символа

...

Эта программа некорректна. Она правильно работает, если в строке заведомо имеется символ 'z'.

Упражнение. Переработать этот фрагмент так, чтобы программа корректно работала и при отсутствии символа 'z'.

Пример. В строке превратить прописные буквы в строчные.

.MODEL small

.STACK 100h

.DATA

string DB "aSd1-E"

lenstr = $ - string

.CODE

start:mov ax,@data

mov ds,ax

mov es,ax

mov si, OFFSET string

mov di,si

mov cx,lenstr

cld

L: lodsb

cmp al,'A'

jnae m

cmp al,'Z'

jnbe m

add al, 'a'-'A'

m: stosb

loop L

mov ax,4C00h

Int 21h

END start

Часть цикла можно было переписать эффективнее:

add al, 'a'-'A'

stosb

loop L

jmp short fin

m: inc di

loop L

fin: mov ax,4C00h

Тогда не происходит лишнего обращения к памяти, а только перемещается указатель.

А теперь пример на новые возможности 386-го процессора.

Пример. Заполнить массив двойных слов числом 12345678h. Сразу посмотрим листинг.

1 0000 MODEL small

2 .386

3 0000 STACK 100h

4 0000 .DATA

5 0000 0C*(00000000) arr DD 12 DUP(0)

6 0030 .CODE

7 0000 B8 0000s start:mov ax,@data

8 0003 8E D8 mov ds,ax

9 0005 8E C0 mov es,ax

10 0007 66| B8 12345678 mov eax,12345678h

11 000D 66| B9 0000000C mov ecx,12

12 0013 66| BF 00000000r mov edi,OFFSET arr

13 0019 FC cld

14 001A F3> 66| AB rep stosd

15 001D B8 4C00 mov ax,4C00h

16 0020 CD 21 int 21h

17 END start

Отметим , что в листинге для команды rep stosd имеется два префикса: 66 — префикс размера операнда, и F3 — префикс повторения.

И еще замечание, не имеющее отношения к строковым операциям. Вместо команды mov ecx,12 можно написать mov cx,12, а вместо mov edi,OFFSET arr — mov di,OFFSET arr. Убедимся, например, во втором утверждении. Заменим команду mov edi,OFFSET arr двумя командами:

mov edi, 0FFFF0000h

mov di,OFFSET arr

В отладчике можно убедиться, что заполнение массива происходит правильно. 32-разрядный адрес преобразуется в 16-разрядный посредством отбрасывания старших разрядов.

16.7. Команды загрузки адресов

Для целей дальнейшего изложения здесь уместно ввести команды ldsиles, Которые к строковым командам не имеют прямого отношения.

Ранее была введена команда lea— загрузить эффективный (исполнительный) адрес. Вот еще две команды.

Загрузить указатель в сегменте данных

lds reg,src

reg  src

DS  src + 2

(Load pointer using DS)

флаги не изменяются

Загрузить указатель в дополнительном сегменте данных

les reg,src

reg  src

ES  src + 2

(Load pointer using ES)

флаги не изменяются

Источником srcдля этих команд служит операнд — двойное слово. Младшее слово загружается в регистр-указатель (как правило,SIилиDI), а старшее — в сегментный регистр.

Соседние файлы в папке Лекции