Моделирование программы гипотетической машины с помощью макросредств

Разработка гипотетической машины при помощи макросредств ассемблера. Разработка алгоритма для реализации обязательных команд: сравнения двух символьных строк; их обмена; определения длины слова. Основные функции обработки строки, листинг программы.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 14.07.2012
Размер файла 59,6 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

5

Размещено на http://www.allbest.ru/

Министерство образования и науки РФ

Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования

Ижевский государственный технический университет имени М.Т. Калашникова

Кафедра "Вычислительная техника"

Курсовая работа

по курсу "Технологии программирования"

на тему: "Моделирование программы гипотетической машины с помощью макросредств"

Разработал

студент группы 4-36-1

Васильев А.С.

Принял

к.т.н., доцент кафедры ВТ

Гафаров Р.М.

Ижевск 2012

Оглавление

Разработка гипотетической машины

Введение

1. Постановка задачи

2. Разработка алгоритма

3. Алгоритм

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

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

Вывод

Литература

Разработка гипотетической машины

Цель работы

Целью данной курсовой работы является изучение стандартных макросредств ассемблера.

Задание

Разработать гипотетическую машину при помощи макросредств ассемблера.

Параметры машины:

1. Формат слова: fw=24 бит

2. Число регистров общего назначения: Nr=3

3. Формат команд ГМ: Fk = {S1,S2; S,I}

4. Количество операндов в команде: Nop=2

5. Команды ГМ для обязательной реализации:

k1: команда сравнения 2-х символьных строк на >,=,<;

k2: команда обмена символьными строками;

k3: команда подсчета количества символов в символьной строке, ограниченной пробелами или знаками препинания.

6. Решить задачу на гипотетической машине:

Расставить слова в символьном массиве в алфавитном порядке, убрав знаки препинания и разделив слова запятыми. После каждого слова поместить в скобках его длину. Сортировку производить в исходном массиве.

Введение

При разработке программ на ассемблере, даже не очень больших по размеру, каждый рано или поздно встречается с рядом проблем. А именно:

1) Плохое понимание исходного текста программы, особенно по прошествии некоторого времени;

2) Повторяемость незначительных или значительных участков программы;

3) Необходимость включения в каждую программу некоторых участков кода используемых в других программах.

Если бы мы писали программу на машинном языке, то данные проблемы были бы принципиально нерешаемыми. Но язык ассемблера, являясь символическим аналогом машинного языка представляет ряд средств для решения этих проблем.

Одним из этих средств являются макросредства. Под макросредствами понимают средства автоматизации программирования. Одним из принципов автоматизации является использование макросредств, когда пользуются одним и тем же текстом.

Таким образом, программирование на языке Ассемблера может быть значительно облегчено, если иметь возможность создавать "стенограмму" часто используемых операторов. Ассемблер обеспечивает эту возможность через макросредства. Макро представляют собой "суперкоманды", которые разгружают ассемблер от части лишней и часто повторяющейся работы по обработке ассемблерной программы. При помощи макросов программисты определяют блоки ассемблерных операторов, а затем, используя конкретные ссылки, указывают ассемблеру на включение соответствующих блоков в ассемблерную программу.

Все это позволяет соединить скорость выполнения ассемблерной программы с мощностью языка высокого уровня.

1. Постановка задачи

Решая задачу с помощью макросов сами макросы поместим в отдельный файл. Каждый макрос назовем так, чтобы его название было понятным, читаемым и выражало бы его функцию. Т.к. некоторые макросы используем неоднократно, а также названия некоторых меток в различных макросах повторяются, то все метки в каждом макросе объявим локальными с помощью LOCAL.

Далее, чтобы каждый макрос выполнял свою функцию и не искажал другой информации, будем сохранять перед выполнением макроса регистры, которые используются в данном макросе, а после завершения работы макроса восстанавливать их. Для этого удобно написать 2-а макроса, которые осуществляют сохранение и восстановление группы регистров в стек.

