Команди для роботи зі склом мови асемблер. Структура команди на мові асемблера програмування на рівні

1. Архітектура ПК ..................................................................... 5

    1.1. Регістри.

    1.1.1 Регістри загального призначення.

1.1.2. сегментні регістри

1.1.3 Регістр прапорів

1.2. Організація пам'яті.

1.3. Подання даних.

1.3.1 Типи даних

1.3.2 Представлення символів і рядків

2. Оператори програми на асемблері ..........................................

    1. Команди мови асемблера

2.2. Режими адресації і формати машинних команд

3. псевдооператор ...................................................................

3.1 Директиви визначення даних

3.2 Структура програми на асемблері

3.2.1 Програмні сегменти. Директива assume

3.2.3 Спрощена директива сегментації

4. Ассемблирование і компоновка програми ...............................

5. Команди пересилання даних ....................................................

    5.1 Команди загального призначення

    5.2 Команди роботи зі стеком

5.3 Команди вводу-виводу

5.4 Команди пересилання адреси

5.5 Команди пересилання прапорів

6. Арифметичні команди .......................................................

    6.1 Арифметичні операції над цілими двійковими числами

6.1.1 Додавання і віднімання

6.1.2 Команди збільшення і зменшення приймача на одиницю

6.2 Множення і ділення

6.3 Зміна знака

7. Логічні операції ..........................................................

8. Зрушення і циклічні зрушення ................................................

9. Строкові операції .............................................................

10. Логіка і організація програм .............................................

10.1 Безумовні переходи

10.2 Умовні переходи

10.4 Процедури в мові асемблера

10.5 Переривання INT

10.6 Системне програмне забезпечення

10.6.1.1 Читання клавіатури.

10.6.1.2 Висновок символів на екран

10.6.1.3 Завершення програм.

10.6.2.1 Вибір режимів дисплея

11. Дискова пам'ять ..................................................................... ..

11.2 Таблиця розподілу файлів

11.3 Операції введення-виведення на диск

11.3.1 Запис файлу на диск

11.3.1.1 Дані в форматі ASCIIZ

11.3.1.2 Файловий номер

11.3.1.3 Створення дискового файлу

11.3.2 Читання дискового файлу

Вступ

Мова асемблера - це символічне уявлення машинного мови. Всі процеси в персональному комп'ютері (ПК) на найнижчому, апаратному рівні приводяться в дію тільки командами (інструкціями) машинної мови. По-справжньому вирішити проблеми, пов'язані з апаратурою (або навіть, більш того, залежні від апаратури як, наприклад, підвищення швидкодії програми), неможливо без знання асемблера.

Асемблер є зручну форму команд безпосередньо для компонент ПК і вимагає знання властивостей і можливостей інтегральної мікросхеми, що містить ці компоненти, а саме мікропроцесора ПК. Таким чином, мова асемблера безпосередньо пов'язаний з внутрішньою організацією ПК. І не випадково практично всі компілятори мов високого рівня підтримують вихід на асемблерний рівень програмування.

Елементом підготовки програміста-професіонала обов'язково є вивчення асемблера. Це пов'язано з тим, що програмування на асемблері вимагає знання архітектури ПК, що дозволяє створювати більш ефективні програми на інших мовах і об'єднувати їх з програмами на асемблері.

У посібнику розглядаються питання програмування мовою асемблера для комп'ютерів на базі мікропрцессоров фірми Intel.

Даний навчальний посібник адресується всім, хто цікавиться архітектурою процесора і основам програмування на мові Асемблер, в першу чергу, розробникам програмного продукту.

    Архітектура ПК.

Архітектура ЕОМ - це абстрактне уявлення ЕОМ, яке відображає її структурну, схемотехнічних і логічну організацію.

Всі сучасні ЕОМ мають деякими загальними і індивідуальними властивостями архітектури. Індивідуальні властивості притаманні тільки конкретної моделі комп'ютера.

Поняття архітектури ЕОМ включає в себе:

    структурну схему ЕОМ;

    засоби і способи доступу до елементів структурної схеми ЕОМ;

    набір і доступність регістрів;

    організацію і способи адресації;

    спосіб представлення і формат даних ЕОМ;

    набір машинних команд ЕОМ;

    формати машинних команд;

    обробка переривань.

Основні елементи апаратних засобів комп'ютера: системний блок, клавіатура, пристрій відображення, дисководи, які друкують пристрої (принтер) і різні засоби зв'язку. Системний блок складається з системної плати, блоку живлення і осередків розширення для додаткових плат. На системній платі розміщені мікропроцесор, постійна пам'ять (ROM), оперативна пам'ять (RAM) і співпроцесор.

      Регістри.

Усередині мікропроцесора інформація міститься в групі з 32 регістрів (16 призначених для користувача, 16 системних), в тій чи іншій мірі доступних для використання програмістом. Так як посібник присвячено програмування для мікропроцесор 8088-i486, то найлогічніше розпочати цю тему з обговорення внутрішніх регістрів мікропроцесора, доступних для користувача.

Призначені для користувача регістри використовуються програмістом для написання програм. До цих регістрів належать:

    вісім 32-бітових регістрів (регістри загального призначення) EAX / AX / AH / AL, EBX / BX / BH / BL, ECX / CX / CH / CL, EDX / DX / DLH / DL, EBP / BP, ESI / SI, EDI / DI, ESP / SP;

    шість 16 -, бітових регістрів сегментів: CS, DS, SS, ES, FS, GS;

    регістри стану і управління: регістр прапорів EFLAGS / FLAGS, і регістр покажчика команди EIP / IP.

Через похилу риску наведені частини одного 32-розрядного регістра. Приставка E (Extended) позначає використання 32-разраядного регістра. Для роботи з байтами використовуються регістри з приставками L (low) і H (high), наприклад, AL, CH - позначають молодший і старший байти 16-розрядних частин регістрів.

        Регістри загального призначення.

EAX / AX / AH / AL (Accumulator register) - акумулятор. Використовуються при множенні і діленні, в операціях введення-виведення і в деяких операціях над рядками.

EBX / BX / BH / BL - базовий регістр (Base register), часто використовується при адресації даних в пам'яті.

ECX / CX / CH / CL - лічильник (Count register), використовується як лічильник числа повторень циклу.

EDX / DX / DH / DL - регістр даних (Data register), використовується для зберігання проміжних даних. У деяких командах використання його обов'язково.

Всі регістри цієї групи дозволяють звертатися до своїх «молодшим» частинам. Використання для самостійної адресації можна лише молодші 16- і 8-бітові частини цих регістрів. Старші 16 біт цих регістрів як самостійні об'єкти недоступні.

Для підтримки команд обробки рядків, що дозволяють виробляти послідовну обробку ланцюжків елементів мають довжину 32, 16 або 8 біт використовуються:

ESI / SI (source index register) - індекс джерела. Містить адреса поточного елемента джерела.

EDI / DI (distination index register) - індекс приймача (Одержувача). Містить поточну адресу в рядку приймачі.

В архітектурі мікропрцессора на програмно-апаратному рівні підтримується структура даних - стек. Для роботи зі стеком є \u200b\u200bспеціальні команди і спеціальні регістри. Слід зазначити, що стек заповнюється в сторону менших адрес.

ESP / SP (stack poINTer register) - регістр покажчика стека. Містить покажчик вершини стека в поточному сегменті стека.

EBP / BP (base poINTer register) - регістр покажчика бази стека. Призначений для організації довільного доступу до даних усередині стека.

1.1.2. сегментні регістри

У програмній моделі мікропроцесора є шість сегментних регістрів: CS, SS, DS, ES, GS, FS. Їх існування обумовлене специфікою організації та використання оперативної пам'яті мікропроцесорами Intel. Мікропроцесор апаратно підтримує структурну організацію програми складається з сегментів. Для вказівки сегментів доступних в даний момент призначені сегментні регістри. Мікропроцесор підтримує наступні типи сегментів:

    Сегмент коду.Містить команди програми Для доступу до цього сегменту служить регістр CS (code segment register) - сегментний регістр коду. Він містить адресу сегмента з машинними командами, до якого має доступ мікропроцесор.

    Сегмент даних. Містить оброблювані програмою дані. Для доступу до цього сегменту служить регістр DS (data segment register) - сегментний регістр даних, Який зберігає адресу сегмента даних поточної програми.

    Сегмент стека. Цей сегмент являє собою область пам'яті, звану стеком. Мікропроцесор організує стек за принципом - перший «прийшов», перший «пішов». Для доступу до стека служить регістр SS (stack segment register) - сегментний регістр стека, Що містить адресу сегмента стека.

    Додатковий сегмент даних. Оброблювані дані можуть знаходитися ще в трьох додаткових сегментах даних. За умовчанням передбачається, що дані знаходяться в сегменті даних. При використанні додаткових сегментів даних їх адреси потрібно вказати явно за допомогою спеціальних префіксів перевизначення сегментів в команді. Адреси додаткових сегментів даних повинні міститися в регістрах ES, GS, FS (extenSIon data segment registers).

        Регістри управління і стану

Мікропроцесор містить кілька регістрів, які містять інформацію про стан, як самого мікропроцесора, так і програми, команди якої в даний момент завантажені в конвеєр. це:

Регістр покажчика команд EIP / IP;

    регістр прапорів EFLAGS / FLAGS.

Використовуючи ці регістри, можна отримувати інформацію про результати виконання команд і впливати на стан самого мікропроцесора.

EIP / IP (instruction poINTer register) - покажчик команд. Регістр EIP / IP має розрядність 32 або 16 біт і містить зсув наступної виконуваної команди щодо вмісту сегментного регістра CS в поточному сегменті команд. Цей регістр безпосередньо недоступний, але зміна його виробляється командами переходу.

