Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
oaip_2 / Курсовая ОАиП.doc
Скачиваний:
100
Добавлен:
27.05.2013
Размер:
204.8 Кб
Скачать

BeginProg – Инициализация программы. Здесь производится привязка сегментных регистров к соответствующим сегментам.

EndProg – Стандартное завершение DOS программы.

PushReg <Registers list> – Сохранение в стек нескольких указаных регистров.

PopReg < Registers list > – Восстановление из стека нескольких указаных регистров

ReadString string – Чтение с клавиатуры строки для обработки.

WriteString string – Вывод обработанной строки на экран.

Теперь , когда рассмотрены все команды и их работа рассмотрим разработку алгоритма работы заданной задачи. Для начала необходимо ввести строку с помощью команды ReadString MyString , где MyString – наша исходная строка. Далее по условию задачи необходимо удалить все знаки препинания , удалим их с помощью команды DeleteSign. Теперь необходимо отсортировать слова , но перед этим подготовим строку соответствующим образом: найдем длину максимального слова (команда FindMaxLen) и приведем все слова к одному размеру (команда ToOneSize). Теперь отсортируем слова (команда Sorting). Запишем длины всех слов (команда WriteLenWords). Кажется , что задача выполнена , однако после приведения всех слов к одному размеру в строке остались лишние знаки препинания , здесь мы можем опять использовать команду DeleteSign. Задача полностью решена. Теперь запишем алгоритм работы программы.

6.Алгоритм

  1. Инициализация программы

  2. Ввод строки для обработки

  3. Удаление “лишних” знаков препинания

  4. Поиск слова с максимальной длиной

  5. Приведение слов к “одному размеру”

  6. Сортировка

  7. Определение длины каждого слова и его запись в конец слова

  8. Удаление “лишних” знаков препинания

  9. Вывод на экран результата

  10. Завершение работы программы

7.Результаты

При запуске файла Course.exe в ответ на приглашение “Введите строку:” набираем:

яблоки,арбузы астраханские,бананы африканские,персики армянские все это фрукты.

Получаем “Обработанная строка:”

арбузы[006],армянские[009],астраханские[012],африканские[011],бананы[006],все[003],персики[007],фрукты[006],это[003],яблоки[006],

“Введите строку:”

apple,melon astrachansky,african banana,armenian peachs are fruits.

“Обработанная строка”:

african[007],apple[005],are[003],armenian[008],astrachansky[012],banana[006],fruits[006],melon[005],peachs[006],

Введите строку:

,,,,,.....груши груши груши,,груша тоже фрукт

Обработанная строка:

груша[005],груши[005],груши[005],груши[005],тоже[004],фрукт[005],

По результатам видно , что программа работает правильно (как с русскими , так и с латинскими буквами).

8.Листинг программы

;///////////////////////////////////////////////////////////////////////////////////////////

:// Листинг основной программы

;//Сортировка слов с определением их длины и удалением знаков препинания.

;// Ver.1.00Beta 14.11.00 23:57 Tutaev Alex

;///////////////////////////////////////////////////////////////////////////////////////////

INCLUDE Macros.inc ;Включение файла макросов

CODE SEGMENT ;Начало кодового сегмента

BeginProg ;НАЧАЛО ПРОГРАММЫ

WriteString MessageIn ;Вывод строки приглашения

ReadString MyString ;Ввод строки для обработки

DeleteSign ;Удаление "лишних" знаков препинания

FindMaxLen ;Поиск слова с MAX длиной

ToOneSize ;Приведение всех слов к одному размеру

Sorting ;Сортировка слов

WriteLenWords ;Определение длины каждого слова

;и запись этого значения в конец слова

DeleteSign ;Удаление "лишних" знаков препинания

;после приведения слов к одному размеру

WriteString MessageOut ;Вывод строки сообщения об окончании обработки.

Writestring MyString ;Вывод обработанной строки

EndProg ;КОНЕЦ ПРОГРАММЫ

CODE ENDS ;Конец кодового сегмента

DATA SEGMENT ;Начало сегмента данных

MessageIn db 15 , 'Введите строку:' , '$' ;Сообщение-'Приглашение'

MessageOut db 20 , 'Обработанная строка:' , '$' ;Сообщение-'Строка обработана'

MyString db 249 dup (0) , '$' ;Строка для обработки

R0 db 0h ; Регистры

R1 db 0h ; общего

R2 db 0h ; назначения

Flag db 0h ;Флаг сортировки

P1 db 0h ;Первый указатель на слово