Поставленную задачу можно разбить на подзадачи и таким образом решить задачу будет более проще. Далее можно разбить подзадачи на еще более мелкие подзадачи, до тех пор пока их можно будет относительно легко решить.

Разобьем задачу на 3-и общие подзадачи:

1. Ввод строки

2. Обработка строки

3. Вывод строки

Первую и третью подзадачи решить относительно просто. А вторую задачу надо будет разбить на еще более простые подзадачи. Эти задачи должны будут выполнять сортировку слов, удаление лишних знаков препинания, определение и запись количества символов в словах. Т.о. разбили 2-ую подзадачу еще на три подзадачи.

Конечно же потребуется разбить и эти подзадачи на более мелкие, но это рассмотрим уже при разработке алгоритма.

Важным является представление строки в данной гипотетической машине. Мы будем представлять ее в следующем виде:

Первый байт - длина строки в байтах.

Второй и последующие байты - сама строка.

Последний байт - символ "$" как признак конца предложения.

Строка состоит максимум из 250 символов.

Не менее важным является организация трех регистров общего назначения.

Их можно определить в сегменте данных как некие переменные размером 8 бит, т.е. один байт. Следует отметить, что эти регистры будут использоваться в командах гипотетической машины. Так очень интенсивно используется регистр R0. Например в него будет заноситься максимальная длина слова, также он будет использоваться в других целях.

Также необходимо создать три обязательные команды, однако их будет не достаточно для решения поставленной задачи. Далее создадим еще несколько команд для решения поставленной задачи.

Задача поставлена и оговорены важные моменты. Теперь можно перейти к разработке алгоритма.

2. Разработка алгоритма

Для начала реализуем 3-и обязательные команды.

1. Сравнить 2-е символьные строки. Макрос CompareWords String1, String2.

Реализовать её можно при помощи команды CMPS (Сравнение двух цепочек), которая по сути выполняет заданную команду. Остаётся только определить адреса сравниваемых элементов и их длину, что не представляет труда.

Адреса определим при помощи загрузки в регистр SI эффективного адреса строки и прибавлением к нему смещения относительно начала строки. Это будет адрес первого слова. Аналогично загрузим в DI адрес второго слова.

Т.к. мы сравниваем цепочку байт, то будем использовать команду CMPSB.

Далее остается проверить флаги стандартным образом и перейти на соответствующую метку.

2. Обмен двух символьных строк. Макрос ChangeWords String1, String2.

Обмен в данном макросе реализован с помощью команды XCHG, которая обменивает 2-а операнда (в нашем случае байта). Так как нам необходимо обменять символьные строки, то естественно надо произвести обмен N байтов, где N - длина строк. В данной гипотетической машине число N будет браться из регистра R0. После определения адресов String1, String2 (определение адресов строк здесь и далее будем осуществлять аналогично описанному в предыдущей команде), числа обмениваемых символов приступаем непосредственно к обмену путем зацикливания команды XCHG на R0 раз. Выбор R0 не означает, что нам придется каждый раз записывать туда значение длины, просто команда определения длины слова будет записывать в этот регистр значение длины. Поэтому удобно использовать команду обмена после команды определения длины слова, которая будет описана ниже.

3. Определение длины слова. Макрос WriteLenWords.

Определить длину слова в строке не составляет труда для этого необходимо знать адрес начала слова, завести счетчик количества букв, а затем, последовательно просматривая строку и инкрементируя счетчик, искать признак конца слова (знак препинания). В счетчике будет находиться длина слова. Наша команда будет выполнять этот алгоритм.

Мы реализовали обязательные команды, однако для выполнения предложенной задачи этого будет мало, поэтому реализуем еще несколько команд.

Как описали в постановке задачи всю задачу мы разбили на подзадачи. Рассмотрим каждую подзадачу в отдельности.

1. Ввод строки.

