Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторна робота СП.docx
Скачиваний:
1
Добавлен:
08.09.2019
Размер:
3.28 Mб
Скачать

Лабораторна робота 8.

Тема: Ланцюжкові команди Асемблера

Ціль: Вивчити основні прийоми обробки рядків у програмах на асемблері.

model tiny

.code

org 100h

Start:

mov si, offset MyStr ; Инициализируем

mov di, offset SubSt ; индексы строк.

M1: call StrLen ; Подсчитать длину строки SubSt

call Compare ; Производим поиск SubStr в MyStr с

; очередного символа.

jc M2

sub si, offset MyStr ; !!! Нашли !!!

inc si

mov InNum, si ; Запишем позицию вхождения.

ret

M2: inc si ; Подстроку не нашли - продолжаем цикл.

cmp byte ptr [si], 0

jne M1

mov InNum, 0 ; Так и не удалось найти подстроку.

ret

MyStr db 'Ассемблер - это язык низкого уровня.',0

SubSt db 'язык ',0

InNum dw ?

StrLen proc

; Осуществляет подсчёт длины строки ASCIIZ.

; Вход - адрес начала строки (в регистре DI).

; Выход - количество символов в строке (в регистре CX).

; !Сама очищает стек от параметров!

push si ; Сохраняем значение регистра SI.

mov si, di

dec si

L11: inc si

cmp byte ptr [si], 0

jne L11

mov cx, si ; Возвращаем результат в CX.

sub cx, di

pop si ; Восстанавливаем значение SI.

ret

StrLen endp

Compare proc

; Производит сравнение CX байт строки по адресу SI с соответствующими

; CX байтами строки по адресу DI. В случае равенства строк флаг CF=0,

; если строки неравны CF=1.

push si ; Сохраняем

push di ; использумые

push cx ; регистры.

cld ; Направление - вперёд.

repe cmpsb ; Сравнение.

jne L21

clc ; Строки равны.

jmp L22

L21: stc ; Строки не равны.

L22: pop cx ; Восстанавливаем

pop di ; сохранённые

pop si ; регистры.

ret

Compare endp

end Start

Задание 2

; Задана строка ASCII. Определить наиболее часто повторяющийся символ.

; Будем считать, что признаком конца строки является байт 00h. Дойдя до этого

; байта, считаем, что строка закончилась и прекращаем просмотр.

; Есть два способа решения этой задачи (оба плохие):

; I способ:

; Создаётся массив статистики из 256 однобайтовых элементов. Строка

; просматривается 1 раз и в зависимости от текущего символа строки,

; соответствующий байт массива статистики увеличивается на единицу.

; После чего, ищем максимальный элемент в массиве статистики. Позиция

; этого элемента и есть ответ.

; В этом алгоритме на вспомогательную структуру (массив статистики) тратится

; много памяти (весь код программы займёт около 20 байт, а этот массив целых

; 256). Зато строка будет просматриваться только один раз.

; II способ.

; Никакого массива статистики не создаётся. Вместо этого, исходная строка

; просматривается 256 раз и на каждом очередном просмотре подсчитывается

; количество соответствующих символов. После этого, количество символов

; сравнивается с максимумом и таким образом определяется часто встречающийся

; символ. Этот алгоритм требует меньше памяти, но гораздо дольше выполняется.

; Рассмотрим реализацию II способа:

model tiny

.code

org 100h

Start:

mov ah, 0 ; Счётчик внешнего цикла по всем элементам

; таблицы ASCII-кодов.

mov ch, 0 ; Частота вхождения самого частовстреч. символа.

M1: mov si, 0 ; Счётчик внутреннего цикла по всем символам

; строки MyStr.

mov cl, 0 ; Сколько раз встречался текущий символ.

M2: mov al, MyStr[si]

cmp al, ah

jne M3

inc cl ; Да, встретился текущий символ.

M3: inc si

cmp MyStr[si], 0 ; Завершение тела внутреннего цикла.

jne M2

cmp cl, ch

jna M4

mov ch, cl ; Нашли новый, более частовстречающися

mov FrecSim, ah ; символ.

M4: inc ah ; Завершение внешнего цикла - пока не

jnz M1 ; переберём все ASCII-символы от 0 до 255.

ret

MyStr db 'Шла Саша по шоссе и сосала сушку.',0 ; Исходная строка.

FrecSim db ? ; Наиболее часто встречающийся символ.

end Start