P2 db 0h ;Второй указатель на слово

DATA ENDS ;Конец сегмента данных

END

;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

;\\ Листинг макро библиотеки для файла Course.asm

;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

;********Инициализация программы**********************************

BeginProg Macro

assume cs:code,ds:data ;Привязка сегментных регистров

mov ax , data ;

mov ds , ax ;В DS-адрес сегмета данных

EndM

;********Завершение программы************************************

EndProg Macro

mov ax , 4C00h ;Функция DOS

int 21h ;Завершить программу

EndM

;********Сортировка слов методом пузырька'**************************

Sorting macro

Local Mbegin , MCMP , MNext , MExit , m0

pushreg < ax , bx > ;Сохранить старые значения регистров

mov al , R0 ;AL=R0 (В R0 длина максимального слова)

inc al ;учитываем знак ' , '

mov Flag , 1 ;установка флага обмена слов

Mbegin: ;

Cmp Flag , 1 ;обменивали строки?

je m0 ;Да -продолжаем

jmp far ptr MExit ;Нет-Выход

m0: mov Flag , 0 ;

mov P1 , 1 ;Занесение в указатели адресов

;сравниваемых

mov P2 , 1 ;слов.

add P2 , al ;

MCMP: TestEnd P2 ;Указатель Р2 на конеце предложения?

je MBegin ;Да -'пузырек всплыл' , продолжаем

;Нет-

CompareWords P1 , P2 ; сравниваем слова

jbe MNext ; если меньше или равно , то продолжаем

; иначе

mov bl , P2 ;

mov bh , P1 ;

ChangeWords bh , bl ; меняем слова местами

mov ah , P2 ; P2 на следующее слово

mov P1 , ah ; P1=P2

add P2 , al ;

mov Flag , 1 ; Флаг обмена установить

jmp MCMP ; Продолжаем сравнивать

MNext:

mov ah , P2 ;P2 на следующее слово

mov P1 , ah ;P1=P2

add P2 , al ;

jmp MCMP ;Продолжаем сравнивать

MExit: ;Выход

popreg < bx , ax > ;Восстановление регистров

EndM

;********Проверка на конец предложения****************************

TestEnd macro ofset

pushreg <si , bx> ;Сохранить старые значения регистров

lea si , MyString ;Загрузить адрес начала строки

xor bx , bx ;Очистка BX

mov bl , ofset ;Загрузить адрес элемента проверки

add si , bx ;

cmp byte ptr[si] , '$' ;Cравнить элемент с признаком конца

popreg <bx , si> ;Восстановление регистров

EndM

;********Сдвиг строки вправо*************************************

ShiftRight macro ofset

pushreg <ax , bx , cx , si , di>

mov bx , ofset ;С какого элемента сдвигать

dec bx

lea di , MyString ;Адрес сдвигаемой строки

mov si , di ;

inc di ;

xor ch , ch ;

mov cl , byte ptr[si] ;Загрузка длины строки

inc cx ;

mov byte ptr[si] , cl ;Увеличиваем длину строки , т.к.сдвинем ее

; вправо

add di , cx ;Вычисляем новые значения DI и SI

add si , cx ;

sub cx , bx ;Вычисляем кол-во сдвигаемых символов

push ds ;Cовмещение сегментых регистров

pop es ;DS и ES

std

rep movsb ;Сдвиг строки

popreg <di , si , cx , bx , ax> ;

EndM

;******Приведение всех слов к одному "размеру"*********************

ToOneSize macro

local tos0 , tos1 , tos2 , tos3 , tosend

pushreg <ax , bx , cx , dx , si , di>

lea si , MyString ;Загрузка строки

mov dh , byte ptr[si] ;Длина строки

inc si ;

mov di , si ;строка-приемник

mov dl , R0 ;в R0- max длина слова

TOS0:

xor cx , cx ;Очистка CX

dec cl ;поправка

TOS1:

inc cl ;считаем кол-во букв в текущ.слове

cld ;

lodsb ;Загружаем в AL текущий символ

dec dh ;отслеживаем конец предложения

jz tosend ;если конец предлож-я то выход

cmp cl , dl ;если длина слова не равна max длине

jne TOS2 ;то вставляем символы ' , '

xor cl , cl ;иначе пропускаем

inc si ;и продолжаем просмотр дальше

jmp TOS1 ;

TOS2:

cmp al , ' , ' ;если не конец слова

jne TOS1 ;то длина текущ.слова есть MAX и тогда

;продолжаем просмотр