Ввод реализуем при помощи стандартной функции DOS ввода предложений. После ввода строки приведем ее к стандартному виду гипотетической машины. Для этого в конец предложения запишем символ "$", а в начало - длину получившейся строки.

2. Вывод строки.

Также реализуем при помощи стандартной функции DOS.

3. Обработка строки.

Эта подзадача является самой главной и сложной. С ходу ее не решить, поэтому мы разбиваем ее на подзадачи. Основными функциями обработки являются:

- Сортировка слов

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

- Запись в конец каждого слова значения его длины

Задачи удаления лишних знаков препинания и определения длины каждого слова не являются сложными и их можно реализовать не разбивая их на подзадачи.
Рассмотрим задачу удаления лишних препинаний. Эта задача реализована макросом DeleteSign. Решить задачу можно определением знаков препинаний и затем "удаления" их путём затирания буквами, следующих за этими знаками. При этом надо не забывать уменьшать длину строки в первом байте строки. Также нужно в конец каждого слова записывать символ запятой, т.к. это записано в задании. Реализовать затирание знаков препинания можно пересылая байты с буквами на место байтов с препинаниями.
Такую пересылку можно осуществить применив команду MOVSB столько раз сколько это необходимо. Т.о. команда DeleteSign работает по следующему алгоритму:
Найти начало первого слова.
Затереть препинания следующие перед первым словом.
Найти следующее слово.
Затереть препинания следующие перед этим словом.
Повторять п.4 пока не конец предложения.
Команду вставки в конец слова значения его длины также достаточно просто реализовать. Небольшую сложность представляет собой преобразование численного значения длины слова в символьный эквивалент. В случае если мы сможем это сделать, то вставку этого символьного эквивалента можно будет осуществить путем непосредственной записи соответствующих символов в строку, необходимо будет только зарезервировать в конце каждого слова определенное количество байт, в противном случае значение длины слова может затереть следующее слово.
Далее проходя последовательно по строке и находя конец слова вставлять его длину пока предложение не закончится.
Рассмотрим как реализуется алгоритм преобразования численного значения длины слова в символьный эквивалент.
Одним из возможных вариантов преобразования является табличное преобразование, т.е. по значению регистра R0 мы выбираем из заранее созданной таблицы необходимый символьный эквивалент, например с помощью команды XLAT. Однако такой вариант требует создания таблицы. Но есть у этого варианта и свои преимущества - так например если для записи использовать числа 16-ой или другой системы счисления, где используются не только символы цифр, то этот вариант более предпочтителен.
В данной команде(реализуется в макросе WriteLenWords) будем использовать числа в 10-й системе, как более наглядные. Преобразование производится следующим образом:
Если к примеру в R0 значение длины от 0 до 9, то преобразовать к символьному эквиваленту достаточно легко прибавив к значению R0 число 4810 или 3016 . Тогда мы получим ASCII код числа. Если же в R0 число 2-ух или выше разрядов, то таким образом мы сможем преобразовать только единицы этого числа, но не десятки, сотни и т.д. Следовательно необходимо "выделить" из этого числа единицы, десятки, сотни и т.д. (в нашем случае только десятки и сотни, т.к. вся строка состоит из 250 символов идля представления самого длинного слова понадобится только 3 знака).
А т.к. числа в 10-й системе представляются так:
Xn*10^N+…+X2*10^2+X1*10^1+X0*10^0=десятичное число
макросредство ассемблер алгоритм программа
где Хn - значение числа в N - ом разряде
N - разряд
то выделить их можно путем деления на 1, 10 и 100 тогда каждый раз в остатке получим единичные разряды Xn. Далее прибавляя к ним константу 3016 получим необходимый символ.
Теперь рассмотрим разработку основного и самого сложного алгоритма - сортировка. Сортировку будем осуществлять методом "пузырька". Сама сортировка реализована в макросе Sorting. Однако сам макрос использует несколько других более простых макросов, т.е. задачу сортировки мы разбили на более простые подзадачи.
Алгоритм сортировки можно представить следущим образом:
While Flag do
Begin
Flag:= false;
For i:=1 to (N-1) do
if Word[i] > Word[i+1] then
Begin
ChangeWords Word[i], Word[i+1];
Flag:= true
End;
End.
Где N - число элементов (слов).
Flag - флаг выхода из цикла(если все "пузырки всплыли")
Word - элементы строки (слова).
Сложность представляет не сам процесс сортировки, и даже не процесс обращения к элементам сортировки - словам, а процесс обмена слов, т.к. слова могут быть различной длины, а команда ChangeWords выполняет обмен слов с одинаковой длиной. Одним из выходов является усложнение алгоритма обмена слов. На первый взгляд это решит проблему, однако решив эту проблему таким образом мы породим еще несколько проблем. В частности придется ввести еще команды которые будут: удалять в строке лишние буквы оставшиеся от более длинного слова и расширять строку для записи более длинного слова. Таким образом придется усложнить алгоритм работы всей программы и, соответственно, увеличить ее размеры и уменьшить быстродействие. Вместо всего этого можно предпринять следующее - в строке все слова "привести к одному размеру" путем добавления к концу слов пробелов или других знаков препинания. Длина такого слова с добавленными пробелами должна быть равна длине максимального слова в строке. Соответственно к самому длинному слову ничего добавлять не надо. Этим самым мы добились:
- Не надо писать новых команд расширения и удаления лишних символов
- Не придется усложнять алгоритм обмена слов
- Процесс обращения к элементам сортировки (словам) значительно облегчится, т.к. длина всех слов одинакова и тогда они отстоят друг от друга на некоторое постоянное число.
Приведение всех слов к одному размеру осуществляется макросом ToOneSize.
Алгоритм команды заключается в вычислении длины слова, определении его конца и сдвига вправо строки на определенное число равное (длина max слова-длина текущего слова), этим мы приравниваем все слова к одному размеру. Перед выполнением этой команды мы удаляем из строки все знаки препинания и разделяем слова запятыми. Поэтому при сдвиге каждый предыдущий символ дублируется как символ запятой и нет опасности "появления нового ненужного слова".
Сдвиг осуществляется макросом ShiftRight offset. Для которого указывается адрес начала сдвига. Далее вычисляется количество сдвигаемых байтов и, с помощью команды MOVSB, производится сдвиг на один байт вправо.
Для нахождения длины максимального слова разработан макрос FindMaxLen. Алгоритм его работы прост - он просматривает строку считая длину текущего слова и сравнивая её с длиной максимального слова, если длина текущего слова больше длины максимального, то длина текущего становится максимальной длиной. Далее максимальная длина записывается в регистр R0 и к нему прибавляется число 5. 5 - это число 3-х цифр и 2-х скобок для записи в конец каждого слова его длины.
Теперь приступим к разработке алгоритма сортировки. Далее нам понадобятся еще некоторые команды, однако они не так сложны и объемны, поэтому мы их рассмотрим по ходу разработки алгоритма.
При разработке будем использовать паскалевский эквивалент приведенный выше.
Для начала сортировки необходимо иметь указатели на сравниваемые слова и флаг устанавливающийся в 1 если мы за один проход совершили хотя бы один обмен, в противном случае все "пузырьки всплыли" и сортировка закончена. В качестве указателей будут выступать переменные Р1 и Р2 (можно было бы использовать стандартные регистры, но для улучшения читабельности вводим 2-е переменные). В качестве флага вводим переменную Flag и устанавливаем ее в 1 чтобы не выйти из цикла до его просмотра. Устанавливаем переменную P1 на первое слово, а Р2 на второе (Р1+R0 т.к. в R0 длина максимального слова). Далее сравниваем слова и осуществляем либо обмен либо ищем дальше. Для продолжения сравнения необходимо сдвинуть указатели Р1 и Р2 на следующую пару слов, для этого присваиваем указателю Р1 значение Р2, а к значению Р2 прибавляем R0. Важным является определение конца строки, т.к. Р2 приходит к концу строки раньше то проверяем не стоит ли Р2 на конце строки. Для этого удобно ввести макрос проверки конца строки TestEnd offset. Он осуществляет сравнение текущего элемента с признаком конца строки "$". Если Р2 стоит на конце строки, то проверяем произвели ли за этот проход хотя бы один обмен, если да, то продолжаем "выталкивать очередной пузырёк" иначе сортировка закончена.
Рассмотрим еще несколько макросов необходимых для работы программы:
BeginProg - Инициализация программы. Здесь производится привязка сегментных регистров к соответствующим сегментам.
EndProg - Стандартное завершение DOS программы.
PushReg <Registers list> - Сохранение в стек нескольких указаных регистров.
PopReg < Registers list > - Восстановление из стека нескольких указаных регистров
ReadString string - Чтение с клавиатуры строки для обработки.
WriteString string - Вывод обработанной строки на экран.
Теперь, когда рассмотрены все команды и их работа рассмотрим разработку алгоритма работы заданной задачи. Для начала необходимо ввести строку с помощью команды ReadString MyString, где MyString - наша исходная строка. Далее по условию задачи необходимо удалить все знаки препинания, удалим их с помощью команды DeleteSign. Теперь необходимо отсортировать слова, но перед этим подготовим строку соответствующим образом: найдем длину максимального слова (команда FindMaxLen) и приведем все слова к одному размеру (команда ToOneSize). Теперь отсортируем слова (команда Sorting). Запишем длины всех слов (команда WriteLenWords). Кажется, что задача выполнена, однако после приведения всех слов к одному размеру в строке остались лишние знаки препинания, здесь мы можем опять использовать команду DeleteSign. Задача полностью решена. Теперь запишем алгоритм работы программы.
3. Алгоритм
Инициализация программы
Ввод строки для обработки
Удаление "лишних" знаков препинания
Поиск слова с максимальной длиной
Приведение слов к "одному размеру"
Сортировка
Определение длины каждого слова и его запись в конец слова
Удаление "лишних" знаков препинания
Вывод на экран результата
Завершение работы программы
4. Результаты
При запуске файла Course.exe в ответ на приглашение "Введите строку:" набираем:

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],

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

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

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

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

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

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

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