EFLAGS / FLAGS (Flag register) - регістр прапорів. Розрядність 32/16 біт. Окремі біти даного регістра мають певне функціональне призначення і називаються прапорами. Прапор - це біт, що приймає значення 1 ( "прапор встановлений"), якщо виконано деякий умова, і значення 0 ( "прапор скинутий") в іншому випадку. Молодша частина цього регістра повністю аналогічна регістру FLAGS для i8086.

1.1.3 Регістр прапорів

Регістр прапорів є 32-розрядним, має ім'я EFLAGS (рис.1). Окремі біти регістра мають певне функціональне призначення і називаються прапорами. Кожному з них присвоєно певне ім'я (ZF, CF і т.д). Молодші 16 біт EFLAGS представляють 16-розрядний регістр прапорів FLAGS, будуть застосовані до запланованого програм, написаних для мікропроцесора i086 і i286.

Рис.1 Регістр прапорів

Деякі прапори прийнято називати прапорами умов; вони автоматично змінюються при виконанні команд і фіксують ті чи інші властивості їх результату (наприклад, дорівнює він нулю). Інші прапори називаються прапорами станів; вони змінюються з програми і впливають на подальшу поведінку процесора (наприклад, блокують переривання).

Прапори умов:

CF (carry flag) - прапор переносу. Приймає значення 1, якщо при додаванні цілих чисел з'явилася одиниця переносу, не «влазити" в розрядну сітку, або якщо при відніманні чисел без знака перше з них було менше другого. У командах зрушення в CF заноситься біт, що вийшов за розрядну сітку. CF фіксує також особливості команди множення.

OF (overflow flag) - прапор переповнення. Встановлюється в 1, якщо при додаванні або вирахуванні цілих чисел зі знаком вийшов результат, по модулю перевершує допустиму величину (сталося переповнення мантиси і вона "залізла" в знаковий розряд).

ZF (zero flag) - прапор нуля. Встановлюється в 1, якщо результат команди виявився рівним 0.

SF (SIgn flag) - прапор знака. Встановлюється в 1, якщо в операції над знаковими числами вийшов негативний результат.

PF (parity flag) - прапор парності. Дорівнює 1, якщо результат чергової команди містить парна кількість двійкових одиниць. Враховується звичайно тільки при операціях вводу-виводу.

AF (auxiliary carry flag) - прапор додаткового перенесення. Фіксує особливості виконання операцій над двійковій-десятковими числами.

Прапори станів:

DF (direction flag) - прапор напрямки. Встановлює напрямок перегляду рядків у строкових командах: при DF \u003d 0 рядки проглядаються "вперед" (від початку до кінця), при DF \u003d 1 - в зворотному напрямку.

IOPL (input / output privilege level) - рівень привілеїв введення-виведення.Використовується в захищеному режимі роботи мікропроцесора, для контролю доступу до команд вводу-виводу, в залежності від привілейованості задачі.

NT (nested task) - прапор вкладеності завдання.Використовується в захищеному режимі роботи мікропроцесора для фіксації того факту, що одна задача вкладена в іншу.

Системні прапор:

IF (INTerrupt flag) - прапор переривань. При IF \u003d 0 процесор перестає реагувати на вступники щодо нього переривання, при IF \u003d 1 блокування переривань знімається.

TF (trap flag) - прапор трасування. При TF \u003d 1 після виконання кожної команди процесор робить переривання (з номером 1), чим можна скористатися при налагодженні програми для її трасування.

RF (resume flag) - прапор відновлення. Використовується при обробці переривань від регістрів налагодження.

VM (virtuAL 8086 mode) - прапор віртуального 8086. 1-процесор працює в режимі віртуального 8086. 0- процесор працює в реальному або захищеному режимі.

AC (ALignment check) - прапор контролю вирівнювання. Призначений для дозволу контролю вирівнювання при зверненні до пам'яті.

      Організація пам'яті.

Фізична пам'ять, до якої мікропроцесор має доступ, називається оперативною пам'яттю (або оперативним запам'ятовуючим пристроєм - ОЗУ). ОЗУ є ланцюжком байтів, що мають свою унікальну адресу (його номер), званий фізичним. Діапазон значень фізичних адрес від 0 до 4 Гбайт. Механізм управління пам'яттю повністю апаратний.

Мікропроцесор апаратно підтримує кілька моделей використання оперативної пам'яті:

    сегментированную модель. У цій моделі пам'ять для програм ділиться на безперервні області пам'яті (сегменти), а сама програма може звертатися тільки до даних, які знаходяться в цих сегментах;

    сторінкову модель. В цьому випадку оперативна пам'ять розглядається як сукупність блоків фіксованого розміру 4 Кбайта. Основне застосування цієї моделі пов'язане з організацією віртуальної пам'яті, що дозволяє використовувати для роботи програм простір пам'яті більше, ніж обсяг фізичної пам'яті. Для мікропроцесора Pentium розмір можливої \u200b\u200bвіртуальної пам'яті може досягати 4 Тбайта.

Використання і реалізація цих моделей залежить від режиму роботи мікропроцесора:

    Режим реальних адрес (реальний режим). Режим аналогічний роботі i8086 процесора. Необхідний для функціонування програм, розроблених для ранніх моделей процесорів.

    Захищений режим. У захищеному режимі з'являється можливість багатозадачного обробки інформації, захисту пам'яті за допомогою четирехуровнего механізму привілеїв і її сторінкової організації.

    Режим віртуального 8086. У цьому режимі з'являється можливість роботи декількох програм для i8086. При цьому можлива робота програм реального режиму.

Сегментація - механізм адресації, що забезпечує існування декількох незалежних адресних просторів. Сегмент являє собою незалежний, підтримуваний на апаратному рівні блок пам'яті.

Кожна програма в загальному випадку може складатися з будь-якої кількості сегментів, але безпосередній доступ вона має до трьох основних: коду, даних і стека - і від одного до трьох додаткових сегментів даних. Операційна система розміщує сегменти програми в оперативній пам'яті по певним фізичним адресами, після чого поміщає значення цих адрес у відповідні регістри. Всередині сегмента програма звертається до адресами щодо початку сегмента лінійно, тобто починаючи з адреси 0 і закінчуючи адресою, рівним розміру сегмента. Відносний адресу або зміщення,який мікропроцесор використовує для доступу до даних усередині сегмента, називається ефективним.

Формування фізичної адреси в реальному режимі

У реальному режимі діапазон зміни фізичної адреси від 0 до 1 Мбайт. Максимальний розмір сегмента 64 Кбайт. При зверненні до конкретного фізичній адресою оперативної пам'яті визначається адреса початку сегмента і зміщення всередині сегменту. Адреса початку сегмента береться з відповідного сегментного регістра. При цьому в сегментному регістрі містяться тільки старші 16 біт фізичної адреси початку сегменту. Відсутні молодші чотири біта 20-бітного адреси виходять зрушенням значення сегментного регістра вліво на 4 розряди. Операція зсуву виконується апаратно. Отримане 20-бітове значення і є справжнім фізичною адресою, відповідним початку сегмента. Тобто фізична адреса задається як пара "сегмент: зсув", де "сегмент" (segment) - це первие16 бітів початкового адресасегмента пам'яті, якому прінадлежітячейка, а "зсув" - 16-бітову адресу цього осередку, відрахований від початку даного сегмента пам'яті (величина 16 * сегмент + зсув дає абсолютний адреса осередку). Якщо, наприклад, в регістрі CS зберігається величина 1234h, тоді адресна пара 1234h: 507h визначає абсолютний адреса, рівний 16 * 1234h + 507h \u003d 12340h + 507h \u003d 12847h. Така пара записується у вигляді подвійного слова, причому (як і для чисел) в "перевернутому" вигляді: в першому слові розміщується зміщення, а по-друге - сегмент, причому кожне з цих словв свою чергу представлено в "перевернутому" вигляді. Наприклад, пара 1234h: 5678h буде записана так: | 78 | 56 | 34 | 12 |.

Даний механізм утворення фізичної адреси дозволяє зробити програмне забезпечення, що переміщується, тобто не залежних від конкретних адрес завантаження його в оперативній пам'яті.

Для того щоб машина могла виконати команди людини на апаратному рівні, необхідно задати певну послідовність дій на мові «нуликів і одиниць». Помічником у цій справі стане Асемблер. Це утиліта, яка працює з перекладом команд на машинну мову. Проте написання програми - досить трудомісткий і складний процес. Дана мова не призначений для створення легких і простих дій. На даний момент будь-який використовується мова програмування (Асемблер працює прекрасно) дозволяє написати спеціальні ефективні завдання, які сильно впливають на роботу апаратної частини. Основним призначенням є створення мікрокоманд і невеликих кодів. Дана мова дає більше можливостей, ніж, наприклад, Паскаль або С.

Короткий опис мов Асемблера

Всі мови програмування поділяються за рівнями: низький і високий. Будь-який з синтаксичної системи «сімейки» Ассемблера відрізняється тим, що об'єднує відразу деякі переваги найбільш поширених і сучасних мов. З іншими їх ріднить і те, що в повній мірі можна використовувати систему комп'ютера.

Відмінною особливістю компілятора є простота у використанні. Цим він відрізняється від тих, які працюють лише з високими рівнями. Якщо взяти до уваги будь-який такий мову програмування, Асемблер функціонує вдвічі швидше і краще. Для того щоб написати в ньому легку програму, не знадобиться багато часу.

Коротко про структуру мови

Якщо говорити в загальному про роботу і структурі функціонування мови, можна точно сказати, що його команди повністю відповідають командам процесора. Тобто Асемблер використовує Мнемокод, найбільш зручні людині для запису.

На відміну від інших мов програмування, Асемблер використовує замість адрес для запису осередків пам'яті певні мітки. Вони з процесом виконання коду переводяться в так звані директиви. Це відносні адреси, які не впливають на роботу процесора (не перекладаються в машинну мову), а необхідні для розпізнавання самим середовищем програмування.

Для кожної лінійки процесора існує своя При такому розкладі правильним буде будь-який процес, в тому числі і перекладений

Мова Асемблера має кілька синтаксисів, які будуть розглянуті в статті.

плюси мови

Найбільш важливим і зручним пристосуванням мови Асемблера стане те, що на ньому можна написати будь-яку програму для процесора, яка буде вельми компактною. Якщо код виявляється величезним, то деякі процеси перенаправляє в оперативну пам'ять. При цьому вони все виконують досить швидко і без збоїв, якщо звичайно, ними керує кваліфікований програміст.

Драйвера, операційні системи, BIOS, компілятори, інтерпретатори і т. Д. - це все програма на мові Асемблера.

При використанні дизассемблера, який здійснює переклад з машинного в можна запросто зрозуміти, як працює та чи інша системна задача, навіть якщо до неї немає пояснень. Однак таке можливо лише в тому випадку, якщо програми легкі. На жаль, в нетривіальних кодах розібратися досить складно.

мінуси мови

На жаль, початківцям програмістам (і часто професіоналам) важко розібрати мову. Асемблер вимагає докладного опису необхідної команди. Через те, що потрібно використовувати машинні команди, зростає ймовірність помилкових дій і складність виконання.

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

Якщо платформа, для якої створюється програма, оновлюється, то всі команди необхідно переписувати вручну - цього вимагає сама мова. Асемблер не підтримує функцію автоматичного регулювання працездатності процесів і заміну будь-яких елементів.

команди мови

Як вже було сказано вище, для кожного процесора є свій набір команд. Найпростішими елементами, які розпізнаються будь-якими типами, є наступні коди:


Використання директив

Програмування мікроконтролерів на мові (Асемблер це дозволяє і прекрасно справляється з функціонуванням) найнижчого рівня в більшості випадків закінчується вдало. Найкраще використовувати процесори з обмеженим ресурсом. Для 32-розрядної техніки дана мова підходить відмінно. Часто в кодах можна помітити директиви. Що ж це? І для чого використовується?

Для початку необхідно зробити акцент на тому, що директиви не переводяться в машинну мову. Вони регулюють виконання роботи компілятором. На відміну від команд, ці параметри, маючи різні функції, відрізняються не завдяки різним процесорам, а за рахунок іншого транслятора. Серед основних директив можна виділити наступні:


походження назви

Завдяки чому отримав назву мову - "Асемблер"? Йдеться про транслятор і компілятор, які і виробляють зашифрування даних. З англійської Assembler означає не що інше, як збирач. Програма не була зібрана вручну, була використана автоматична структура. Більш того, на даний момент вже у користувачів і фахівців стерлася різниця між термінами. Часто Ассемблером називають мови програмування, хоча це всього лише утиліта.

Через загальноприйнятого збірного назви у деяких виникає помилкове рішення, що існує єдина мова низького рівня (або ж стандартні норми для нього). Щоб програміст зрозумів, про яку структурі йдеться, необхідно уточнювати, для якої платформи використовується та чи інша мова Асемблера.

макрозасоби

Мови Асемблера, які створені відносно недавно, мають макросредства. Вони полегшують як написання, так і виконання програми. Завдяки їх наявності, транслятор виконує написаний код в рази швидше. При створенні умовного вибору можна написати величезний блок команд, а простіше скористатися макросредств. Вони дозволять швидко перемикатися між діями, в разі виконання умови або невиконання.

При використанні директив макромови програміст отримує макроси Ассемблера. Іноді він може широко використовуватися, а іноді його функціональні особливості знижуються до однієї команди. Їх наявність в коді полегшує роботу з ним, робить його більш зрозумілим і наочним. Однак слід все одно бути уважним - в деяких випадках макроси, навпаки, погіршують ситуацію.

Тема 1.4 ассемблерного мнемоніка. Структура і формати команд. Види адресації. Система команд мікропроцесора

план:

1 Мова асемблера. Основні поняття

2 Символи мови асемблера

3 Типи операторів асемблера

4 Директиви асемблера

5 Система команд процесора

1 Язик асемблера. Основні поняття

Мова асемблера - це символічне уявлення машинного мови. Всі процеси в машині на найнижчому, апаратному рівні приводяться в дію тільки командами (інструкціями) машинної мови. Звідси зрозуміло, що, незважаючи на загальну назву, мова асемблера для кожного типу комп'ютера свій.

Програма на асемблері являє собою сукупність блоків пам'яті, званих сегментами пам'яті.Програма може складатися з одного або декількох таких блоків-сегментів. Кожен сегмент містить сукупність речень мови, кожне з яких займає окремий рядок коду програми.

Речення асемблера бувають чотирьох типів:

1) команди або інструкції, що представляють собою символічні аналоги машинних команд. У процесі трансляції інструкції асемблера перетворяться у відповідні команди системи команд мікропроцесора;

