Вступ
Мікропроцесори корпорації 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.Етапипроектування:
•формування «ассемблерной» моделі задачі;
•вибір методу реалізації завдання;
2. Етапи проектування:
•формування «ассемблерной» моделі задачі;
•вибір методу реалізації завдання;
•розробка алгоритму реалізації задачі;
•розробка структури програми відповідно до обраною моделлю пам'яті.
3.Етап кодування:
• уточнення структури вхідних та вихідних даних і визначення формату їхподання;
• програмування задачі;
• коментування тексту програми і складання попереднього опису програми.
4. Етап налагодження і тестування:
• складання тестів для перевірки правильності роботи програми;
• виявлення, локалізація й усунення помилок у програмі, виявлених утестах;
• коректування коду програми та її опису.
5. Етап експлуатації та супроводу:
• настройка програми на конкретні умови використання;
• навчання користувачів роботі з програмою;
• організація збору відомостей про збої в роботі програми, помилки увихідних даних, побажання щодо поліпшення інтерфейсу і зручності рабі ти зпрограмою;
• модифікація програми з метою усунення виявлених помилок і, принеобхідності, зміни її функціональних можливостей.
До порядку застосування та повноті виконання перерахованих етапівпотрібно підходити розумно. Багато що визначається особливостями конкретногозавдання, її призначенням, об'ємом коду і оброблюваних даних, іншимихарактеристиками завдання. Деякі з цих етапів можуть або виконуватися одночасноз іншими етапами, або зовсім відсутніми.
Традиційно в існуючих реалізацій асемблера немає інтегрованогосередовища, подібної інтегрованим середах Turbo Pascal, Turbo С або Visual C.Тому для виконання всіх функцій щодо введення коду програми, її трансляції,редагування та налагодження необхідно використовувати окремі службові програми.Велика частина їх входить до складу спеціалізованих пакетів асемблера.
На малюнку 1.1 наведена загальна схема процесу розробки програми наасемблері. На схемі виділено чотири кроки процесу. На першому кроці, коливводиться код програми, можна використовувати будь-який текстовий редактор.Основною вимогою до нього є те, щоб він не вставляв сторонніх символів. Файлповинен мати розширення asm.
/>
Рис. 1.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. — Синтаксис опису адресних операндів
Переміщувані операнди — будь-які символьні імена, що представляють деякіадреси пам'яті. Ці адреси можуть позначати місце розташування в пам'яті деякоїінструкції (якщо операнд — мітка) або даних (якщо операнд — ім'я областіпам'яті в сегменті даних). Переміщувані операнди відрізняються від адреснихтим, що вони не прив'язані до конкретного адресою фізичної пам'яті. Сегментнаскладова адреси переміщуваного операнда невідома і буде визначена післязавантаження програми в пам'ять для виконання.
Зчитувач адреси — специфічний вид операнда. Він позначається знаком $.Специфіка цього операнда в тому, що коли транслятор асемблера зустрічає увихідній програмі цей символ, то він підставляє замість нього поточне значеннялічильника адреси. Значення лічильника адреси, або як його іноді називаютьлічильник розміщення.
Базовий і індексний операнди. Цей тип операндів використовується дляреалізації непрямої базової, непрямої індексної адресації або їх комбінацій ірозширень.
Операнди є елементарними компонентами, з яких формується частина машинноїкоманди, що позначає об'єкти, над якими виконується операція. У більшзагальному випадку операнди можуть входити як складові частини в більш складніутворення, звані виразами. Вирази являють собою комбінації операндів таоператорів, що розглядаються як єдине ціле. Результатом обчислення виразу можебути адреса деякої комірки пам'яті або деяке константне (абсолютне) значення. Утабл. 2.2 наведено підтримувані мовою асемблера оператори і перераховані їхпріоритети.
Оператор перевизначення типу ptr застосовується для перевизначення абоуточнення ім'я типу мітки або змінної, що визначаються виразом. Тип можеприймати одне з наступних значень: byte, word, dword, qword, tbyte, noar, far.Оператор ptr дозволяє безпосередньо в команді перевизначити тип і виконати команду.
Оператор перевизначення сегмента: (двокрапка) змушує обчислювати фізичнуадресу щодо конкретно задається сегментної складової: «ім'я сегментногорегістра», «ім'я сегмента» з відповідної директиви SEGMENT або «ім'я групи».
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.
Блок-схема алгоритму наведена в додатку 2.
4. Відладка та випробування розробленого програмногозабезпечення
Алгоритм визначення CRC реалізований в процедурі CalcCRC. Перед викликомцієї процедури необхідно в регістри записати початкові дані — сегментнийрегістр ES повинен містити сегмент в якому розташований масив, регістр DX — зміщення початку масиву всередині сегмента, BX — довжина масиву.
Програма виконує наступні операції на вибір користувача: обчислення CRCмасиву і запис результату в змінну, перевірка цілісності масиву — повторнеобчислення CRC і порівняння обчисленого значення з записаним, спотвореннямасиву — оборотне зміна одного біта перевірочного масиву.
Для обчислення CRC, викликається процедура CalcCRC, а результат виконаннязберігається у змінній result.
При перевірці цілісності, викликається процедура CalcCRC, а результатвиконання порівнюється зі збереженим у змінній result. У випадку розбіжності,виводиться повідомлення про помилку. При збігу значень (цілісність даних непорушена) повідомлення не виводиться і користувач повертається в головне меню.
Спотворення масиву використовується для тестування програми ідемонстрації роботи.
Для тестування в програмі передбачений перевірочний масив даних довжиною32 байта. При спотворенні, інвертується молодший біт першого слова масиву.
Висновок
Асемблер є символічним аналогом машинної мови. З цієї причини програма,написана на асемблері, повинна відображати всі особливості архітектуримікропроцесора: організацію пам'яті, способи адресації операндів, правилавикористання регістрів і т. д. З-за необхідності врахування подібнихособливостей асемблер унікальний для кожного типу мікропроцесорів.
У цій роботі розглянуті основні етапи програмування на асемблері,реалізований алгоритм виконання поставленого завдання, а також виконанатрансляція коду у виконуваний файл.
Література
1. Абель П. Основипрограммирования/ Пер. с англ. Ю. В. Сальниковая.- М.: Висш. Шк. 1992г. — 447с.:ил.
2. А. Жуков, А.Авдохин «Assembler».-Спб: БХВ — Петербург, 2002..
3. Архитектураввода-вывода персональных ЭВМ IBM РС Под редакцией Ю. С. Лукача (C)Инженерно-техническое бюро, 1990
4. В. Юров«Assembler» Практикум.-Спб.: Питер, 2001.
5. В. Юров«Assembler» Учебник.-Спб.: Питер, 2001.
6. Зубков С. В.Ассемблер для Dos, Windows и Unix — «Питер», в 2004 г.
7. Ирвин, Кип.Язык Ассемблера для процессоров Intel, 3-е издание: Пер. с англ. — М.: Издательский дом «Вильямс», 2002.-616с.: ил. — Парал. Тит. Англ.
8. ИспользованиеTurbo Assembler при разработке программ / Сост. А. А.Чекатков.-Киев: Диалектика,1995.-228с
Додаток А
Текст програми
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; Додаємо зовсiм небагато
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
;*************************************************