InitRealComputer ; настройка на реальную ЭВМ

; две предыдущие макрокоманды обеспечивают выполнение программы ГМ на реальной ЭВМ

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

InitRealComputer MACRO

.286

fw = 24 ; разрядность слова ГМ; fw = 8..255

fb = 8 ; разрядность байта

EndLine EQU 10,13,'$' ; код перевода строки при выводе

EndSTR EQU ' ','$' ; признак конца строки

ENDM

;--------------------------------------------------------------

CONSTsection MACRO

ENDM

;--------------------------------------------------------------

STACKsection MACRO n ; описание стека

Stack1 SEGMENT STACK

dw n*kByte dup (?)

Stack1 ENDS

ENDM

;--------------------------------------------------------------

DATAsection MACRO ; описание сегмента данных

Data1 SEGMENT

ENDM

;--------------------------------------------------------------

ENDdata MACRO ; описание конца сегмента данных

Data1 ENDS

ENDM

;--------------------------------------------------------------

CODEsection MACRO ; описание сегмента кода

Code1 SEGMENT

ENDM

;--------------------------------------------------------------

FINISH MACRO ; описание завершения программы

ret

COURSE endp

ENDM

;--------------------------------------------------------------

ENDcode MACRO ; описание конца сегмента кода

Code1 ENDS