2) макроси -оформляються певним чином пропозиції тексту програми, що заміщаються під час трансляції іншими пропозиціями;

3) директиви,є зазначенням транслятору асемблера на виконання деяких дій. У директив немає аналогів в машинному поданні;

4) рядки коментарів , Що містять будь-які символи, в тому числі і літери російського алфавіту. Коментарі ігноруються транслятором.

­ Структура програми на асемблері. Синтаксис асемблера.

Пропозиції, складові програму, можуть являти собою синтаксичну конструкцію, що відповідає команді, макрокоманді, директиві або коментарю. Для того щоб транслятор асемблера міг розпізнати їх, вони повинні формуватися за певними синтаксичними правилами. Для цього найкраще використовувати формальний опис синтаксису мови на зразок правил граматики. Найбільш поширені способи подібного опису мови програмування - синтаксичні діаграми і розширені форми Бекуса-Наура. Для практичного використання більш зручні синтаксичні діаграми.Наприклад, синтаксис пропозицій асемблера можна описати за допомогою синтаксичних діаграм, показаних на наступних малюнках 10, 11, 12.

Малюнок 10 - Формат пропозиції ассемблера


­ Малюнок 11 - Формат директив

­ Малюнок 12 - Формат команд і макрокоманд

На цих малюнках:

­ ім'я мітки - ідентифікатор, значенням якого є адреса першого байта того пропозиції вихідного тексту програми, яке він позначає;

­ ім'я - ідентифікатор, що відрізняє дану директиву від інших однойменних директив. В результаті обробки асемблером певної директиви цього імені можуть бути присвоєні певні характеристики;

­ код операції (КОП) і директива - це мнемонічні позначення відповідної машинної команди, макрокоманди або директиви транслятора;

­ операнди - частини команди, макрокоманди або директиви асемблера, що позначають об'єкти, над якими виробляються дії. Операнди асемблера описуються виразами з числовими і текстовими константами, мітками і ідентифікаторами змінних з використанням знаків операцій і деяких зарезервованих слів.

Синтаксичні діаграми допомагають знайти і потім пройти шлях від входу діаграми (ліворуч) до її виходу (праворуч). Якщо такий шлях існує, то пропозиція або конструкція синтаксично правильні. Якщо такого шляху немає, значить цю конструкцію компілятор не прийме.

­ 2 Символи мови асемблера

Допустимими символами при написанні тексту програм є:

1) всі латинські літери: A-Z, a-z. При цьому великі і малі літери вважаються еквівалентними;

2) цифри від 0 до 9 ;

3) знаки ? , @ , $ , _ , & ;

4) роздільники , . () < > { } + / * % ! " " ? = # ^ .

Речення асемблера формуються з лексем, Що представляють собою синтаксично нероздільні послідовності припустимих символів мови, що мають сенс для транслятора.

лексемами є:

1) ідентифікатори - послідовності допустимих символів, що використовуються для позначення таких об'єктів програми, як коди операцій, імена змінних і назви міток. Правило запису ідентифікаторів полягає в наступному: ідентифікатор може складатися з одного або декількох символів;

2) ланцюжка символів - послідовності символів, укладені в одинарні або подвійні лапки;

3) цілі чіслав однієї з наступних систем числення : двійковій, десятковій, шістнадцятковій. Ототожнення чисел при записі їх в програмах на асемблері виробляється за певними правилами:

4) десяткові числа не вимагають для свого ототожнення вказівки будь-яких додаткових символів, наприклад 25 або 139. Для ототожнення у вихідному тексті програми двійкових чисел необхідно після запису нулів і одиниць, що входять до їх складу, поставити латинське " b", Наприклад 10010101 b.

5) шістнадцятиричні числа мають більше умовностей при своєму записі:

По-перше, вони складаються з цифр 0...9 , Малих і великих літер латинського алфавіту a, b, c, d, e, f або A, B, C, D, E, F.

По-друге, у транслятора можуть виникнути труднощі з розпізнаванням шістнадцяткових чисел через те, що вони можуть складатися як з одних цифр 0 ... 9 (наприклад, 190845), так і починатися з літери латинського алфавіту (наприклад, ef15). Для того щоб "пояснити" транслятору, що дана лексема не є десятковим числом або ідентифікатором, програміст повинен спеціальним чином виділяти шістнадцяткове число. Для цього на кінці послідовності шістнадцяткових цифр, складових шестнадцатеріч-ве число, записують латинську букву " h". Це обов'язкова умова. Якщо шістнадцяткове число починається з букви, то перед ним записується провідний нуль: 0 ef15 h.

