МОСКОВСКИЙГОСУДАРСТВЕННЫЙ ОТКРЫТЫЙ УНИВЕРСИТЕТ
ФАКУЛЬТЕТИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ
ПОЯСНИТЕЛЬНАЯЗАПИСКА К КУРСОВОЙ РАБОТЕ
по дисциплине:
«Системное программирование»
Выполнил:Тябенков А.О.
студентIV курса МГОУ
Специальность:200106
Шифр:6041013/ с
Проверил:Юрагов Е.А.
2008
МОСКОВСКИЙГОСУДАРСТВЕННЫЙ ОТКРЫТЫЙ УНИВЕРИТЕТ
Факультетинформатики и радиоэлектроники
Кафедра:Информационная измерительная техника
Специальность:200106
ЗАДАНИЕ
Накурсовой проект Тябенкова Антона Олеговича Шифр: 6041013/с
1. Тема работы:
На языкеассемблера разработать алгоритм контроля, на циклический CRC-код, массиваданных хранящегося в некоторой области памяти. Код должен быть сохранен дляпоследующей периодической проверки массива данных. В случае несовпадения наэкран должно выводиться сообщение об искажении данных.
2. Содержаниепояснительной записки:
Введение
1. Созданиепрограммы на ассемблере
2. Синтаксисассемблера
3. Описаниеалгоритма
4. Описаниепрограммы
Заключение
Список литературы
3.Дата выдачи задания:
4.Срок выполнения:
Заданиевыдал _______________Юрагов Е.А.
Заданиепринял _______________Тябенков А.О.
СОДЕРЖАНИЕ
Введение--------------------------------------------------------------------------------- 2
1. Создание программы на ассемблере---------------------------------------- 6
2. Синтаксис ассемблера------------------------------------------------------------ 12
3. Описание алгоритма-------------------------------------------------------------- 17
4. Описание программы------------------------------------------------------------ 19
Приложение 1 Блок-схема алгоритма — 20
Приложение 2 Листинг программы--------------------------------------------- 21
Заключение----------------------------------------------------------------------------- 26
Список литературы------------------------------------------------------------------- 27
ВВЕДЕНИЕ
Микропроцессорыкорпорации Intel и персональные компьютеры на их базе прошли не очень длинныйво времени, но значительный по существу путь развития, на протяжении которогокардинально изменялись их возможности и даже сами принципы их архитектуры.
В то же время,внося в микропроцессор принципиальные изменения, разработчики были вынужденыпостоянно иметь в виду необходимость обеспечения совместимости новых моделейсо старыми, чтобы не отпугивать потенциального покупателя перспективой полнойзамены освоенного или разработанного им программного обеспечения. В результатесовременные микропроцессоры типа Pentium, обеспечивая такие возможности, как32-битную адресацию почти неограниченных объемов памяти, многозадачный режим содновременным выполнением нескольких программ, аппаратные средства защитыоперационной системы и прикладных программ друг от друга, богатый набордополнительных эффективных команд и способов адресации, в то же время могутработать (и часто работают) в режиме первых микропроцессоров типа 8086, используявсего лишь 1 мегабайт оперативной памяти, 16-разрядные операнды (т. е. числа вдиапазоне до 216-1=65535) и ограниченный состав команд. Посколькупрограммирование на языке ассемблера напрямую затрагивает аппаратныевозможности микропроцессора, прежде всего, следует выяснить, в какой степенипрограммист может использовать новые возможности микропроцессоров в своихпрограммах, и какие проблемы программной несовместимости могут при этомвозникнуть.
Первыеперсональные компьютеры корпорации IBM, появившиеся в 1981 г. и получившиеназвание IBM PC, использовали в качестве центрального вычислительного узла16-разрядный микропроцессор с 8-разрядной внешней шиной Intel 8088. Вдальнейшем в персональных компьютерах стал использоваться и другой вариантмикропроцессора, 8086, который отличался от 8088 тем, что являлся полностью16-разрядным. С тех пор его имя стало нарицательным, и в программах,использующих только возможности процессоров 8088 или 8086, говорят, что ониработают в режиме 86-го процессора.
В 1983 г.корпорацией Intel был предложен микропроцессор 80286, в котором был реализованпринципиально новый режим работы, получивший название защищенного. Однакопроцессор 80286 мог работать и в режиме 86-го процессора, который сталиназывать реальным.
В дальнейшем насмену процессору 80286 пришли модели 80386, i486 и, наконец, различные вариантыпроцессора Pentium. Все они могут работать и в реальном, и в защищенномрежимах. Хотя каждая следующая модель была значительно совершеннее предыдущей(в частности, почти на два порядка возросла скорость работы процессора, начинаяс модели 80386 процессор стал 32-разрядным, а в процессорах Pentium реализовандаже 64-разрядный обмен данными с системной шиной), однако с точки зренияпрограммиста все эти процессоры весьма схожи. Основным их качеством являетсяналичие двух режимов работы — реального и защищенного. Строго говоря, всовременных процессорах реализован еще и третий режим — виртуального 86-гопроцессора, или V86, однако в плане использования языка ассемблера этот режимне отличается от обычного режима 86-го процессора, и в этой книге мы егокасаться не будем.
Реальный изащищенный режимы прежде всего принципиально различаются способом обращения коперативной памяти компьютера. Метод адресации памяти, используемый в реальномрежиме, позволяет адресовать память лишь в пределах 1 Мбайт; в защищенномрежиме используется другой механизм (из-за чего, в частности, эти режимы иоказались полностью несовместимыми), позволяющий обращаться к памяти объемомдо 4 Гбайт. Другое важное отличие защищенного режима заключается в аппаратнойподдержке многозадачности с аппаратной же (т.е. реализованной в самоммикропроцессоре) защитой задач друг от друга.
Реальный изащищенный режимы имеют прямое отношение к работе операционной системы,установленной на компьютере.
В настоящее времяна персональных компьютерах типа IBM PC используются в основном два классаоперационных систем (оба — разработки корпорации Microsoft): однозадачнаятекстовая система MS-DOS и многозадачная графическая система Windows.Операционная система MS-DOS является системой реального режима; другимисловами, она использует только средства процессора 8086, даже если онаустановлена на компьютере с процессором Pentium. Система Windows — это системазащищенного режима; она значительно более полно использует возможностисовременных процессоров, в частности, многозадачность и расширенное адресноепространство. Разумеется, система Windows не могла бы работать с процессором8086, так как в нем не был реализован защищенный режим.
Соответственнодвум типам операционных систем, и все программное обеспечение персональныхкомпьютеров подразделяется на два класса: программы, предназначенные дляработы под управлением MS-DOS (их часто называют приложениями DOS) и программы,предназначенные для системы Windows (приложения Windows). Естественно, приложения.DOS могут работать только в реальном режиме, а приложения Windows — только взащищенном.
Таким образом,выражения «программирование в системе MS-DOS», «программирование в реальномрежиме» и «программирование 86-го процессора» фактически являются синонимами.При этом следует подчеркнуть, что хотя процессор 8086, как микросхема, ужедавно не используется, его архитектура и система команд целиком вошли всовременные процессоры. Лишь относительно небольшое число команд современных процессоровспециально предназначены для организации защищенного режима и распознаютсяпроцессором, только когда он работает в защищенном режиме.
Целью выполнения даннойкурсовой работы является получение практических навыков работы программированияна языке ассемблера.
Итогом выполнениякурсовой работы является разработка алгоритма контроля на четность массиваданных, хранящегося в некоторой области памяти и программы на языке ассемблера,реализующий данный алгоритм.
1. СОЗДАНИЕ ПРОГРАММЫ НА АССЕМБЛЕРЕ.
Надежностьпрограммы достигается, в первую очередь, благодаря ее правильномупроектированию, а не бесконечному тестированию. Это правило означает, что еслипрограмма правильно разработана в отношении как структур данных, так иструктур управления, то это в определенной степени гарантирует правильность еефункционирования. При применении такого стиля программирования ошибки являютсялегко локализуемыми и устранимыми.
В большинствеслучаев рекомендуется следующий процесс разработки программы на ассемблере:
1.Этап постановкии формулировки задачи:
· изучение предметной области и сбор материала впроблемно-ориентированном контексте;
· определение назначения программы, выработка требований к нейи представление требований, если возможно, в формализованном виде;
· формулирование требований к представлению исходных данных ивыходных результатов;
· определение структур входных и выходных данных;
· формирование ограничений и допущений на исходные и выходныеданные.
2.Этаппроектирования:
· формирование «ассемблерной» модели задачи;
· выбор метода реализации задачи;
· разработка алгоритма реализации задачи;
· разработка структуры программы в соответствии с выбранноймоделью памяти.
3. Этап кодирования:
· уточнение структуры входных и выходных данных и определениеассемблерного формата их представления;
· программирование задачи;
· комментирование текста программы и составление предварительного описания программы.
4. Этап отладкии тестирования:
· составление тестов для проверки правильности работыпрограммы;
· обнаружение, локализация и устранение ошибок в программе,выявленных в тестах;
· корректировка кода программы и ее описания.
5. Этапэксплуатации и сопровождения:
· настройка программы на конкретные условия использования;
· обучение пользователей работе с программой;
· организация сбора сведений о сбоях в работе программы,ошибках в выходных данных, пожеланиях по улучшению интерфейса и удобства рабеты с программой;
· модификация программы с целью устранения выявленных ошибок и,при необходимости, изменения ее функциональных возможностей.
К порядкуприменения и полноте выполнения перечисленных этапов нужно подходить разумно.Многое определяется особенностями конкретной задачи, ее назначением, объемомкода и обрабатываемых данных, другими характеристиками задачи. Некоторые изэтих этапов могут либо выполняться одновременно с другими этапами, либо вовсеотсутствовать.
Традиционно усуществующих реализаций ассемблера нет интегрированной среды, подобнойинтегрированным средам Turbo Pascal, Turbo С или Visual C++. Поэтому длявыполнения всех функций по вводу кода программы, ее трансляции, редактированиюи отладке необходимо использовать отдельные служебные программы. Большая частьих входит в состав специализированных пакетов ассемблера.
На рисунке одинприведена общая схема процесса разработки программы на ассемблере. На схемевыделено четыре шага процесса. На первом шаге, когда вводится код программы,можно использовать любой текстовый редактор. Основным требованием к немуявляется то, чтобы он не вставлял посторонних символов (спецсимволовредактировании). Файл должен иметь расширение. asm.
/>
Рис. 1. «Процессразработки программы на ассемблере».
Программы,реализующие остальные шаги схемы, входят в состав программного пакетаассемблера. После написания текста программы на ассемблере наступает следующийэтап — трансляция программы. На этом шаге формируется объектный модуль, которыйвключает в себя представление исходной программы в машинных кодах и некоторуюдругую информацию, необходимую для отладки и компоновки его с другими модулями.Традиционно на рынке ассемблеров для микропроцессоров фирмы Intel имеется двапакета: «Макроассемблер» MASM фирмы Microsoft и Turbo Assembler TASM фирмыBorland.
У этих пакетовмного общего. Пакет макроассемблера фирмы Microsoft (MASM) получил своеназвание потому, что он позволял программисту задавать макроопределения (илимакросы), представляющие собой именованные группы команд. Они обладали темсвойством, что их можно было вставлять в программу в любом месте, указав толькоимя группы в месте вставки. Пакет Turbo Assembler (TASM) интересен тем, чтоимеет два режима работы. Один из этих режимов, называемый MASM, поддерживаетвсе основные возможности макроассемблера MASM. Другой режим, называемый IDEAL,предоставляет более удобный синтаксис написания программ, более эффективноеиспользование памяти при трансляции программы и другие новшества, приближающиекомпилятор ассемблера к компиляторам языков высокого уровня.
В эти пакетывходят трансляторы, компоновщики, отладчики и другие утилиты для повышенияэффективности процесса разработки программ на ассемблере.
В данной курсовойработе для получения объектного модуля исходный файл подвергается трансляциипри помощи программы tasm.exe из пакета TASM.
После устраненияошибок можно приступать к следующему шагу — созданию исполняемого(загрузочного) модуля, или, как еще называют этот процесс, к компоновкепрограммы. Главная цель этого шага — преобразовать код и данные в объектныхфайлах в их перемещаемое выполняемое отображение. Процесс создания исполняемогомодуля разделяют на 2 шага — трансляцию и компоновку. Это сделано намеренно длятого, чтобы можно было объединять вместе несколько модулей (написанных на одномили нескольких языках). Формат объектного файла позволяет, при определенныхусловиях, объединить несколько отдельно оттранслированных исходных модулей водин модуль. При этом в функции компоновщика входит разрешение внешних ссылок(ссылок на процедуры и переменные) в этих модулях. Результатом работыкомпоновщика является создание загрузочного файла с расширением ехе. Послеэтого операционная система может загрузить такой файл и выполнить его.
Устранение синтаксических ошибок еще не гарантирует того, что программа будет хотя бы будетзапускаться, не говоря уже о правильности работы. Поэтому обязательным этапомпроцесса разработки является отладка.
На этапе отладки,используя описание алгоритма, выполняется контроль правильностифункционирования как отдельных участков кода, так и всей программы в целом. Нодаже успешное окончание отладки еще не является гарантией того, что программабудет работать правильно со всеми возможными исходными данными. Поэтому нужнообязательно провести тестирование программы, то есть проверить ее работу на«пограничных» и заведомо некорректных исходных данных. Для этого составляютсятесты.
Специфика программна ассемблере состоит в том, что они интенсивно работают с аппаратнымиресурсами компьютера. Это обстоятельство заставляет программиста постоянноотслеживать содержимое определенных регистров и областей памяти. Естественно,что человеку трудно следить за этой информацией с большой степенью детализации.Поэтому для локализации логических ошибок в программах используют специальныйтип программного обеспечения — программные отладчики.
Отладчики бываютдвух типов:
· интегрированные — отладчик реализован в виде интегрированнойсреды типа среды для языков Turbo Pascal, Quick С и т.д.;
· автономные — отладчик представляет собой отдельную программу.
Из-за того, чтоассемблер не имеет своей интегрированной среды, для отладки написанных на немпрограмм используют автономные отладчики. К настоящему времени разработанобольшое количество таких отладчиков. В общем случае с помощью автономногоотладчика можно исследовать работу любой программы, для которой созданисполняемый модуль, независимо от того, на каком языке был написан его исходныйтекст.
2.СИНТАКСИС АССЕМБЛЕРА
Предложения,составляющие программу, могут представлять собой синтаксическую конструкцию,соответствующую команде, макрокоманде, директиве или комментарию. Для тогочтобы транслятор ассемблера мог распознать их, они должны формироваться поопределенным синтаксическим правилам.
Предложенияассемблера формируются из лексем, представляющих собой синтаксически неразделимые последовательности допустимых символов языка имеющие смысл длятранслятора. Лексемами являются:
· идентификаторы — последовательности допустимых символов,использующиеся для обозначения таких объектов программы, как коды операций,имена переменных и названия меток. Правило записи идентификаторов заключается вследующем. Идентификатор может состоять из одного или нескольких символов. Вкачестве символов можно использовать буквы латинского алфавита, цифры инекоторые специальные знаки — _, ?, $, @.
· цепочки символов — последовательности символов, заключенные водинарные или двойные кавычки;
· целые числа в одной из следующих систем счисления: двоичной,десятичной, шестнадцатеричной. Отождествление чисел при записи их в программахна ассемблере производится по определенным правилам. Десятичные числа нетребуют для своего отождествления указания каких-либо дополнительных символов.
Практически каждоепредложение содержит описание объекта, над которым или при помощи котороговыполняется некоторое действие. Эти объекты называются операндами. Их можноопределить так: операнды — это объекты (некоторые значения, регистры или ячейкипамяти), на которые действуют инструкции или директивы, либо это объекты,которые определяют или уточняют действие инструкций или директив.
Операнды могуткомбинироваться с арифметическими, логическими, побитовыми и атрибутивнымиоператорами для расчета некоторого значения или определения ячейки памяти, накоторую будет воздействовать данная команда или директива.
Рассмотримклассификацию операндов, поддерживаемых транслятором ассемблера.
Постоянныеили непосредственные операнды —число, строка, имя или выражение, имеющие некоторое фиксированное значение.Имя не должно быть перемещаемым, то есть зависеть от адреса загрузки программыв память.
Адресныеоперанды — задают физическое расположениеоперанда в памяти с помощью указания двух составляющих адреса: сегмента исмещений (рис. 2).
/>
Рис. 2. «Синтаксисописания адресных операндов».
Перемещаемыеоперанды — любые символьные имена,представляющие некоторые адреса памяти. Эти адреса могут обозначатьместоположение в памяти некоторой инструкции (если операнд — метка) или данных(если операнд — имя области памяти в сегменте данных). Перемещаемые операндыотличаются от адресных тем, что они не привязаны к конкретному адресуфизической памяти. Сегментная составляющая адреса перемещаемого операнданеизвестна и будет определена после загрузки программы в память для выполнения.
Считчикадреса — специфический вид операнда. Онобозначается знаком $. Специфика этого операнда в том, что когда трансляторассемблера встречает в исходной программе этот символ, то он подставляетвместо него текущее значение счетчика адреса. Значение счетчика адреса, иликак его иногда называют счетчика размещения, представляет собой смещениетекущей машинной команды относительно начала сегмента кода.
Базовыйи индексный операнды. Этот тип операндовиспользуется для реализации косвенной базовой, косвенной индексной адресацииили их комбинаций и расширений.
Операнды являютсяэлементарными компонентами, из которых формируется часть машинной команды,обозначающая объекты, над которыми выполняется операция. В более общем случаеоперанды могут входить как составные части в более сложные образования,называемые выражениями. Выражения представляют собой комбинации операндов иоператоров, рассматриваемые как единое целое. Результатом вычисления выраженияможет быть адрес некоторой ячейки памяти или некоторое константное (абсолютное)значение. В табл. 2.2 приведены поддерживаемые языком ассемблера операторы иперечислены их приоритеты.
Арифметическиеоператоры. К ним относятся унарные операторы«+» и «-», бинарные «+» и «-», операторы умножения «*», целочисленного деления«/», получения остатка от деления «mod». Эти операторы расположены на уровняхприоритета 6, 7, 8 в табл. 2.1.
Операторысдвига выполняют сдвиг выражения науказанное количество разрядов.
Операторысравнения (возвращают значение «истина» или«ложь») предназначены для формирования логических выражений (табл. 5.1). IЛогическое значение «истина» соответствует цифровой единице, а «ложь» — нулю.
Табл. 2.1.
Операторы сравненияОператор Значение eq ИСТИНА, если выражение_1 равно выражение_2 пе ИСТИНА, если выражение_1 не равно выражение_2 It ИСТИНА, если выражение_1 меньше выражение_2 le ИСТИНА, если выражение_1 меньше или равно выражение_2 gt ИСТИНА, если выражение_1 больше выражение_2 ge ИСТИНА, если выражение_1 больше или равно выражение_2 eq ИСТИНА, если выражение_1 равно выражение_2 пе ИСТИНА, если выражение_1 не равно выражение_2
Логическиеоператоры выполняют над выражениямипобитовые операции. Выражения должны быть абсолютными, то есть такими,численное значение которых может быть вычислено транслятором.
Индексныйоператор [ ]. Скобки тоже являютсяоператором, и транслятор их наличие воспринимает, как указание сложить значениевыражение_1 за этими скобками с выражение_2, заключенным в скобки.
Операторпереопределения типа ptr применяется дляпереопределения или уточнения имя типа метки или переменной, определяемыхвыражением. Тип может принимать одно из следующих значений: byte, word, dword,qword, tbyte, noar, far. Оператор ptr позволяет непосредственно в командепереопределить тип и выполнить команду.
Операторпереопределения сегмента : (двоеточие)заставляет вычислять физический адрес относительно конкретно задаваемойсегментной составляющей: «имя сегментного регистра», «имя сегмента» изсоответствующей директивы SEGMENT или «имя группы».
Операторименования типа структуры. (точка) также заставляет транслятор производитьопределенные вычисления
Операторполучения сегментной составляющей адресавыражения seg возвращает физический адрес сегмента для выражения, вкачестве которого могут выступать метка, переменная, имя сегмента, имя группыили некоторое символическое имя.
Операторполучения смещения выраженияoffset позволяет получить значения смещения выражения в байтах относительноначала того сегмента, в котором выражение определено.
3. ОПИСАНИЕАЛГОРИТМА
Алгоритм реализуетвычисление CRC8 делением заданного массива данных на образующий полином x8+x5+x4+1. Деление выполнено последовательным вычитанием по модулю 2полинома из исходной последовательности.
Для этогоорганизован цикл по словам исходной последовательности и цикл по разрядногосдвига внутри слова. Поскольку удобнее просматривать массив в порядкеувеличения адреса (от младшего к старшему), процедура реализует зеркальныйалгоритм.
Подробнее о томкак выполняется деление при вычислении CRC смотри в прилагаемыхисточниках.
Для процедурывычисления исходные данные передаются через регистры. Сегментный регистр ES должен содержатьсегмент в котором расположен массив, регистр DX – смещение начала массива внутри сегмента, BX – длина массива.Результат накапливается в аккумуляторе AL.
Перед началомвычислений инициируем AX значением FFFFh. В регистр CX заносим длину массива и умножаем её на 8. Таким образом этотрегистр хранит количество разрядов в массиве и используется как счётчик цикловкомандой loop. Дополнять исходную последовательность (проверяемый массив)нулями нет необходимости, т.к. количество разрядов кратно степени образующегомногочлена.
Смещение переносимв регистр DI.
В BX заносим первое словомассива.
Проверяем младшийразряд BX. Если он равен нулю – выполняем сдвиг слова на один разрядвправо, если нет – выполняем сложение с образующим многочленом по модулю 2, азатем выполняем сдвиг.
Сдвиг по разрядамвыполняется следующим образом. В DX хранится количество сдвигов оставшееся до конца слова(удобнее подсчитывать не количество выполненных сдвигов, а от количестваразрядов в слове до 0). Если в DX – 0, то нужно в DX записать 8, а в BX загрузить следующее слово массива, иначе – просто сдвигаем BX вправо на разряд и уменьшаем DX на 1.
Повторяемсуммирование.
После окончанияпроцедуры аккумулятор AX содержит вычисленное для массива значение CRC8.
Для сохранениярезультата его переносим в переменную result.
Для проверкицелостности массива нужно повторить вычисление контрольной суммы и сравнить созначением в result.
Блок-схемаалгоритма приведена в приложении 1.
4. ОПИСАНИЕПРОГРАММЫ
Алгоритмопределения CRC реализован в процедуре CalcCRC. Перед вызовом этойпроцедуры необходимо в регистры записать начальные данные — сегментный регистр ES должен содержатьсегмент в котором расположен массив, регистр DX – смещение начала массива внутри сегмента, BX – длина массива.
Программа выполняет следующие операции по выбору пользователя: вычисление CRC массива и записьрезультата в переменную, проверка целостности массива – повторное вычисление CRC и сравнениевычисленного значения с записанным, искажение массива – обратимое изменениеодного бита проверочного массива.
Для вычисления CRC, вызывается процедура CalcCRC, а результатвыполнения сохраняется в переменной result.
При проверкецелостности, вызывается процедура CalcCRC, а результат выполнения сравнивается с сохранённым в переменнойresult. В случае несовпадения, выводится сообщение об ошибке. Присовпадении значений (целостность данных не нарушена) сообщение не выводится ипользователь возвращается в главное меню.
Искажение массиваиспользуется для тестирования программы и демонстрации работы.
Для тестирования впрограмме предусмотрен проверочный массив данных длиной 32 байта. Приискажении, инвертируется младший бит первого слова массива.
ПРИЛОЖЕНИЕ 1
Блок-схемаалгоритма
/>
ПРИЛОЖЕНИЕ 2
MODEL SMALL
;*****************************************************************************
; Сегмент стека
;*****************************************************************************
_Stack SEGMENT WORD 'STACK'
DB 200h DUP (?)
_Stack ENDS
;*****************************************************************************
; Сегмент тестового массива
;*****************************************************************************
DataSeg SEGMENT WORD 'DATA'
TestTab DB 32 DUP ( \
00h, 01h, 02h, 03h, 04h, 05h, 06h,07h, \
08h, 09h, 0Ah, 0Bh, 0Ch, 0Dh, 0Eh,0Fh, \
00h, 01h, 02h, 03h, 04h, 05h, 06h,07h, \
08h, 09h, 0Ah, 0Bh, 0Ch, 0Dh, 0Eh, 0Fh \
)
DataSeg ENDS
;*****************************************************************************
; Сегмент переменных
;*****************************************************************************
_Data SEGMENT WORD 'DATA'
;*****************************************************************************
FSelMsg DB 13,10,'Выберите действие:',13,10, \
13,10,'1-Определить CRC',13,10, \
'2-Проверить массив',13,10, \
'3-Исказить массив',13,10, \
'4-Выход',13,10, \
'$'
ByeStr DB 13,10,'Для продолжения нажмите любую клавишу.$'
ErrorString DB 13,10,'Ошибка ввода',13,10,'$'
ErrorResult DB 13,10,'Данные искажены. CRC8 нарушена.',13,10,'$'
;*****************************************************************************
BegSeg DW (?) ; Сегмент проверочного массива
BegOffs DW (?) ; Начало проверочного массива
Result DW (?) ; Результат вычисления
FuncNum DB (?) ; Выбранная операция
_Data ENDS
;*****************************************************************************
; Сегмент программы
;*****************************************************************************
.CODE
;*****************************************************************************
call cls ; Очистка экрана
call SetDATSeg ; Загрузка адреса сегмента переменных
call SetArrSeg ; Установка указателя сегмента массива
; Главное меню
Mnu: call SelectFunction ; Выбор операции
call cls ; Очистка экрана
mov AL,FuncNum
;*******************************
Mnu1: cmp AL,1 ; Определение чётности
jne Mnu2
; Установка параметров
mov DX,OFFSET TestTab; Смещение начала массива
mov BX,30 ; Размер проверяемого блока данных
;call TestOdd
call CalcCRC
mov Result,AX ; Сохранение результата
;*******************************
Mnu2: cmp AL,2 ; Определить чётность и сравнить с пред.
jne Mnu3
mov DX,OFFSET TestTab; Смещение начала массива
mov BX,30 ; Размер блока данных
call CalcCRC
cmp Result,AX
je Mnu2End
; Результат не совпал. Данные искажены. Выдать сообщение об ошибке
mov DX,OFFSET ErrorResult
mov AH,9h
int 21h ; Вывод сообщения обошибке
mov DX,OFFSET ByeStr ; Вывод приглашения
mov AH,9h
int 21h
mov AH,0Ch
mov AL,01h
int 21h ; Ожидание нажатия любойклавиши
Mnu2End:
call cls
jmp Mnu
;*******************************
Mnu3: cmp AL,3 ; Искажение масива (первый байт)
jne Mnu4
mov DI,OFFSET TestTab
mov AX,ES:[DI]
xor AX,1 ; Инвертируем младшийбит
mov ES:[DI],AX
;*******************************
Mnu4: cmp AL,4 ; Выход из программы
jne Mnu
;*******************************
jmp Exit
; Завершение программы
;Exit:
; Приостанов перед выходом
mov DX,OFFSET ByeStr ;? Нажмите клавишу??
mov AH,9h
int 21h
mov AH,0Ch
mov AL,01h
int 21h
Exit:; Выход
mov AH,4Ch
int 21h
;*****************************************************************************
; Печать новой строки
NewStr:
mov AH,02h
mov DL,0Dh
int 21h
mov DL,0Ah
int 21h
ret
;*****************************************************************************
include cls.prc
;*****************************************************************************
; Главное меню
SelectFunction:
;1.1.Вывод строки меню
mov DX,OFFSET FSelMsg
mov AH,9h
int 21h
;1.2.Выбор функции
mov FuncNum,0
call input10 ; Считываемномер пункта меню
mov FuncNum,AL ; Сохраняем номер выбранной функции
ExitSF: ret
;*****************************************************************************
; Подпрограмма ввода числа
input10:
push BX ; Сохраняем регистры
push DX
push CX
mov DX,0 ; Обнуляем регистр хранения результата
InputChar:
clc
mov AH,0Ch
mov AL,1
int 21h ; Считываем символ с эхом
cmp AL,13d
je ExitI10 ; Если его код 13? конец ввода
cmp AL,'0'
jb ErrInput ; Если код меньше кода символа 0 ошибкаввода
cmp AL,'9'
jg ErrInput ; Если код больше кода символа 9 ошибкаввода
clc
sub AX,30h ; Получаем из кода символа число
mov CX,0
mov CL,AL
mov AX,DX
mov BX,10
mul BX ; Умножаем на 10 уженакопленный результат
add AX,CX ; Прибавляем считанное число
mov DX,AX ; Сохраняем результат
jmp InputChar
ErrInput:
Stc ; В случае ошибки ввода устанавливаем флаг
ExitI10:
mov AX,DX ; Переносим результат в регистр возврата
pop CX
pop DX
pop BX ; Восстанавливаем регистры
ret
;*****************************************************************************
; Установка указателя на сегмент переменных
SetDATSeg:
push AX
mov AX,_Data
mov DS,AX
pop AX
ret
;*****************************************************************************
; Установка указателя на проверочный массив
SetArrSeg proc
push AX
mov AX,DataSeg
mov ES,AX
pop AX
ret
SetArrSeg endp
;****************************************************************************
; Процедура вычисления CRC16
;ES — сегмент массива
;DX — адрес начала массива
;BX — длина блока данных
;AX — результат вычислений
;****************************************************************************
CalcCRC proc
push CX ;\
push BX ;- сохранение регистров
push DI ;/
push DX
mov DI,DX ; Загрузка индекса начала массива
mov DX,8
mov CX,BX ; Установка счётчика цикла
shl CX,1 ;\
shl CX,1 ;- CX=CX*8
shl CX,1 ;/
mov AX,65535 ; Очистка регистра результата
mov BX,ES:[DI]
CRNext: loop CRNextTest ; Цикл по словам массива
pop DX
pop DI ;\
pop BX ;-восстановление регистров
pop CX ;/
ret
CRNextTest:
push AX
mov AX,BX
and AX,1b
jz Shift
pop AX
xor AL,31h
push AX
Shift: mov AX,DX
jz NewWord
shr BX,1
dec DX
jmp EndShift
NewWord:
mov DX,8
inc DI
mov BX,ES:[DI]
EndShift:
pop AX
jmp CRNext
CalcCRC endp
;*****************************************************************************
END
;*****************************************************************************
ЗАКЛЮЧЕНИЕ
Ассемблер являетсясимволическим аналогом машинного языка. По этой причине программа, написаннаяна ассемблере, должна отражать все особенности архитектуры микропроцессора:организацию памяти, способы адресации операндов, правила использованиярегистров и т. д. Из-за необходимости учета подобных особенностей ассемблеруникален для каждого типа микропроцессоров.
В данной курсовойработе рассмотрены основные этапы программирования на ассемблере, реализованалгоритм выполнения поставленной задачи, а также выполнена трансляция кода висполняемый файл.
СПИСОК ЛИТЕРАТУРЫ:
1. Финогенов К.Г. Основы языка Ассемблера. – М.: Радио исвязь,2000.
2. Юров В. Assembler. Специальный справочник. – СПб.: Питер, 2001.
3. Юров В. Assembler. Практикум. – СПб.: Питер, 2001.
4. Юров В., Хорошенко В. Assembler – Учебный курс.- СПб.:Питер, 2000.