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

 

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

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

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

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







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

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

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




Разработал

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

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

Принял

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

Гафаров Р.М.




Ижевск 2012

Оглавление


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

Введение

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

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

3. Алгоритм

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

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

Вывод

Литература


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


Цель работы

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

Задание

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

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

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

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

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

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

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

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

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

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

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

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


Введение


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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Такую пересылку можно осуществить применив команду MOVSB столько раз сколько это необходимо. Т.о. команда DeleteSign работает по следующему алгоритму:

  1. Найти начало первого слова.
  2. Затереть препинания следующие перед первым словом.
  3. Найти следующее слово.
  4. Затереть препинания следующие перед этим словом.
  5. Повторять п.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:= false;i:=1 to (N-1) doWord[i] > Word[i+1] thenWord[i], Word[i+1];:= 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. Алгоритм


  1. Инициализация программы
  2. Ввод строки для обработки
  3. Удаление "лишних" знаков препинания
  4. Поиск слова с максимальной длиной
  5. Приведение слов к "одному размеру"
  6. Сортировка
  7. Определение длины каждого слова и его запись в конец слова
  8. Удаление "лишних" знаков препинания
  9. Вывод на экран результата
  10. Завершение работы программы

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


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


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

"Обработанная строка: "[007],apple[005],are[003],armenian[008],astrachansky[012],banana[006],fruits[006],melon[005],peachs[006],



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


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


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

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

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

;///////////////////////////////////////////////////////////////////////////////////////////Macros.inc ;Включение файла макросов; настройка на реальную ЭВМ

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

START ;НАЧАЛО ПРОГРАММЫMessageIn ;Вывод строки приглашенияMyString ;Ввод строки для обработки;Удаление "лишних" знаков препинания;Поиск слова с MAX длиной;Приведение всех слов к одному размеру;Сортировка слов;Определение длины каждого слова

;и запись этого значения в конец слова;Удаление "лишних" знаков препинания

;после приведения слов к одному размеруMessageOut ;Вывод строки сообщения об окончании обработки.MyString ;Вывод обработанной строки

FINISH ;КОНЕЦ ПРОГРАММЫENDS ;Конец кодового сегментаATA SEGMENT ;Начало сегмента данныхdb 15, 'Введите строку:', '$' ;Сообщение-'Приглашение'db 20, 'Обработанная строка:', '$' ;Сообщение-'Строка обработана'db 249 dup (0), '$' ;Строка для обработкиdb 0h ; Регистрыdb 0h ; общегоdb 0h ; назначенияdb 0h ;Флаг сортировкиdb 0h ;Первый указатель на словоdb 0h ;Второй указатель на словоENDS ;Конец сегмента данных

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

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

InitRealComputer MACRO

.286

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

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

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

ENDM

;--------------------------------------------------------------MACRO

;--------------------------------------------------------------MACRO n ; описание стекаSEGMENT STACKn*kByte dup (?)ENDS

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

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

Data1 ENDS

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

Code1 SEGMENT

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

COURSE endp

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

Code1 ENDSCOURSE

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

START Macrocs:code,ds:data ;Привязка сегментных регистровax, data ;ds, ax ;В DS-адрес сегмета данных

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

FINISH Macroax, 4C00h ;Функция DOS21h ;Завершить программу

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

Sorting macroMbegin, MCMP, MNext, MExit, m0

pushreg < ax, bx > ;Сохранить старые значения регистровal, R0 ;AL=R0 (В R0 длина максимального слова)al ;учитываем знак ', 'Flag, 1 ;установка флага обмена слов: ;Flag, 1 ;обменивали строки?m0 ;Да -продолжаемfar ptr MExit ;Нет-Выход: mov Flag, 0 ;P1, 1 ;Занесение в указатели адресов

;сравниваемыхP2, 1 ;слов.P2, al ;: TestEnd P2 ;Указатель Р2 на конеце предложения?MBegin ;Да -'пузырек всплыл', продолжаем

;Нет-P1, P2 ; сравниваем словаMNext ; если меньше или равно, то продолжаем

; иначеbl, P2 ;bh, P1 ;bh, bl ; меняем слова местамиah, P2 ; P2 на следующее слово

mov P1, ah ; P1=P2P2, al ;