Практично кожне речення містить опис об'єкта, над яким або за допомогою якого виконується певна дія. Ці об'єкти називаються операндами. Їх можна визначити так: операнди - це об'єкти (деякі значення, регістри або комірки пам'яті), на які діють інструкції або директиви, або це об'єкти, які визначають або уточнюють дію інструкцій або директив.

Можливо, провести наступну класифікацію операндів:

­ постійні або безпосередні операнди;

­ адресні операнди;

­ переміщувані операнди;

лічильник адреси;

­ регістровий операнд;

­ базовий і індексний операнди;

­ структурні операнди;

записи.

Операнди є елементарними компонентами, з яких формується частина машинної команди, що позначає об'єкти, над якими виконується операція. У більш загальному випадку операнди можуть входити як складові частини в більш складні утворення, звані виразами.

вирази являють собою комбінації операндів і операторів, що розглядаються як єдине ціле. Результатом обчислення виразу може бути адреса деякої комірки пам'яті або деяке константне (абсолютне) значення.

­ 3 Типи операторів асемблера

Перерахуємо можливі типи операторів асемблера і синтаксичні правила формування виразів асемблера:

­ арифметичні оператори;

­ оператори зсуву;

­ оператори порівняння;

­ логічні оператори;

­ індексний оператор;

­ оператор перевизначення типу;

­ оператор перевизначення сегмента;

­ оператор іменування типу структури;

­ оператор одержання сегментної складової адреси виразу;

­ оператор одержання зсуву виразу.

1 директиви асемблера

­ Директиви асемблера бувають:

1) Директиви сегментації. В ході попереднього обговорення ми з'ясували всі основні правила запису команд і операндів у програмі на асемблері. Відкритим залишилося питання про те, як правильно оформити послідовність команд, щоб транслятор міг їх обробити, а мікропроцесор - виконати.

При розгляді архітектури мікропроцесора ми довідалися, що він має шість сегментних регістрів, за допомогою яких може одночасно працювати:

­ з одним сегментом коду;

­ з одним сегментом стека;

­ з одним сегментом даних;

­ з трьома додатковими сегментами даних.

Фізично сегмент являє собою область пам'яті, зайняту командами і (або) даними, адреси яких обчислюються щодо значення у відповідному сегментному регістрі. Синтаксичне опис сегмента на асемблері являє собою конструкцію, зображену на малюнку 13:


­ Малюнок 13 - Синтаксичне опис сегмента на асемблері

Важливо відзначити, що функціональне призначення сегмента трохи ширше, ніж просте розбиття програми на блоки коду, даних і стека. Сегментація є частиною більш загального механізму, пов'язаного з концепцією модульного програмування. Вона передбачає уніфікацію оформлення об'єктних модулів, що створюються компілятором, в тому числі з різних мов програмування. Це дозволяє об'єднувати програми, написані на різних мовах. Саме для реалізації різних варіантів такого об'єднання і призначені операнди в директиві SEGMENT.

2) Директиви управління лістингом. Директиви управління лістингом діляться на наступні групи:

­ загальні директиви управління лістингом;

­ директиви виведення в лістинг включаються файлів;

­ директиви виведення блоків умовного ассемблирования;

­ директиви виведення в лістинг макрокоманд;

­ директиви виведення в лістинг інформації про перехресні посилання;

­ директиви зміни формату лістингу.

2 Система команд процесора

Система команд процесора представлена \u200b\u200bна малюнку 14.

Розглянемо основні групи команд.

­ Малюнок 14 - Класифікація команд асемблера

Команди бувають:

1 Команди пересилання даних. Ці команди займають дуже важливе місце в системі команд будь-якого процесора. Вони виконують такі найважливіші функції:

­ збереження в пам'яті вмісту внутрішніх регістрів процесора;

­ копіювання вмісту з однієї області пам'яті в іншу;

­ запис в пристрої введення / виводу і читання з пристроїв введення / виводу.

У деяких процесорах всі ці функції виконуються однією єдиною командоюMOV (Для байтових пересилань -MOVB ) але з різними методами адресації операндів.

В інших процесорах крім командиMOV є ще кілька команд для виконання перерахованих функцій. Також до командам пересилання даних відносяться команди обміну інформацією (їх позначення будується на основі словаExchange ). Може бути передбачений обмін інформацією між внутрішніми регістрами, між двома половинами одного регістра (SWAP ) Або між регістром і осередком пам'яті.

2 Арифметичні команди. Арифметичні команди розглядають коди операндів як числові виконавчі або двійковій-десяткові коди. Ці команди можуть бути розділені на п'ять основних груп:

­ команди операцій з фіксованою комою (додавання, віднімання, множення, ділення);

­ команди операцій з плаваючою комою (додавання, віднімання, множення, ділення);

­ команди очищення;

­ команди инкремента і декремента;

­ команда порівняння.

3 Команди операцій з фіксованою комою працюють з кодами в регістрах процесора або в пам'яті як зі звичайними двійковими кодами. Команди операцій з плаваючою комою (крапкою) використовують формат уявлення чисел з порядком і мантиссой (зазвичай ці числа займають дві послідовні комірки пам'яті). В сучасних потужних процесорах набір команд з плаваючою комою не обмежується тільки чотирма арифметичне-тическими діями, а містить і безліч інших більш складних команд, наприклад, обчислення тригонометричних функцій, логарифмічних функцій, а також складних функцій, необхідних при обробці звуку і зображення.

4 Команди очищення призначені для запису нульового коду в регістр або елемент пам'яті. Ці команди можуть бути замінені командами пересилання нульового коду, але спеціальні команди очищення зазвичай виконуються швидше, ніж команди пересилання.

5 Команди инкремента (збільшення на одиницю) і декремента

(Зменшення на одиницю) також бувають дуже зручні. Їх можна в принципі замінити командами підсумовування з одиницею або віднімання одиниці, але інкремент і декремент виконуються швидше, ніж підсумовування і віднімання. Ці команди вимагають одного вхідного операнда, який одночасно є і вихідним операндом.

6 Команда порівняння призначена для порівняння двох вхідних операндів. По суті, вона обчислює різницю цих двох операндів, але вихідного операнда не формує, а всього лише змінює біти в регістрі стану процесора по результату цього вирахування. Наступна за командою порівняння команда (зазвичай це команда переходу) буде аналізувати біти в регістрі стану процесора і виконувати дії в залежності від їх значень. У деяких процесорах передбачені команди цепочечного порівняння двох послідовностей операндов, що в пам'яті.

7 Логічні команди. Логічні команди виконують над операндами логічні (побітові) операції, тобто вони розглядають коди операндів не як єдине число, а як набір окремих бітів. Цим вони відрізняються від арифметичних команд. Логічні команди виконують такі основні операції:

­ логічне І, логічне АБО, складання по модулю 2 (виключає Або);

­ логічні, арифметичні та циклічні зрушення;

­ перевірка бітів і операндів;

­ установка і очищення бітів (прапорів) регістра стану процесора (PSW).

Команди логічних операцій дозволяють побитно обчислювати основні логічні функції від двох вхідних операндів. Крім того, операція І використовується для примусового очищення заданих бітів (в якості одного з операндів при цьому використовується код маски, в якому розряди, що вимагають очищення, встановлені в нуль). Операція АБО застосовується для примусової установки заданих бітів (в якості одного з операндів при цьому використовується код маски, в якому розряди, що вимагають установки в одиницю, дорівнюють одиниці). Операція «Що виключає АБО» використовується для інверсії заданих бітів (в якості одного з операндів при цьому застосовується код маски, в якому біти, що підлягають інверсії, встановлені в одиницю). Команди вимагають двох вхідних операндів і формують один вихідний операнд.

8 Команди зрушень дозволяють побитно зрушувати код операнда вправо (в сторону молодших розрядів) або вліво (в сторону старших розрядів). Тип зсуву (логічний, арифметичний або циклічний) визначає, яким буде нове значення старшого біта (при зсуві вправо) або молодшого біта (при зсуві вліво), а також визначає, чи буде десь збережено колишнє значення старшого біта (при зсуві вліво) або молодшого біта (при зсуві вправо). Циклічні зрушення дозволяють зрушувати біти коду операнда по колу (за годинниковою стрілкою при зсуві вправо або проти годинникової стрілки при зсуві вліво). При цьому в кільце зсуву може входити чи не входити прапор переносу. У біт прапора перенесення (якщо він використовується) записується значення старшого біта при циклічному зсуві вліво і молодшого біта при циклічному зсуві вправо. Відповідно, значення біта прапора перенесення буде переписуватися в молодший розряд при циклічному зсуві вліво і в старший розряд при циклічному зсуві вправо.

9 Команди переходів. Команди переходів призначені для організації всіляких циклів, розгалужень, викликів підпрограм і т.д., тобто вони порушують послідовний хід виконання програми. Ці команди записують в регістр-лічильник команд нове значення і тим самим викликають перехід процесора не до наступної по порядку команді, а до будь-якої іншої команди в пам'яті програм. Деякі команди переходів передбачають надалі повернення назад, в точку, з якої був зроблений перехід, інші не передбачають цього. Якщо повернення передбачено, то поточні параметри процесора зберігаються в стеці. Якщо повернення не передбачене, то поточні параметри процесора не зберігаються.

Команди переходів без повернення діляться на дві групи:

­ команди безумовних переходів;

­ команди умовних переходів.

У позначеннях цих команд використовуються словаBranch (розгалуження) і Jump (стрибок).

Команди безумовних переходів викликають перехід в нову адресу незалежно ні від чого. Вони можуть викликати перехід на зазначену величину зсуву (вперед або назад) або ж на вказану адресу пам'яті. Величина зміщення або нове значення адреси вказуються в якості вхідного операнда.

