Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
76
Добавлен:
11.02.2014
Размер:
223.84 Кб
Скачать

Листинг 5 – Использование команды LODS для преобразования пропиных букв в строчные

.model small

.stack 100h

.data

Str1 db 'ABcDEfG',13,10,'$'

.code

.386

mov ax,@data mov ds,ax mov es,ax

mov ah,9

 

; вывод исходной строки

 

lea dx,Str1

 

 

 

 

int 21h

 

 

 

 

 

lea si,Str1

; загрузка в es:si смещения строки

lea di,Str1

; загрузка в es:di смещения строки

cld

 

; сброс флага df

 

 

mov cx,sizeof Str1

; длина строки

 

 

next_symbol:

 

; обработка следующего символа

 

lodsb [si]

; загрузка в al очередного символа

cmp al,41h

; что код символа не меньше 41h

 

jb m1

 

; и не больше 5Ah (буква прописная),

cmp al,5Ah

; если буква прописная, то пропускаем

ja m1

 

; и переходим к следующей

 

or al,00100000b

; меняем регистр

 

 

m1:

 

 

 

 

 

stosb [di]

; записываем обратно

 

 

loop next_symbol

; обработка следующего символа

 

mov ah,9

 

; вывод измененной строки

 

lea dx,Str1

 

 

 

 

int 21h

 

 

 

 

 

mov ah,1

 

 

 

 

 

int 21h

 

 

 

 

 

mov ax, 4C00h

 

 

 

 

int 21h

 

 

 

 

 

end

 

 

 

 

 

Сравнение

цепочек

командой

CMPS

(CMPSc

адрес_приемника,

адрес_источника)

Команды, реализующие операцию-примитив сравнения цепочек, производят сравнение элементов цепочки-источника с элементами цепочки-приемника.

Адрес_источника определяет адрес цепочки-источника в сегменте данных, заранее загружаемый в пару регистров DS: ESI/SI;

Адрес_приемника определяет адрес цепочки-приемника, которая должна находиться в дополнительном сегменте, заранее загружаемый в пару регистров

ES:EDI/DI.

Алгоритм работы команды CMPS заключается в последовательном выполнении вычитания (элемент цепочки-источника минус элемент цепочки-получателя) над

11

очередными элементами обеих цепочек. Принцип выполнения вычитания командой CMPS такой же, как у команды сравнения СМР. Она так же, как и СМР, производит вычитание элементов, не записывая при этом результата, и устанавливает флаги ZF, SF и OF. После вычитания очередных элементов цепочек командой CMPS индексные регистры ESI/SI и EDI/DI автоматически изменяются в соответствии со значением флага DF на значение, равное размеру элемента сравниваемых цепочек. Чтобы заставить команду CMPS выполняться несколько раз, то есть произвести последовательное сравнение элементов цепочек, необходимо перед командой CMPS определить префикс повторения.

Работа с портами ввода-вывода командами INS и OUT (INSc адрес_приемника, номер_порта и OUTc номер_порта, адрес_источника)

Команды позволяют организовать эффективную передачу данных между портами ввода-вывода и цепочками в памяти. Эти две команды позволяют достичь более высокой скорости передачи данных по сравнению с той скоростью, которую может обеспечить контроллер DMA (Direct Memory Access – прямой доступ к памяти).

Ввод элемента цепочки из порта ввода-вывода осуществляется командой INS. Эта команда вводит элемент из порта, номер которого находится в регистре DX, в элемент цепочки, адрес памяти которого определяется операндом адрес_приемника. Несмотря на то, что цепочка, в которую вводится элемент, адресуется указанием этого операнда, ее адрес должен быть явно сформирован в паре регистров ES:EDI/DI. Размер элементов цепочки должен быть согласован с размером порта – он определяется директивой резервирования памяти, с помощью которой выделяется память для размещения элементов цепочки. После пересылки команда INS производит коррекцию содержимого регистра EDI/DI на величину, равную размеру элемента, участвовавшего в операции пересылки. Как обычно, при работе цепочечных команд учитывается состояние флага

DF.

Операция вывода элемента цепочки в порт ввода-вывода реализуется командой OUTS. Эта команда выводит элемент цепочки в порт, номер которого находится в регистре DX. Адрес элемента цепочки определяется операндом адрес_источника. Несмотря на то, что цепочка, из которой выводится элемент, адресуется указанием этого операнда, значение адреса должно быть явно сформировано в паре регистров DS:t'SI/SI. Размер структурных элементов цепочки должен быть согласован с размером порта — он определяется директивой резервирования памяти, с помощью которой выделяется память для размещения элементов цепочки. После пересылки команда OUTS производит коррекцию содержимого регистра ESI/SI на величину, равную размеру элемента цепочки, участвовавшего в операции пересылки. При этом, как обычно, учитывается состояние флага DF.

Задания 1 Программу из листинга 2 оформить в виде процедур (участок кода, в котором

выводится номер элемента и строка равен/не равен нулю).

2 Используя, если надо, регистр AX как вспомогательный и считая, что флаг направления DF равен 0, описать через другие (не строковые) команды действие команды: а) MOVSB; б) SCASB; в) LODSB; г) STOSB; д) REP MOVSB.

12

3 Дано описание:

S DB 100 DUP(?) ; S array [0..99] of char

T DB 100 DUP(?) ; T array [0..99] of char

Рассматривая S и T как символьные строки фиксированной длины, описанные в сегменте данных, на начало которого уже установлены регистры DS и ES, и используя строковые команды, выписать фрагмент программы для решения следующей задачи.

Вариант

Задание

1

Определить, со скольких пробелов начинается строка S, и записать ответ в

 

регистр CL

2

Определить, сколькими пробелами заканчивается строка S, и записать ответ в

 

регистр CL

3

Найти индекс (от 0 до 99) первого вхождения буквы 'Q' в строку S и записать

 

ответ в регистр DI; если эта буква не входит в S, то в DI записать −1

4

Заменить в строке S последнее вхождение буквы 'n' ('N')

5

Записать в регистр BH число вхождений символа '*' в строку S

6

Определить, равны ли левая и правая половины строки S, и записать ответ 1

 

(равны) или 0 в регистр AL

7

Определить, входят ли первые 5 символов строки T в строку S как подстрока, и

 

записать ответ 1 (входят) или 0 в регистр AL

8

Заменить последние 10 символов строки S на 10 первых символов строки T

9

Циклически сдвинуть элементы строки S на две позиции влево

10

Если первая и вторая четверти строки S не равны, то заменить третью четверть

 

на последнюю

11

Переписать содержимое строки T в строку S с заменой всех пробелов на

 

символ '*'

12

В строке S заменить все пробелы на символ '*'

13

В строке S заменить все большие латинские буквы на соответствующие малые

14

Удалить из строки S все цифры, сдвинув к ее началу все остальные символы и

 

дописав пробелы в ее конец

13