mov Flag, 1 ; Флаг обмена установитьMCMP ; Продолжаем сравнивать:ah, P2 ;P2 на следующее слово

mov P1, ah ;P1=P2P2, al ;

jmp MCMP ;Продолжаем сравнивать: ;Выход< bx, ax > ;Восстановление регистров

;********Проверка на конец предложения****************************macro ofset<si, bx> ;Сохранить старые значения регистровsi, MyString ;Загрузить адрес начала строкиbx, bx ;Очистка BX

mov bl, ofset ;Загрузить адрес элемента проверкиsi, bx ;byte ptr[si], '$' ;Cравнить элемент с признаком конца<bx, si> ;Восстановление регистров

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

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

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

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

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

; вправоdi, cx ;Вычисляем новые значения DI и SIsi, cx ;cx, bx ;Вычисляем кол-во сдвигаемых символовds ;Cовмещение сегментых регистровes ;DS и ESmovsb ;Сдвиг строки<di, si, cx, bx, ax> ;

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

ToOneSize macrotos0, tos1, tos2, tos3, tosend<ax, bx, cx, dx, si, di>si, MyString ;Загрузка строкиdh, byte ptr[si] ;Длина строки

inc si ;di, si ;строка-приемникdl, R0 ;в R0- max длина слова:cx, cx ;Очистка CXcl ;поправка:cl ;считаем кол-во букв в текущ.слове;;Загружаем в AL текущий символdh ;отслеживаем конец предложенияtosend ;если конец предлож-я то выходcl, dl ;если длина слова не равна max длинеTOS2 ;то вставляем символы ', 'cl, cl ;иначе пропускаемsi ;и продолжаем просмотр дальшеTOS1 ;:al, ', ' ;если не конец словаTOS1 ;то длина текущ.слова есть MAX и тогда

;продолжаем просмотрbx, si ;Вычисляем смещение откуда будемbx, di ;сдвигать строкуch, dl ;Вычисляем количество сдвигов

sub ch, cl ;ch, cl ;

xor ch, ch ;si, cx ;И новое значение SI-указатель на строку: ShiftRight bx ;сдвигаем СХ раз со смещ. ВХTOS3 ;TOS0:<di, si, cx, bx, ax>

EndM

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

FindMaxLen macroStart, End, MaxOrNo, No<si, cx, bx, ax>

lea si, MyString ;Загрузка обрабатываемой строкиcl, [si] ;Кол-во символов

xor ch, ch ;bx, bx ;

inc si ;;: ;Ищем первое словоal, '$' ;Если конец предложенияMaxOrNo ;илиal, ', ' ;конец словаMaxOrNo ;то проверяем на MAX длинуbl ;иначе инкреминтируем число букв в словеStart ;продолжаем пока не конец предложенияEnd ;:bl, bh ;сравниваем на MAX длинуNo ;если текущ.длина больше чем MAX'аяbh, bl ;то MAX=текущ.:bl, bl ;иначе очищаем счетчик буквStart ;и продолжаем:R0, bh ;Помещаем в R0 MAX значениеR0, 05h ;Прибавляем к Max значению 5(2 скобки и 3

; цифры)<si, cx, bx, ax>

EndM

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

DeleteSign macroStart, beg, end, m0, m1, m2<si, di, cx, ax>si, Mystring ;Загрузка строкиcl, byte ptr[si] ;Кол-во букв в строке

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

mov byte ptr[si], cl ;di, si ;строка-приемникch, ch ;

add di, cx ;На конец предложенияbyte ptr [di-1], ', ' ;запись в конец предложения ', 'byte ptr[di], '$' ;и признака конца предложенияsi ;на начало строкиdi, si ;ds ;Совмещение регистровes ;

;Удаление знаков препинания если: ;нет первого слова; загрузка символа строкиal, ' ' ; Поиск знаков препинания

je m0 ;al, '.' ;m0 ;al, ',' ;m0 ;cx ;di ;

dec si ; поправкаmovsb ; "Удаление" символов

pop dicxdi

jmp Beg: loop Start

;Удаление препинаний после первого и: ;последующих словsi, didial, ' ' ;Поиск знаков препинания

je m1al, '.'m1al, ','m1BegEnd:

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