Команди умовних переходів викликають перехід не завжди, а тільки при виконанні заданих умов. В якості таких умов зазвичай виступають значення прапорів в регістрі стану процесора (PSW ). Тобто умовою переходу є результат попередньої операції, яка змінює значення прапорів. Всього таких умов переходу може бути від 4 до 16. Кілька прикладів команд умовних переходів:

­ перехід, якщо дорівнює нулю;

­ перехід, якщо не дорівнює нулю;

­ перехід, якщо є переповнення;

­ перехід, якщо немає переповнення;

­ перехід, якщо більше нуля;

­ перехід, якщо менше або дорівнює нулю.

Якщо умова переходу виконується, то проводиться завантаження в регістр-лічильник команд нового значення. Якщо ж умова переходу не виконується, лічильник команд просто нарощується, і процесор вибирає і виконує наступну по порядку команду.

Спеціально для перевірки умов переходу застосовується команда порівняння (СМР), що передує команді умовного переходу (або навіть декільком командам умовних переходів). Але прапори можуть встановлюватися і будь-який інший командою, наприклад командою пересилання даних, будь-якої арифметичної або логічної командою. Відзначимо, що самі команди переходів прапори не змінюють, що як раз і дозволяє ставити кілька команд переходів одну за одною.

Особливе місце серед команд переходу з поверненням займають команди переривань. Ці команди в якості вхідного операнда вимагають номер переривання (адреса вектора).

висновок:

Мова асемблера - це символічне уявлення машинного мови. Мова асемблера для кожного типу комп'ютера свій. Програма на асемблері являє собою сукупність блоків пам'яті, званих сегментами пам'яті. Кожен сегмент містить сукупність речень мови, кожне з яких займає окремий рядок коду програми. Речення асемблера бувають чотирьох типів: команди або інструкції, макроси, директиви, рядки коментарів.

Допустимими символами при написанні тексту програм є всі латинські літери: A-Z, a-z. При цьому великі і малі літери вважаються еквівалентними; цифри від 0 до 9 ; знаки ? , @ , $ , _ , & ; роздільники , . () < > { } + / * % ! " " ? = # ^ .

Застосовують наступні типи операторів асемблера і синтаксичні правила формування виразів асемблера. арифметичні оператори, оператори зсуву, оператори порівняння, логічні оператори, індексний оператор, оператор перевизначення типу, оператор перевизначення сегмента, оператор іменування типу структури, оператор одержання сегментної складової адреси виразу, оператор одержання зсуву виразу.

Система команд розділена на 8 основних груп.

­ Контрольні питання:

1 Що являє собою мову асемблера?

2 Які символи можна застосовувати для запису команд на асемблері?

3 Що являють собою мітки і їх призначення?

4 Пояснити структуру команд асемблера.

5 Перерахувати 4 типи пропозицій асемблера.

НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ УЗБЕКИСТАНУ ІМЕНІ Мірза УЛУГБЕКА

ФАКУЛЬТЕТ КОМП'ЮТЕРНИХ ТЕХНОЛОГІЇ

На тему: Семантичний розбір EXE-файлу.

виконав:

Ташкент 2003.

Передмова.

Мова асемблера і структура команд.

Структура EXE-файлу (семантичний розбір).

Структура COM-файлу.

Принцип дії і розповсюдження вірусу.

Дисассемблер.

Програми.

Передмова

Професія програміста дивовижна і унікальна. У наш час науку і життя неможливо уявити без новітніх технології. Все що пов'язано з діяльністю людини не обходиться без обчислювальної техніки. А це сприяє її високому розвитку і досконалості. Нехай розвиток персональних комп'ютерів почалося не так давно, але протягом цього часу були зроблені колосальні кроки з програмних продуктів і ще довгий час ці продукти будуть широко використовуватися. Область пов'язаних з комп'ютерами знанні зазнала вибух, як і відповідна технологія. Якщо не брати до розгляду комерційну сторону, то можна сказати, що чужих людей в цій галузі професійної діяльності немає. Багато хто займається розробкою програм не заради вигоди або заробітку, а з власної волі, по захопленню. Звичайно це не повинно позначитися на якості програми, і в цій справі так би мовити «бізнесі» є конкуренція і попит на якість виконання, на стабільній роботі і відповідає всім вимогам сучасності. Тут так само варто відзначити появу мікропроцесорів в 60-х роках, які прийшли на заміну великої кількості набору ламп. Є деякі різновиди мікропроцесорів які сильно відрізняються один від одного. Ці мікропроцесори відмінні один від одного розрядністю і вбудованими системними командами. Найпоширеніші такі як: Intel, IBM, Celeron, AMD і т.д. Всі ці процесори мають відношення до розвиненої архітектурі процесорів фірми Intel. Поширення мікрокомп'ютерів послужило причиною перегляду ставлення до мови асемблера з двох основних причин. По-перше, програми, написані на мові асемблера, вимагають значно менше пам'яті і часу виконання. По-друге, знання мови асемблера і результуючого машинного коду дає розуміння архітектури машини, що навряд чи забезпечується при роботі на мові високого рівня. Хоча більшість фахівців в області програмного забезпечення ведуть розробки на мовах високого рівня, таких як Паскаль, С або Delphi, що простіше при написанні програм, найбільш потужне і ефективне програмне забезпечення повністю або частково написано на мові асемблера. Мови високого рівня були розроблені для того, щоб уникнути спеціальної технічної особливості конкретних комп'ютерів. А мова асемблера, в свою чергу, розроблений для конкретної специфіки процесора. Отже, для того, щоб написати програму на мові асемблера для конкретного комп'ютера, слід знати його архітектуру. В наші дні видом основного програмного продукту є EXE-файл. З огляду на позитивні сторони цього, автор програми може бути впевнений в її недоторканності. Але найчастіше часом це далеко не так. Існує так само і дисассемблер. За допомогою дисассемблер можна дізнатися переривання і коди програми. Людині, що добре розбирається в асемблері не складно буде переробити всю програму на свій смак. Можливо звідси з'являється сама нерозв'язна проблема - вірус. Навіщо ж люди пишуть вірус? Деякі ставлять це питання з подивом, деякі з злістю, але тим не менш продовжують існувати люди які цікавляться цим завданням не з точки зору нанесення якогось шкоди, а як інтересу до системного програмування. Пишуть Віруси з різних причин. Одним подобається системні виклики, іншим удосконалювати свої знання в асемблера. Про все це я спробую викласти в своїй роботі. Так само в ньому сказано не тільки про структуру EXE-файлу а й про мову асемблера.

^ Мова Асемблера.

Цікаво простежити, починаючи з часу появи перших комп'ютерів і закінчуючи сьогоднішнім днем, за трансформаціями уявлень про мову асемблера у програмістів.

Колись асемблер була мовою, без знання якого не можна було змусити комп'ютер зробити що-небудь корисне. Поступово ситуація змінювалася. З'являлися більш зручні засоби спілкування з комп'ютером. Але, на відміну від інших мов, асемблер не вмирав, більш того він не міг зробити цього в принципі. Чому? У пошуках відповіді спробуємо зрозуміти, що таке мова асемблера взагалі.

Якщо коротко, то мова асемблера - це символічне уявлення машинного мови. Всі процеси в машині на найнижчому, апаратному рівні приводяться в дію тільки командами (інструкціями) машинної мови. Звідси зрозуміло, що, незважаючи на загальну назву, мова асемблера для кожного типу комп'ютера свій. Це стосується і зовнішнього вигляду програм, написаних на асемблері, і ідей, відображенням яких ця мова є.

По-справжньому вирішити проблеми, пов'язані з апаратурою (або навіть, більш того, залежні від апаратури як, наприклад, підвищення швидкодії програми), неможливо без знання асемблера.

Програміст або будь-який інший користувач може використовувати будь-які високорівневі засоби, аж до програм побудови віртуальних світів і, можливо, навіть не підозрювати, що насправді комп'ютер виконує не команди мови, на якому написана його програма, а їх трансформоване уявлення в формі нудною і похмурою послідовності команд зовсім іншої мови - машинного. А тепер уявімо, що у такого користувача виникла нестандартна проблема чи просто щось не заладилося. Наприклад, його програма повинна працювати з деяким незвичайним пристроєм або виконувати інші дії, що вимагають знання принципів роботи апаратури комп'ютера. Яким би розумним не був програміст, яким би гарним не був мову, на якому він написав свою дивну програму, без знання асемблера йому не обійтися. І не випадково практично всі компілятори мов високого рівня містять засоби зв'язку своїх модулів з модулями на асемблері або підтримують вихід на асемблерний рівень програмування.

Звичайно, час комп'ютерних універсалів вже пройшло. Як то кажуть не можна осягнути неосяжне. Але є щось спільне, свого роду фундамент, на якому будується будь-яке серйозне комп'ютерна освіта. Це знання про принципи роботи комп'ютера, його архітектурі і мовою асемблера як відображенні і втіленні цих знань.

Типовий сучасний комп'ютер (на базі i486 або Pentium) складається з наступних компонентів (рис. 1).

Рис. 1. Комп'ютер і периферійні пристрої

Рис. 2. Структурна схема персонального комп'ютера

З малюнка (рис 1) видно, що комп'ютер складається з кількох фізичних пристроїв, кожне з яких підключено до одного блоку, званого системним. Якщо міркувати логічно, то ясно, що він грає роль деякого координуючого пристрою. Давайте заглянемо всередину системного блоку (не потрібно намагатися проникнути всередину монітора - там немає нічого цікавого, до того ж це небезпечно): відкриваємо корпус і бачимо якісь плати, блоки, з'єднувальні дроти. Щоб зрозуміти їх функціональне призначення, подивимося на структурну схему типового комп'ютера (рис. 2). Вона не претендує на безумовну точність і має на меті лише показати призначення, взаємозв'язок і типовий склад елементів сучасного персонального комп'ютера.