mov bx , si ;Вычисляем смещение откуда будем

sub bx , di ;сдвигать строку

mov ch , dl ;Вычисляем количество сдвигов

sub ch , cl ;

xchg ch , cl ;

xor ch , ch ;

add si , cx ;И новое значение SI-указатель на строку

TOS3: ShiftRight bx ;сдвигаем СХ раз со смещ. ВХ

loop TOS3 ;

jmp TOS0

TOSEND:

popreg <di , si , cx , bx , ax>

EndM

;******Поиск слова с максимальной длиной***************************

FindMaxLen macro

local Start , End , MaxOrNo , No

pushreg <si , cx , bx , ax>

lea si , MyString ;Загрузка обрабатываемой строки

mov cl , [si] ;Кол-во символов

xor ch , ch ;

xor bx , bx ;

inc si ;

cld ;

Start: ;Ищем первое слово

lodsb

cmp al , '$' ;Если конец предложения

je MaxOrNo ;или

cmp al , ' , ' ;конец слова

je MaxOrNo ;то проверяем на MAX длину

inc bl ;иначе инкреминтируем число букв в слове

loop Start ;продолжаем пока не конец предложения

jmp End ;

MaxOrNo:

cmp bl , bh ;сравниваем на MAX длину

jbe No ;если текущ.длина больше чем MAX'ая

mov bh , bl ;то MAX=текущ.

No:

xor bl , bl ;иначе очищаем счетчик букв

jmp Start ;и продолжаем

End:

mov R0 , bh ;Помещаем в R0 MAX значение

Add R0 , 05h ;Прибавляем к Max значению 5(2 скобки и 3

; цифры)

popreg <si , cx , bx , ax>

EndM

;******Удаление "лишних" знаков препинания**************************

DeleteSign macro

local Start , beg , end , m0 , m1 , m2

Pushreg <si , di , cx , ax>

lea si , Mystring ;Загрузка строки

mov cl , byte ptr[si] ;Кол-во букв в строке

inc cl ;инкр.т.к.добавим один символ

mov byte ptr[si] , cl ;

mov di , si ;строка-приемник

xor ch , ch ;

add di , cx ;На конец предложения

mov byte ptr [di-1] , ' , ' ;запись в конец предложения ' , '

mov byte ptr[di] , '$' ;и признака конца предложения

inc si ;на начало строки

mov di , si ;

push ds ;Совмещение регистров

pop es ;

;Удаление знаков препинания если

Start: ;нет первого слова

lodsb ; загрузка символа строки

cmp al , ' ' ; Поиск знаков препинания

je m0 ;

cmp al , '.' ;

je m0 ;

cmp al , ',' ;

je m0 ;

push cx ;

push di ;

dec si ; поправка

rep movsb ; "Удаление" символов

pop di

pop cx

dec di

jmp Beg

m0: loop Start

;Удаление препинаний после первого и

Beg: ;последующих слов

mov si , di

inc di

lodsb

cmp al , ' ' ;Поиск знаков препинания

je m1

cmp al , '.'

je m1

cmp al , ','

je m1

loop Beg

jmp End

m1:

lodsb

cmp al , ' ' ;Поиск знаков препинания

je m2

cmp al , '.'

je m2

cmp al , ','

je m2

push cx

push di

mov byte ptr[di-1] , ',' ;запись в конец слова ' , '

dec si ;поправка

rep movsb ;"Удаление" препинаний

pop di

pop cx

jmp beg

m2: loop m1

End: popreg <ax , cx , di , si>

ENDM

;******Сравнение слов********************************************

CompareWords macro FirstWord , SecondWord

pushreg <cx , ds , es , si , di>

lea si , Mystring ;Загрузка строки

mov di , si

push ds

pop es

xor ch , ch

mov cl , FirstWord ;Вычисление начала первого

add si , cx ;и

xor ch , ch ;второго

mov cl , SecondWord ;слов

add di , cx ;

xor ch , ch

mov cl , R0 ;длина цепочки

cld

repe cmpsb ;продвигаемся по цепочке

popreg <di , si , es , ds , cx>

ENDM

;*****Обменять слова********************************************

ChangeWords macro First , Second

local mLoop

pushreg <si , di , cx , ax>

lea si , MyString ;загрузка строки

mov di , si ;

xor ch , ch ;

mov cl , First ;вычисление первого

add si , cx ;и

xor ch , ch ;второго

mov cl , Second ;слов

add di , cx ;

xor ch , ch ;

mov cl , R0 ;длина слов