je m2al, '.'m2al, ','m2cxdibyte ptr[di-1], ',' ;запись в конец слова ', '

dec si ;поправкаmovsb ;"Удаление" препинаний

pop dicxbeg: loop m1: popreg <ax, cx, di, si>

;******Сравнение слов********************************************macro FirstWord, SecondWord<cx, ds, es, si, di>si, Mystring ;Загрузка строкиdi, sidsesch, ch

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

mov cl, SecondWord ;словdi, cx ;ch, chcl, R0 ;длина цепочкиcmpsb ;продвигаемся по цепочке<di, si, es, ds, cx>

;*****Обменять слова********************************************macro First, SecondmLoop<si, di, cx, ax>si, MyString ;загрузка строкиdi, si ;

xor ch, ch ;cl, First ;вычисление первогоsi, cx ;иch, ch ;второго

mov cl, Second ;словdi, cx ;

xor ch, ch ;cl, R0 ;длина слов:al, byte ptr[si] ;загрузка обмениваемых символов

mov ah, byte ptr[di] ;al, ah ;обменbyte ptr[si], al ;

mov byte ptr[di], ah ;сохранение обменяных символовsi ;di ;mLoop ;продолжаем пока не конец слов

popreg <ax, cx, di, si>

EndM

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

ReadString macro RdStrm1dx, RdStr ;адрес строки DS:DXbx, dxbyte ptr[bx], 250 ;MAX число вводимых символов

mov ah, 0ah ;Фукция DOS ввода строки21h ;вызов прерывания

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

; предложения символа $bx, RdStr ;в bx загружаем адресс строкиbyte ptr[bx+1] ;учитываем символ конца строки '$'cl, [bx+1] ;заносим в счетчик количество символовch, ch ; строки: mov al, [bx+1] ;сдвиг символов вправо на одну позицию[bx], albx ;переход к следующей паре символовm1al, '$' ;заносим в конец строки символ '$'byte ptr[bx], al

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

;13 - перевод строки и 10 возврат кареткиah, 2h ;Функция DOS вывода символаdl, 13 ;в dl загружается код символа

int 21hdl, 1021h

EndM

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

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

lea dx, WrStr ;ссылка на сообщениеdx ;пропускаем длину строки21h ;вывести сообщение на экран

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

;13 - перевод строки и 10 возврат кареткиah, 2h ;Функция DOS вывода символаdl, 13 ;в dl загружается код символа

int 21hdl, 1021h

EndM

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

WriteLenWords macrom0, m1, m2, m3, m4, m5, mend<ax, bx, cx, si, di>

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

inc sidi, sibx, bxbl, R0 ;R0-MAX длина

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

inc di: xor cx, cx ;

mov cl, R0 ;занесение в счетчик: cld ;;загрузка текущего элемента строкиal, '$' ;если конец предложенияmend ; то выходal, ', ' ;если нашли конец словаm2 ; то вычисляемbx, cx ; число букв в словеm5 ; если 0 то ищем след.словоm3 ; иначе записываем в конец длину слова: loop m1: dec si ;конец словаbyte ptr [si], '[' ;Вставляемbyte ptr [si+4], ']' ;скобки иbyte ptr[si+5], ', ' ;знак запятой в строкуal, bl ;AL-длина словаbl, 0Ah ;BL-число 10si, 3 ;Встаем на последний символ числа длиныcx, 3 ;Число делений - 3 т.к.3 цифры: xor ah, ah ;Очищаем остаток от деленияbl ;Делим AL на 10 (AH-остаток, AL-число)ah, 30h ;Прибавляем к остатку код нуля'0'

;чтобы получить ASCII код цифрыbyte ptr[si], ah ;Вставляем в строку полученный символsi ;Сдвигаемся влево на один символm4 ;Повторяем деление три раза: mov si, di ;si-ставим на следующее слово

xor ch, ch ;bl, R0 ;

add di, bx ;di-на следующее после si словоdim0 ;продолжаем вставку длин

mend:<di, si, cx, bx, ax>

EndM

;*****Занесение в стек нескольких регистров**************************macro ReglistReg, <RegList> ;подставить аргумент Reg из списка RegListReg

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

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

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

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

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


Вывод


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

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

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


Литература


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

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

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


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

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