Обговоримо схему на рис. 2 в дещо нетрадиційному стилі.
Людині властиво, зустрічаючись з чимось новим, шукати якісь асоціації, які можуть допомогти йому пізнати невідоме. Які асоціації викликає комп'ютер? У мене, наприклад, комп'ютер часто асоціюється з самою людиною. Чому?

Людина створюючи комп'ютер десь в глибині себе думав що створює щось схоже на себе самого. У комп'ютера є органи сприйняття інформації із зовнішнього світу - це клавіатура, миша, накопичувачі на магнітних дисках. На рис. 2 ці органи розташовані праворуч від системних шин. У комп'ютера є органи "переварюють" отриману інформацію - це центральний процесор і оперативна пам'ять. І, нарешті, у комп'ютера є органи мови, що видають результати переробки. Це також деякі з пристроїв справа.

Сучасним комп'ютерам, звичайно, далеко до людини. Їх можна порівняти з істотами, що взаємодіють із зовнішнім світом на рівні великого, але обмеженого набору безумовних рефлексів.
Цей набір рефлексів утворює систему машинних команд. На якому б високому рівні ви не спілкувалися з комп'ютером, в кінцевому підсумку все зводиться до нудною та одноманітною послідовності машинних команд.
Кожна машинна команда є свого роду подразником для порушення того чи іншого безумовного рефлексу. Реакція на цей подразник завжди однозначна і "зашита" в блоці мікрокоманд у вигляді прошивки. Ця мікропрограма і реалізує дії з реалізації машинної команди, але вже на рівні сигналів, що подаються на ті чи інші логічні схеми комп'ютера, тим самим керуючи різними підсистемами комп'ютера. У цьому полягає так званий принцип мікропрограмного управління.

Продовжуючи аналогію з людиною, відзначимо: для того, щоб комп'ютер правильно харчувався, придумано безліч операційних систем, компіляторів сотень мов програмування і т. Д. Але всі вони є, по суті, лише стравою, на якому за певними правилами доставляється їжа (програми) шлунку (комп'ютера). Тільки шлунок комп'ютера любить дієтичну, одноманітну їжу - подавай йому інформацію структуровану, у вигляді суворо організованих послідовностей нулів і одиниць, комбінації яких і складають машинний мову.

Таким чином, зовні будучи поліглотом, комп'ютер розуміє тільки одну мову - мову машинних команд. Звичайно, для спілкування і роботи з комп'ютером, необов'язково знати цю мову, але практично будь-який професійний програміст рано чи пізно стикається з необхідністю його вивчення. На щастя, програмісту не потрібно намагатися осягнути значення різних комбінацій двійкових чисел, так як ще в 50-і роки програмісти стали використовувати для програмування символічний аналог машинної мови, який назвали мовою асемблера. Ця мова точно відображає всі особливості машинної мови. Саме тому, на відміну від мов високого рівня, мова асемблера для кожного типу комп'ютера свій.

З усього вищесказаного можна зробити висновок, що, так як мова асемблера для комп'ютера "рідний", то і найефективніша програма може бути написана тільки на ньому (за умови, що її пише кваліфікований програміст). Тут є одне маленьке "але": це дуже трудомісткий, вимагає великої уваги і практичного досвіду процес. Тому реально на асемблері пишуть в основному програми, які повинні забезпечити ефективну роботу з апаратною частиною. Іноді на асемблері пишуться критичні за часом виконання або витрачання пам'яті ділянки програми. Згодом вони оформляються у вигляді підпрограм і суміщаються з кодом на мові високого рівня.

До вивчення мови асемблера будь-якого комп'ютера має сенс приступати тільки після з'ясування того, яка частина комп'ютера залишена видимої і доступною для програмування на цій мові. Це так звана програмна модель комп'ютера, частиною якої є програмна модель мікропроцесора, яка містить 32 регістра в тій чи іншій мірі доступних для використання програмістом.

Дані регістри можна розділити на дві великі групи:

^ 16 призначених для користувача регістрів;

16 системних регістрів.

У програмах на мові асемблера регістри використовуються дуже інтенсивно. Більшість регістрів мають певне функціональне призначення.

Як випливає з назви, призначеними для користувача регістри називаються тому, що програміст може використовувати їх при написанні своїх програм. До цих регістрів належать (рис. 3):

Вісім 32-бітових регістрів, які можуть використовуватися програмістами для зберігання даних і адрес (їх ще називають регістрами загального призначення (РОН)):

шість регістрів сегментів: cs, ds, ss, es, fs, gs;

регістри стану і управління:

Регістр прапорів eflags / flags;

Регістр покажчика команди eip / ip.

Рис. 3. Користувальницькі регістри мікропроцесорів i486 і Pentium

Чому багато хто з цих регістрів наведені з похилою рискою? Ні, це не різні регістри - це частини одного великого 32-розрядного регістра. Їх можна використовувати в програмі як окремі об'єкти. Так зроблено для забезпечення працездатності програм, написаних для молодших 16-розрядних моделей мікропроцесорів фірми Intel, починаючи з i8086. Мікропроцесори i486 і Pentium мають в основному 32-розрядні регістри. Їх кількість, за винятком сегментних регістрів, таке ж, як і у i8086, але розмірність більше, що і відображено в їх позначеннях - вони мають
приставку e (Extended).

^ Регістри загального призначення
Всі регістри цієї групи дозволяють звертатися до своїх "молодшим" \u200b\u200bчастинам (див. Рис. 3). Розглядаючи цей малюнок, зауважте, що використовувати для самостійної адресації можна лише молодші 16 і 8-бітові частини цих регістрів. Старші 16 біт цих регістрів як самостійні об'єкти недоступні. Це зроблено, як ми зазначили вище, для сумісності з молодшими 16-розрядними моделями мікропроцесорів фірми Intel.

Перерахуємо регістри, які відносяться до групи регістрів загального призначення. Так як ці регістри фізично знаходяться в мікропроцесорі всередині арифметико-логічного пристрою (АЛП), то їх ще називають регістрами АЛУ:

eax / ax / ah / al (Accumulator register) - акумулятор.
Застосовується для зберігання проміжних даних. У деяких командах використання цього регістра обов'язково;

ebx / bx / bh / bl (Base register) - базовий регістр.
Застосовується для зберігання базової адреси деякого об'єкта в пам'яті;

ecx / cx / ch / cl (Count register) - регістр-лічильник.
Застосовується в командах, які виробляють деякі повторювані дії. Його використання найчастіше неявно і приховано в алгоритмі роботи відповідної команди.
Наприклад, команда організації циклу loop крім передачі керування команді, що знаходиться за деякою адресою, аналізує і зменшує на одиницю значення регістра ecx / cx;

edx / dx / dh / dl (Data register) - регістр даних.
Так само, як і регістр eax / ax / ah / al, він зберігає проміжні дані. У деяких командах його використання обов'язково; для деяких команд це відбувається неявно.

Наступні два регістри використовуються для підтримки так званих ланцюгових операцій, тобто операцій, які виробляють послідовну обробку ланцюжків елементів, кожен з яких може мати довжину 32, 16 або 8 біт:

esi / si (Source Index register) - індекс джерела.
Цей регістр у ланцюгових операціях містить поточну адресу елемента в ланцюжку-джерелі;

edi / di (Destination Index register) - індекс приймача (одержувача).
Цей регістр у ланцюгових операціях містить поточну адресу в ланцюжку-приймачі.

В архітектурі мікропроцесора на програмно-апаратному рівні підтримується така структура даних, як стек. Для роботи зі стеком в системі команд мікропроцесора є спеціальні команди, а в програмній моделі мікропроцесора для цього існують спеціальні регістри:

esp / sp (Stack Pointer register) - регістр покажчика стека.
Містить покажчик вершини стека в поточному сегменті стека.

ebp / bp (Base Pointer register) - регістр покажчика бази кадру стека.
Призначений для організації довільного доступу до даних усередині стека.

Стеком називають область програми для тимчасового зберігання довільних даних. Зрозуміло, дані можна зберігати і в сегменті даних, проте в цьому випадку для кожного що зберігається на час даного треба заводити окрему іменовану комірку пам'яті, що збільшує розмір програми і кількість використовуваних імен. Зручність стека полягає в тому, що його область використовується багато разів, причому збереження в стеку даних і вибірка їх звідти виконується за допомогою ефективних команд push і pop без зазначення будь-яких імен.
Стек традиційно використовується, наприклад, для збереження вмісту регістрів, використовуваних програмою, перед викликом підпрограми, яка, в свою чергу, буде використовувати регістри процесора "в своїх особистих цілях". Початковий вміст регістрів ізатекается з стека після повернення з підпрограми. Інший поширений прийом - передача підпрограмі необхідних нею параметрів через стек. Підпрограма, знаючи, в якому порядку поміщені в стек параметри, може забрати їх звідти і використовувати при своєму виконанні. Відмінною особливістю стека є своєрідний порядок вибірки містяться в ньому даних: в будь-який момент часу в стеку доступний тільки верхній елемент, тобто елемент, завантажений в стек останнім. Вивантаження з стека верхнього елементу робить доступним наступний елемент. Елементи стека розташовуються в області пам'яті, відведеної під стек, починаючи з дна стека (тобто з його максимального адреси) по послідовно зменшується адресами. Адреса верхнього, доступного елемента зберігається в регістрі-покажчику стека SP. Як і будь-яка інша область пам'яті програми, стек повинен входити в якийсь сегмент або утворювати окремий сегмент. У будь-якому випадку сегментна адреса цього сегмента поміщається в сегментний регістр стека SS. Таким чином, пара регістрів SS: SP описують адресу доступною осередки стека: в SS зберігається сегментна адреса стека, а в SP - зсув останнього збереженого в стеку даного (рис. 4, а). Обратитим на те, що в початковому стані покажчик стека SP вказує на осередок, що лежить під дном стека і не входить в нього.