mLoop:

mov al , byte ptr[si] ;загрузка обмениваемых символов

mov ah , byte ptr[di] ;

xchg al , ah ;обмен

mov byte ptr[si] , al ;

mov byte ptr[di] , ah ;сохранение обменяных символов

inc si ;

inc di ;

loop mLoop ;продолжаем пока не конец слов

popreg <ax , cx , di , si>

EndM

;*****Cчитывание строки с клавиатуры******************************

ReadString macro RdStr

local m1

lea dx , RdStr ;адрес строки DS:DX

mov bx , dx

mov byte ptr[bx] , 250 ;MAX число вводимых символов

mov ah , 0ah ;Фукция DOS ввода строки

int 21h ;вызов прерывания

;пропуск 1-го байта и запись в конец

; предложения символа $

lea bx , RdStr ;в bx загружаем адресс строки

inc byte ptr[bx+1] ;учитываем символ конца строки '$'

mov cl , [bx+1] ;заносим в счетчик количество символов

xor ch , ch ; строки

m1: mov al , [bx+1] ;сдвиг символов вправо на одну позицию

mov [bx] , al

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

loop m1

mov al , '$' ;заносим в конец строки символ '$'

mov byte ptr[bx] , al

;Перевод строки путем вывода на экран последовательно 2-х символов

;13 - перевод строки и 10 возврат каретки

mov ah , 2h ;Функция DOS вывода символа

mov dl , 13 ;в dl загружается код символа

int 21h

mov dl , 10

int 21h

EndM

;****Вывод строки на экран*****************************************

WriteString macro WrStr

mov ah , 09h ;Функция DOS вывода строки

lea dx , WrStr ;ссылка на сообщение

inc dx ;пропускаем длину строки

int 21h ;вывести сообщение на экран

;Перевод строки путем вывода на экран последовательно 2-х символов

;13 - перевод строки и 10 возврат каретки

mov ah , 2h ;Функция DOS вывода символа

mov dl , 13 ;в dl загружается код символа

int 21h

mov dl , 10

int 21h

EndM

;******Вставка в конец слов значения их длин*************************

WriteLenWords macro

local m0 , m1 , m2 , m3 , m4 , m5 , mend

pushreg <ax , bx , cx , si , di>

lea si , mystring ;Загружаем в SI адрес строки

inc si

mov di , si

xor bx , bx

mov bl , R0 ;R0-MAX длина

add di , bx ;di-cледующее слово

inc di

m0: xor cx , cx ;

mov cl , R0 ;занесение в счетчик

m1: cld ;

lodsb ;загрузка текущего элемента строки

cmp al , '$' ;если конец предложения

je mend ; то выход

cmp al , ' , ' ;если нашли конец слова

jne m2 ; то вычисляем

sub bx , cx ; число букв в слове

jz m5 ; если 0 то ищем след.слово

jmp m3 ; иначе записываем в конец длину слова

m2: loop m1

m3: dec si ;конец слова

mov byte ptr [si] , '[' ;Вставляем

mov byte ptr [si+4] , ']' ;скобки и

mov byte ptr[si+5] , ' , ' ;знак запятой в строку

mov al , bl ;AL-длина слова

mov bl , 0Ah ;BL-число 10

add si , 3 ;Встаем на последний символ числа длины

mov cx , 3 ;Число делений - 3 т.к.3 цифры

m4: xor ah , ah ;Очищаем остаток от деления

div bl ;Делим AL на 10 (AH-остаток , AL-число)

add ah , 30h ;Прибавляем к остатку код нуля'0'

;чтобы получить ASCII код цифры

mov byte ptr[si] , ah ;Вставляем в строку полученный символ

dec si ;Сдвигаемся влево на один символ

loop m4 ;Повторяем деление три раза

m5: mov si , di ;si-ставим на следующее слово

xor ch , ch ;

mov bl , R0 ;

add di , bx ;di-на следующее после si слово

inc di

jmp m0 ;продолжаем вставку длин

mend:

popreg <di , si , cx , bx , ax>

EndM

;*****Занесение в стек нескольких регистров**************************

PushReg macro Reglist

Irp Reg , <RegList> ;подставить аргумент Reg из списка RegList

push Reg

EndM

EndM

;*****Чтение из стека нескольких регистров************************

PopReg macro Reglist

Irp Reg , <RegList> ;подставить аргумент Reg из списка RegList

pop Reg

EndM

EndM

;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

;\\ КОНЕЦ ФАЙЛА \\\

;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

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