END COURSE

ENDM

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

START Macro

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

mov ax, data ;

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

EndM

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

FINISH 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

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

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

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

Вывод

После выполнения работы можно сделать вывод, что использование макросредств значительно упрощает процесс программирования, потому что не приходится несколько раз переписывать один и тот же блок программы, на этом, в какой-то мере, можно сэкономить время. При помощи них можно симулировать работу ЭВМ, например в нашем случае, работу гипотетической машины со своими параметрами.

Однако при этом можно использовать и процедуры. В отличии от макросов они не увеличивают размеров программ, однако имеют низкое быстродействие.

Таким образом, при разработке такого рода лучше всего поступать так: большие фрагменты рекомендуется описывать как процедуры, а маленькие - как макросы.

Литература

1. Гафаров Р.М. Методические указания для выполнения курсовой работы "Моделирование программы гипотетической машины с помощью макросредств ассемблера" по курсу "Технология программирования", изд.:ИжГТУ, 2010г., 49с.

2. В.Н. Пильщиков "Программирование на языке ассемблера IBM PC" - М.: "Диалог-МИФИ",1998г.

3. Абель А.П. "Язык Ассемблера для IBM PC и Программирования" - М.:Высшая школа,1992г.

Размещено на Allbest.ru


Подобные документы

  • Результат нахождения количества отрицательных чисел. Листинг программы, задача которой - удаление всех знаков препинания в символьной строке. Приложение вывода списка очередности предоставления мест в общежитии. Форма для расчета валютных операций.

    отчет по практике [3,8 M], добавлен 15.06.2015

  • Разработка структурной схемы гипотетической ЭВМ, ее функциональной или принципиальной схемы и алгоритма работы конкретного блока, входящего в состав этой ЭВМ. Принципы работы и архитектура центрального процессора и памяти, система прерывания программ.

    курсовая работа [4,1 M], добавлен 25.03.2012

  • Описание алгоритма решения задачи по вычислению суммы элементов строк матрицы с использованием графического способа. Детализация укрупненной схемы алгоритма и разработка программы для решения задачи в среде Turbo Pascal. Листинг и тестирование программы.

    курсовая работа [446,0 K], добавлен 19.06.2014

  • Функциональный состав микро-ЭВМ, разработка системы команд. Описание взаимодействия всех блоков электронно-вычислительной машины при выполнении команд программы. Арифметико-логическое устройство, кэш-память процессора, функциональное моделирование.

    курсовая работа [981,4 K], добавлен 27.05.2013

  • Разработка блок-схемы и программы обработки одномерного массива с доступом к элементам с помощью индексов и с помощью указателей. Словесное описание алгоритма и пользовательского интерфейса, листинг программы обработки матрицы и результат её выполнения.

    курсовая работа [391,1 K], добавлен 30.09.2013

  • Описание алгоритма решения задачи графическим способом. Вывод элементов массива. Описание блоков укрупненной схемы алгоритма на языке Pascal. Листинг программы, а также ее тестирование. Результат выполнения c помощью ввода различных входных данных.

    контрольная работа [150,4 K], добавлен 03.05.2014

  • Задачи трансляторов, характеристика их видов. Этапы и функции основных фаз процесса компиляции. Описание используемых директив и команд ассемблера, алгоритмов, таблиц. Листинг программы. Алгоритм работы программной реализации разрабатываемого компилятора.

    курсовая работа [1,3 M], добавлен 24.06.2013

  • Графическая схема алгоритма выполнения программы определения запасов сырья. Решение задачи с помощью программы MS Excel. Разработка макроса для построения диаграммы. Использование интерфейса программы для работы с таблицей. Разработка базы данных.

    курсовая работа [1,2 M], добавлен 24.04.2014

  • Разработка программы на языке Pascal. Описание переменных. Действия, которые должна выполнить программа согласно выбранного алгоритма. Детализация графической части программы. Листинг и тестирование программы. Вывод массива данных на экран монитора.

    контрольная работа [360,4 K], добавлен 13.06.2012

  • Этапы процедуры принятия решений. Разработка математического алгоритма. Блок-схема алгоритма работы программы. Разработка программы на языке программирования С++ в среде разработки MFC. Текст программы определения технического состояния станка с ЧПУ.

    курсовая работа [823,0 K], добавлен 18.12.2011

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.