Рис 4. Організація стека: а - вихідний стан, б - після завантаження одного елемента (в даному прикладі - вмісту регістра АХ), в - після завантаження другого елементу (вмісту регістра DS), г - після вивантаження одного елемента, д - після вивантаження двох елементів і повернення в початковий стан.

Завантаження в стек здійснюється спеціальною командою роботи зі стеком push (проштовхнути). Ця команда спочатку зменшує на 2 вміст покажчика стека, а потім поміщає операнд за адресою в SP. Якщо, наприклад, ми хочемо тимчасово зберегти в стеці вміст регістра АХ, слід виконати команду

Стек переходить в стан, показане на рис. 1.10, б. Видно, що покажчик стека зміщується на два байти вгору (в сторону менших адрес) і за цією адресою записується вказаний в команді проштовхування операнд. Наступна команда завантаження в стек, наприклад,

переведе стек в стан, показане на рис. 1.10, в. У стеці будуть тепер зберігатися два елементи, причому доступним буде тільки верхній, на який вказує покажчик стека SP. Якщо через якийсь час нам знадобилося відновити початковий вміст збережених в стеку регістрів, ми повинні виконати команди вивантаження з стека pop (виштовхнути):

pop DS
pop AX

Якого розміру повинен бути стек? Це залежить від того, наскільки інтенсивно він використовується в програмі. Якщо, наприклад, планується зберігати в стеці масив обсягом 10 000 байт, то стек повинен бути не менше цього розміру. При цьому треба мати на увазі, що в ряді випадків стек автоматично використовується системою, зокрема, при виконанні команди переривання int 21h. За цією командою спочатку процесор поміщає в стек адреса повернення, а потім DOS відправляє туди ж вміст регістрів і іншу інформацію, що відноситься до перерваної програми. Тому, навіть якщо програма зовсім не використовує стек, він все ж повинен бути присутнім в програмі і мати розмір не менше кількох десятків слів. У нашому першому прикладі ми відвели під стек 128 слів, що безумовно достатньо.

^ Структура програми на асемблері

Програма на асемблері являє собою сукупність блоків пам'яті, званих сегментами пам'яті. Програма може складатися з одного або декількох таких блоків-сегментів. Кожен сегмент містить сукупність речень мови, кожне з яких займає окремий рядок коду програми.

Речення асемблера бувають чотирьох типів:

команди або інструкції, що представляють собою символічні аналоги машинних команд. У процесі трансляції інструкції асемблера перетворяться у відповідні команди системи команд мікропроцесора;

макрокоманди - оформляються певним чином пропозиції тексту програми, що заміщаються під час трансляції іншими пропозиціями;

директиви, які є зазначенням транслятору асемблера на виконання деяких дій. У директив немає аналогів в машинному поданні;

рядки коментарів, що містять будь-які символи, в тому числі і літери російського алфавіту. Коментарі ігноруються транслятором.

^ Синтаксис асемблера

Пропозиції, складові програму, можуть являти собою синтаксичну конструкцію, що відповідає команді, макрокоманді, директиві або коментарю. Для того щоб транслятор асемблера міг розпізнати їх, вони повинні формуватися за певними синтаксичними правилами. Для цього найкраще використовувати формальний опис синтаксису мови на зразок правил граматики. Найбільш поширені способи подібного опису мови програмування - синтаксичні діаграми і розширені форми Бекуса-Наура. Для практичного використання більш зручні синтаксичні діаграми. Наприклад, синтаксис пропозицій асемблера можна описати за допомогою синтаксичних діаграм, показаних на наступних малюнках.

Рис. 5. Формат пропозиції ассемблера

Рис. 6. Формат директив

Рис. 7. Формат команд і макрокоманд

На цих малюнках:

ім'я мітки - ідентифікатор, значенням якого є адреса першого байта того пропозиції вихідного тексту програми, яке він позначає;

ім'я - ідентифікатор, що відрізняє дану директиву від інших однойменних директив. В результаті обробки асемблером певної директиви цього імені можуть бути присвоєні певні характеристики;

код операції (КОП) і директива - це мнемонічні позначення відповідної машинної команди, макрокоманди або директиви транслятора;

операнди - частини команди, макрокоманди або директиви асемблера, що позначають об'єкти, над якими виробляються дії. Операнди асемблера описуються виразами з числовими і текстовими константами, мітками і ідентифікаторами змінних з використанням знаків операцій і деяких зарезервованих слів.

^ Як використовувати синтаксичні діаграми? Дуже просто: для цього потрібно всього лише знайти і потім пройти шлях від входу діаграми (ліворуч) до її виходу (праворуч). Якщо такий шлях існує, то пропозиція або конструкція синтаксично правильні. Якщо такого шляху немає, значить цю конструкцію компілятор не прийме. При роботі з синтаксичними діаграмами звернемо увагу на напрям обходу, що визначене стрілками, так як серед шляхів можуть бути і такі, за якими можна йти справа наліво. По суті, синтаксичні діаграми відбивають логіку роботи транслятора при розборі вхідних пропозицій програми.

Допустимими символами при написанні тексту програм є:

Всі латинські букви: A-Z, a-z. При цьому великі і малі літери вважаються еквівалентними;

Цифри від 0 до 9;

Знаки ?, @, $, _, &;

Роздільники,. ()< > { } + / * % ! " " ? \ = # ^.

Речення асемблера формуються з лексем, що представляють собою синтаксично нероздільні послідовності припустимих символів мови, що мають сенс для транслятора.

Лексемами є:

ідентифікатори - послідовності припустимих символів, що використовуються для позначення таких об'єктів програми, як коди операцій, імена змінних і назви міток. Правило запису ідентифікаторів полягає в наступному: ідентифікатор може складатися з одного або декількох символів. В якості символів можна використовувати букви латинського алфавіту, цифри і деякі спеціальні знаки - _,?, $, @. Ідентифікатор не може починатися символом цифри. Довжина ідентифікатора може бути до 255 символів, хоча транслятор сприймає лише перші 32, а інші ігнорує. Регулювати довжину можливих ідентифікаторів можна з використанням опції командного рядка mv. Крім цього існує можливість вказати транслятору на те, щоб він розрізняв великі та малі літери або ігнорував їх відмінність (що і робиться за замовчуванням).

^ Команди асемблера.

Команди асемблера розкривають можливість передавати комп'ютера свої вимоги, механізм передачі управління в програмі (цикли і переходи) для логічних порівнянь і програмної організації. Однак, програмовані завдання рідко бувають такі прості. Більшість програм містять ряд циклів, в яких кілька команд повторюються до досягнення певного вимоги, і різні перевірки, що визначають, які з кількох дій слід виконувати. Деякі команди можуть передавати управління, змінюючи нормальну послідовність кроків безпосередньої модифікацією значення зміщення в командному покажчику. Як говорилося раніше, існують різні команди для різних процесорів, ми ж будемо розглядати ряд деяких команд для процесорів 80186, 80286 і 80386.

Для опису стану прапорів після виконання деякої команди будемо використовувати вибірку з таблиці, що відбиває структуру регістра прапорів eflags:

У нижньому рядку цієї таблиці наводяться значення прапорів після виконання команди. При цьому можуть використовуватися такі символи:

1 - після виконання команди прапор встановлюється (дорівнює 1);

0 - після виконання команди прапор скидається (дорівнює 0);

r - значення прапора залежить від результату роботи команди;

Після виконання команди прапор не визначений;

пробіл - після виконання команди прапор не змінюється;

Для подання операндів в синтаксичних діаграмах використовуються наступні позначення:

r8, r16, r32 - операнд в одному з регістрів розміром байт, слово або подвійне слово;

m8, m16, m32, m48 - операнд в пам'яті розміром байт, слово, подвійне слово або 48 біт;

i8, i16, i32 - безпосередній операнд розміром байт, слово або подвійне слово;

a8, a16, a32 - відносний адреса (зсув) в сегменті коду.

Команди (в алфавітному порядку):

* Дані команди описані докладно.

ADD
(ADDition)

додавання

^ Схема команди:

add приймач, джерело

Призначення: додавання двох операндів джерело і приймач розмірністю байт, слово або подвійне слово.

Алгоритм роботи:

скласти операнди джерело і приймач;

записати результат складання в приймач;

встановити прапори.

Стан прапорів після виконання команди:

застосування:
Команда add використовується для складання двох цілочисельних операндів. Результат складання поміщається за адресою першого операнда. Якщо результат складання виходить за межі операнда приймач (виникає переповнення), то врахувати цю ситуацію слід шляхом аналізу прапора cf і подальшого можливого застосування команди adc. Наприклад, складемо значення в регістрі ax і області пам'яті ch. При додаванні слід врахувати можливість переповнення.

Регістр плюс регістр або пам'ять:

| 000000dw | modregr / rm |

Регістр AX (AL) плюс безпосереднє значення:

| 0000010w | --data-- | data, якщо w \u003d 1 |

Регістр або пам'ять плюс безпосереднє значення:

| 100000sw | mod000r / m | --data-- | data, якщо BW \u003d 01 |

CALL
(CALL)

Виклик процедури або завдання

^ Схема команди:

призначення:

передача управління близькій або далекої процедурі із запам'ятовуванням в стеці адреси точки повернення;

перемикання завдань.

Алгоритм роботи:
визначається типом операнда:

Мітка ближня - в стек заноситься вміст покажчика команд eip / ip і в цей же регістр завантажується нове значення адреси, відповідне мітці;

Мітка далека - в стек заноситься вміст покажчика команд eip / ip і cs. Потім в ці ж регістри завантажуються нові значення адрес, відповідні далекої мітці;

R16, 32 або m16, 32 - визначають регістр або елемент пам'яті, що містять зміщення в поточному сегменті команд, куди передається управління. При передачі управління в стек заноситься вміст покажчика команд eip / ip;

Покажчик на пам'ять - визначає комірку пам'яті, що містить 4 або 6-байтний покажчик на спричинюється процедуру. Структура такого покажчика 2 + 2 або 2 + 4 байта. Інтерпретація такого покажчика залежить від режиму роботи мікропроцесора:

^ Стан прапорів після виконання команди (крім перемикання завдання):

виконання команди не впливає на прапори

При перемиканні завдання значення прапорців змінюються відповідно до інформацією про регістрі eflags в сегменті стану TSS завдання, на яку проводиться перемикання.
застосування:
Команда call дозволяє організувати гнучку і різноманітну передачу управління на підпрограму зі збереженням адреси точки повернення.

Про б ь е к т н и й к о д (чотири формату):

Пряма адресація в сегменті:

| 11101000 | disp-low | diep-high |

Непряма адресація в сегменті:

| 11111111 | mod010r / m |

Непряма адресація між сегментами:

| 11111111 | mod011r / m |

Пряма адресація між сегментами:

| 10011010 | offset-low | offset-high | seg-low | seg-high |

CMP
(CoMPare operands)

порівняння операндів

^ Схема команди:

cmp операнд1, операнд2

Призначення: порівняння двох операндів.

Алгоритм роботи:

виконати віднімання (операнд1-операнд2);

в залежності від результату встановити прапори, операнд1 і операнд2 не зраджувати (тобто результат не запам'ятовувати).

застосування:
Дана команда використовується для порівняння двох операндів шляхом вирахування, при цьому операнди не змінюються. За результатами виконання команди встановлюються прапори. Команда cmp застосовується з командами умовного переходу і командою установки байта за значенням setcc.

Про б ь е к т н и й к о д (три формату):

Регістр або пам'ять з регістром:

| 001110dw | modregr / m |

Безпосереднє значення з регістром AX (AL):

| 0011110w | --data-- | data, якщо w \u003d 1 |

Безпосереднє значення з регістром або пам'яттю:

| 100000sw | mod111r / m | --data-- | data, якщо sw \u003d 0 |

DEC
(DECrement operand by 1)

Зменшення операнда на одиницю

^ Схема команди:

dec операнд

Призначення: зменшення значення операнда в пам'яті або регістрі на 1.

Алгоритм роботи:
команда віднімає 1 з операнда. Стан прапорів після виконання команди:

застосування:
Команда dec використовується для зменшення значення байта, слова, подвійного слова в пам'яті або регістрі на одиницю. При цьому зауважте те, що команда не впливає на прапор cf.

Регістр: | 01001reg |

^ Регістр або пам'ять: | 1111111w | mod001r / m |

DIV
(DIVide unsigned)

розподіл беззнаковое

Схема команди:

div дільник

Призначення: виконання операції ділення двох двійкових беззнакових значень.

^ Алгоритм роботи:
Для команди необхідне завдання двох операндів - діленого і дільника. Ділене задається неявно і розмір його залежить від розміру дільника, який вказується в команді:

якщо дільник розміром в байт, то ділене повинно бути розташоване в регістрі ax. Після операції приватне поміщається в al, а залишок - в ah;

якщо дільник розміром в слово, то ділене повинно бути розташоване в парі регістрів dx: ax, причому молодша частина діленого знаходиться в ax. Після операції приватне поміщається в ax, а залишок - в dx;

якщо дільник розміром в подвійне слово, то ділене повинно бути розташоване в парі регістрів edx: eax, причому молодша частина діленого знаходиться в eax. Після операції приватне поміщається в eax, а залишок - в edx.

^ Стан прапорів після виконання команди:

застосування:
Команда виконує цілочисельне ділення операндів з видачею результату ділення у вигляді приватного і залишку від ділення. При виконанні операції ділення можливе виникнення виняткової ситуації: 0 - помилка ділення. Ця ситуація виникає в одному з двох випадків: дільник дорівнює 0 або приватна занадто велике для його розміщення в регістрі eax / ax / al.

Про б ь е к т н и й к о д:

| 1111011w | mod110r / m |

INT
(INTerrupt)

Виклик підпрограми обслуговування переривання

^ Схема команди:

int номер_прериванія

Призначення: виклик підпрограми обслуговування переривання з номером переривання, заданим операндом команди.

^ Алгоритм роботи:

записати в стек регістр прапорів eflags / flags і адресу повернення. При записи адреси повернення спочатку записується вміст сегментного регістра cs, потім вміст покажчика команд eip / ip;

скинути в нуль прапори if і tf;

передати управління на програму обробки переривання з вказаним номером. Механізм передачі управління залежить від режиму роботи мікропроцесора.

^ Стан прапорів після виконання команди:

застосування:
Як видно з синтаксису, існують дві форми цієї команди:

int 3 - має свій індивідуальний код операції 0cch і займає один байт. Ця обставина робить її дуже зручною для використання в різних програмних відладчика для установки точок переривання шляхом підміни першого байта будь-якої команди. Мікропроцесор, зустрічаючи в послідовності команд команду з кодом операції 0cch, викликає програму обробки переривання з номером вектора 3, яка служить для зв'язку з програмним отладчиком.

Друга форма команди займає два байти, має код операції 0cdh і дозволяє ініціювати виклик підпрограми обробки переривання з номером вектора в діапазоні 0-255. Особливості передачі управління, як було зазначено, залежать від режиму роботи мікропроцесора.

Про б ь е к т н и й к о д (два формати):

Регістр: | 01000reg |

^ Регістр або пам'ять: | 1111111w | mod000r / m |

JCC
JCXZ / JECXZ
(Jump if condition)

(Jump if CX \u003d Zero / Jump if ECX \u003d Zero)

Перехід, якщо виконана умова

Перехід, якщо CX / ECX дорівнює нулю

^ Схема команди:

jcc мітка
jcxz мітка
jecxz мітка

Призначення: перехід всередині поточного сегмента команд в залежності від деякої умови.

^ Алгоритм роботи команд (крім jcxz / jecxz):
Перевірка стану прапорів в залежності від коду операції (воно відображає перевіряється умова):

якщо перевіряється умова істинно, то перейти до комірки, позначеної операндом;

якщо перевіряється умова помилкова, то передати управління наступній команді.

Алгоритм роботи команди jcxz / jecxz:
Перевірка умови рівності нулю вмісту регістра ecx / cx:

якщо перевіряється услов

За призначенням можна виділити команди (в дужках наводяться приклади мнемонічних кодів операцій команд асемблера ПК типу IBM PC):

l виконання арифметичних операцій (ADD і ADC - складання та складання з перенесенням, SUB і SBB - віднімання і віднімання з позичкою, MUL і IMUL - множення без знака і зі знаком, DIV і IDIV - ділення без знака і зі знаком, CMP - порівняння і т.д.);

l виконання логічних операцій (OR, AND, NOT, XOR, TEST і т. д.);

l пересилання даних (MOV - переслати, XCHG - обміняти, IN - ввести в мікропроцесор, OUT - вивести з мікропроцесора і т. д.);

l передачі управління (розгалуження програми: JMP - безумовного переходу, CALL - виклику процедури, RET - повернення з процедури, J * - умовного переходу, LOOP - управління циклом і т. д.);

l обробки рядків символів (MOVS - пересилання, CMPS - порівняння, LODS - завантаження, SCAS - сканування. Ці команди зазвичай використовуються з префіксом (модифікатором повторення) REP;

l переривання роботи програми (INT - програмні переривання, INTO - умовного переривання при переповненні, IRET - повернення з переривання);

l управління мікропроцесором (ST * і CL * - установки і скидання прапорів, HLT - зупинки, WAIT - очікування, NOP - холостого ходу і т. д.).

З повним списком команд асемблера можна познайомитися в роботах.

Команди пересилання даних

l MOV dst, src - пересилання даних (move - переслати з src в dst).

Пересилає: один байт (якщо src і dst мають формат байта) або одне слово (якщо src і dst мають формат слова) між регістрами або між регістром і пам'яттю, а також заносить безпосереднє значення в регістр або в пам'ять.

Операнди dst і src повинні мати однаковий формат - байт або слово.

Src можуть мати тип: r (register) - регістр, m (memory) - пам'ять, i (impedance) - безпосереднє значення. Dst можуть бути типу r, m. Не можна в одній команді використовувати операнди: rsegm спільно з i; два операнда типу m і два операнда типу rsegm). Операнд i може бути і простим виразом:

mov AX, (152 + 101B) / 15

Обчислення виразу виконується тільки при трансляції. Прапори не змінює.

l PUSH src - занесення слова в стек (push - проштовхнути; записати в стек ізsrc). Поміщає в вершину стека вміст src - будь-якого 16-бітового регістра (в тому числі і сегментного) або двох елементів пам'яті, що містять 16-бітове слово. Прапори не міняються;

l POP dst - витяг слова з стека (pop - виштовхнути; вважати з стека в dst). Знімає слово з вершини стека і поміщає його в dst - будь-який 16-бітовий регістр (в тому числі і сегментний) або в два відділення пам'яті. Прапори не міняються.

Поділитися