Структура команди мовою асемблера містить. Структура команди на мові асемблера програмування на рівні. Формат даних та структура команд мови асемблер

Команди мови Асемблер (Лекція)

ПЛАН ЛЕКЦІЇ

1. Основні групи операцій.

Pentium.

1. Основні групи операцій

Мікропроцесори виконують набір команд, які реалізують такі основні групи операцій:

Операції пересилання,

Арифметичні операції,

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

Операції зсуву,

Операції порівняння тестування,

Бітові операції,

Операції управління програмою;

Операції управління процесором.

2. Мнемокоди команд процесора Pentium

При описі команд зазвичай використовуються їх мнемонічні позначення (мнемокоди), які служать завдання команди при програмуванні мовою Асемблера. Для різних версій асемблера мнемокоды деяких команд можуть відрізнятися. Наприклад, для команди виклику підпрограми використовується мнемокодCALL або JSR (“ Jump to SubRoutine”). Проте мнемокоды більшості команд основних типів мікропроцесорів збігаються чи відрізняються незначно, оскільки є скороченнями відповідних англійських слів, визначальних виконувану операцію. Розглянемо мнемокоди команд, прийняті для процесорів Pentium.

Команди пересилання. Основною командою цієї групи є командаMOV яка забезпечує пересилання даних між двома регістрами або між регістром і осередком пам'яті. У деяких мікропроцесорах реалізується пересилання між двома осередками пам'яті, а також групове пересилання вмісту кількох регістров з пам'яті. Наприклад, мікропроцесори сімейства 68 xxx компанії Motorola виконують командуMOVE , що забезпечує пересилання з одного осередку пам'яті до іншого, і командуMOVEM , яка здійснює запис у пам'ять або завантаження з пам'яті вмісту заданого набору регістрів (до 16 регістрів). КомандаXCHG здійснює взаємний обмін вмістом двох регістрів процесора або регістру та комірки пам'яті.

Команди введення IN та висновку OUT реалізують пересилання даних з регістру процесора зовнішній пристрій або прийом даних із зовнішнього пристрою регістр. У цих командах задається номер інтерфейсного пристрою (порту вводу-виводу), через який здійснюється передача даних. Зазначимо, що багато мікропроцесорів немає спеціальних команд звернення до зовнішнім пристроям. В цьому випадку введення та виведення даних у системі виконується за допомогою командиMOV , де задається адреса необхідного інтерфейсного пристрою. Таким чином, зовнішній пристрій адресується як осередок пам'яті, а в адресному просторі виділяється певний розділ, в якому розташовуються адреси підключених до системи інтерфейсних пристроїв (портів).

Команди арифметичних операцій. Основними в цій групі є команди додавання, віднімання, множення і поділу, які мають ряд варіантів. Команди складання ADD та віднімання SUB виконують відповідні операції зcодержимим двох регістрів, регістру та комірки пам'яті або з використанням безпосереднього операнда. Команди AD C , SB B виробляють додавання та віднімання з урахуванням значення ознакиC, що встановлюється при формуванні перенесення у процесі виконання попередньої операції За допомогою цих команд реалізується послідовне додавання операндів, число розрядів яких перевищує розрядність процесора. Команда NEG змінює знак операнда, переводячи його у додатковий код.

Операції множення та поділу можуть виконуватися над числами зі знаком (командиI MUL, I DIV ) або беззнака (команди MUL, DIV ). Один з операцій завжди розміщується в регістрі, другий може перебувати в регістрі, осередку пам'яті або бути безпосереднім операндом. Результат операції знаходиться в регістрі. При множенні (командиMUL , IMUL ) Виходить результат подвоєної розрядності, для розміщення якого використовується два регістри. При розподілі (командиDIV , IDIV ) як ділимого використовується операнд подвоєної розрядності, що розміщується у двох регістрах, а як результат у два регістри записується приватне та залишок.

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

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

Команди порівняння та тестування . Порівняння операндів зазвичай здійснюється за допомогою командиCMP , яка здійснює віднімання операндів із встановленням значень ознак N, Z, V, Cу регістрі стану відповідно до отриманого результату. При цьому результат віднімання не зберігається і значення операндів не змінюються. Подальший аналіз одержаних значень ознак дозволяє визначити відносне значення (>,<, =) операндов со знаком или без знака. Использование различных способов адресации позволяет производит сравнение содержимого двух регистров, регистра и ячейки памяти, непосредственно заданного операнда с содержимым регистра или ячейки памяти.

Деякі мікропроцесори виконують команду тестування TST яка є однооперандним варіантом команди порівняння. Під час виконання цієї команди встановлюються ознаки N, Zвідповідно до знаку і значення (рівно або не дорівнює нулю) адресованого операнда.

Команди бітових операцій . Ці команди роблять установку значення ознакиCу регістрі станів відповідно до значення тестованого бітаbn в адресованому операнді. У деяких мікропроцесорах за результатом тестування біта проводиться установка ознакиZ. Номер біта, що тестуєтьсяnзадається або вмістом зазначеного в команді регістру, або безпосереднім операндом.

Команди цієї групи реалізують різні варіанти зміни тестованого біту. BT зберігає значення цього біта незмінним. B T S післятестування встановлює значення bn=1, а команда B T C - значення bn=0.Команда B T C інвертує значення біта bn після тестування.

Операції керування програмою. Для керування програмою використовується велика кількість команд, серед яких можна виділити:

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

- команди умовних переходів;

- команди організації програмних циклів;

- команди переривання;

- команди зміни ознак.

Безумовна передача керування проводиться командоюJMP яка завантажує в програмний лічильникPCновий вміст, що є адресою наступної команди, що виконується. Ця адреса або безпосередньо вказується в командіJMP (пряма адресація), або обчислюється як сума поточного вмістуPCта заданого у команді зміщення, яке є числом зі знаком (відносна адресація). Так якPCмістить адресу чергової команди програми, то останній спосіб визначає адресу переходу, зміщений щодо чергової адреси на задане число байтів. При позитивному зміщенні відбувається перехід до наступних команд програми, при негативному зміщенні – до попередніх.

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

Команди управління ознаками забезпечують запис - читання вмісту регістру стану, у якому зберігаються ознаки, і навіть зміна значень окремих ознак. Наприклад, у процесорах Pentium реалізуються команди LAHF і SAHF , які виконують завантаження молодшого байта, де містяться ознаки, з регістру стану EFLAGу молодший байт регістру EAXта заповнення молодшого байта EFLAGSз регістру E AX.. Команди CLC, STCздійснюють встановлення значень ознаки перенесення CF=0, CF=1, а команда CMCвикликає інвертування значення цієї ознаки.Так як ознаки визначають хід виконання програми при умовних переходах, команди зміни ознак зазвичай використовуються для управління програмою.

Команди управління процесором . До цієї групи належать команди зупинки, відсутності операції та ряд команд, що визначають режим роботи процесора або його окремих блоків. КомандаHLT припиняє виконання програми та переводить процесор у стан зупинки, вихід з якого відбувається при надходженні сигналів переривання або перезапуску ( Reset). Команда NOP ("порожня" команда), яка не викликає виконання будь-яких операцій, служить для реалізації програмних затримок або заповнення перепусток, що утворилися в програмі.

Спеціальні команди CLI, STI забороняють та дозволяють обслуговування запитів переривання. У процесорах Pentium для цього використовується біт управління (прапор)IFу регістрі EFLAGS.

Багато сучасних мікропроцесорів виконують команду ідентифікації, яка дозволяє користувачеві або іншим пристроям отримати інформацію про тип процесора, який використовується в даній системі. У процесорах Pentuimдля цього служить команда CPUID , при виконанні якої необхідні дані про процесор надходять до регістру EAX,EBX ,ECX ,EDXі потім можуть зчитуватися користувачем або операційною системою.

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

Деякі процесори здійснюють арифметичні операції з двійково-десятковими числами або виконують спеціальні команди корекції результату при обробці таких чисел. До складу багатьох високопродуктивних процесорів входить FPU - блок обробки чисел c "плаваючою точкою".

У ряді сучасних процесорів реалізовано групову обробку кількох цілих чисел чи чисел c "плаваючою точкою" за допомогою однієї команди за принципом SIMD (“Single Instruction – Multiple Data ”) - «Одна команда – Безліч даних». Одночасне виконання операцій над кількома операндами суттєво підвищує продуктивність процесора під час роботи з відео- та аудіоданими. Такі операції широко використовуються для обробки зображень, звукових сигналів та інших програм. Для виконання цих операцій до складу процесорів введені спеціальні блоки, що реалізують відповідні набори команд, які в різних типах процесорів ( Pentium, Athlon) отримали назвуMMX (“ Milti- Media Extension ”) – Мультимедійне Розширення,SSE(“ Streaming SIMD Extension ”) – Потокове SIMD - Розширення, “3 DExtension- Тривимірне розширення.

Характерною рисою процесорів компанії Intel , починаючи з моделі 80286, є пріоритетний контроль при зверненні до пам'яті, який забезпечується під час роботи процесора як захищених віртуальних адрес – – “ Protected Mode ” (захищений режим). Для реалізації цього режиму використовують спеціальні групи команд, які служать для організації захисту пам'яті відповідно до прийнятого алгоритму пріоритетного звернення.

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

Структура команди мовою асемблера Команда асемблера вказує транслятору, яку дію має виконати мікропроцесор. Директиви асемблера - параметри, задані у тексті програми, які впливають процес асемблирования чи властивості вихідного файла. Операнд визначає початкове значення даних (у сегменті даних) або елементи, над якими виконується дія за командою (сегмент коду). Команда може мати один або два операнди, або не мати операндів. Число операндів неявно задається кодом команди. Якщо команду або директиву необхідно продовжити на наступному рядку, використовується символ «зворотний сліш»: «» . За замовчуванням Асемблер не розрізняє великі та малі літери в написанні команд і директив. Приклади директиви та команди Count db 1; Ім'я, директива, один операнд mov eax, 0; Команда, два операнди

Ідентифікатори – послідовності допустимих символів, які використовуються для позначення імен змінних та назв міток. Ідентифікатор може складатися з одного або кількох таких символів: всі літери латинського алфавіту; цифри від 0 до 9; спецсимволи: _, @, $, ? . Як перший символ мітки може використовуватися точка. Як ідентифікатори не можна використовувати зарезервовані імена асемблера (директиви, оператори, імена команд). Першим символом ідентифікатора має бути буква чи спецсимвол. Максимальна довжинаідентифікатор 255 символів, але транслятор сприймає перші 32, інші ігнорує. Усі мітки, які записуються в рядку, що не містить директиви асемблера, повинні закінчуватися двокрапкою «:». Мітка, команда (директива) та операнд не обов'язково повинні починатися з певної позиції в рядку. Рекомендується записувати їх у стовпчик для більшої дочитальності програми.

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

Коментарі Використання коментарів у програмі покращує її ясність, особливо там, де призначення набору команд є незрозумілим. Коментарі починаються на будь-якому рядку вихідного модуля із символу "точка з комою" (;). Усі символи, що знаходяться праворуч від “; » до кінця рядка є коментарем. Коментар може містити будь-які друковані символи, включаючи пробіл . Коментар може займати весь рядок або слідувати за командою на тому ж рядку.

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

Моделі пам'яті Перед оголошенням сегментів необхідно вказати модель пам'яті за допомогою директиви. MODEL модифікатор модель_пам'яті, угода_про_дзвінки, тип_ОС, параметр_стека Основні моделі пам'яті мови асемблера: Модель пам'яті Адресація коду Адресація даних Операційна система Чергування коду та даних TINY NEAR MS-DOS Допустимо SMALL NEAR MS-DOS, Windows Немає MEDIUM FAR NEAR MS-DOS COMPACT NEAR FAR MS-DOS, Windows Ні LARGE FAR MS-DOS, Windows Ні HUGE FAR MS-DOS, Windows Ні NEAR Windows 2000, Windows XP, Windows Допустимо FLAT NEAR NT,

Моделі пам'яті Модель tiny працює тільки в 16-розрядних додатках MS-DOS. У цій моделі всі дані та код розташовуються в одному фізичному сегменті. Розмір програмного файлу у разі не перевищує 64 Кбайт. Модель small підтримує один сегмент коду та один сегмент даних. Дані та код при використанні цієї моделі адресуються як near (ближні). Модель medium підтримує декілька сегментів програмного коду і один сегмент даних, причому всі посилання в сегментах програмного коду за умовчанням вважаються далекими (far), а посилання в сегменті даних - ближніми (near). Модель compact підтримує декілька сегментів даних, у яких використовується дальня адресація даних (far), та один сегмент коду з ближньою адресацією (near). Модель large підтримує декілька сегментів коду та декілька сегментів даних. За замовчуванням усі посилання на код та дані вважаються далекими (far). Модель huge практично еквівалентна моделі пам'яті large.

Моделі пам'яті Модель flat передбачає несегментовану конфігурацію програми і використовується лише в 32-розрядних операційних системах. Ця модель подібна до моделі tiny в тому сенсі, що дані і код розміщені в одному сегменті, тільки 32-розрядному. Для розробки програми моделі flat перед директивою. model flat слід розмістити одну з директив: . 386, . 486, . 586 або. 686. Вибір директиви вибору процесора визначає набір команд, доступних під час написання програм. Літера p після директиви вибору процесора означає захищений режим роботи. Адресація даних та коду є ближньою (near), при цьому всі адреси та покажчики є 32-розрядними.

Моделі пам'яті. MODEL модифікатор модель_пам'яті, угода про виклики, тип_ОС, параметр_стека Параметр модифікатор використовується для визначення типів сегментів і може приймати значення: use 16 (сегменти вибраної моделі використовуються як 16-бітні) use 32 (сегменти обраної моделі використовуються як 32-бітові). Параметр угода_про_дзвінки використовується для визначення способу передачі параметрів при виклику процедури з інших мов, у тому числі і мов високого рівня (C++, Pascal). Параметр може приймати такі значення: C, BASIC, FORTRAN, PASCAL, SYSCALL, STDCALL.

Моделі пам'яті. MODEL модифікатор модель_пам'яті, угода_про_дзвінки, тип_ОС, параметр_стека Параметр тип_ОС дорівнює OS_DOS за замовчуванням, і на даний момент це єдине значення цього параметра, що підтримується. Параметр параметр_стека встановлюється рівним: NEARSTACK (реєстр SS дорівнює DS, області даних і стека розміщуються в тому самому фізичному сегменті) FARSTACK (реєстр SS не дорівнює DS, області даних і стека розміщуються в різних фізичних сегментах). За промовчанням приймається значення NEARSTACK.

Приклад програми, що «нічого не робить». 686 P. MODEL FLAT, STDCALL. DATA. CODE START: RET END START RET – команда мікропроцесора. Вона забезпечує правильне закінчення роботи програми. Решта програми належить до роботи транслятора. . 686 P - дозволено команди захищеного режиму Pentium 6 (Pentium II). Ця директива вибирає підтримуваний набір команд асемблера, вказуючи модель процесора. . MODEL FLAT, stdcall – плоска модель пам'яті. Ця модель пам'яті використовується в операційній системі Windows. stdcall - угода про виклики процедур, що використовується.

Приклад програми, що «нічого не робить». 686 P. MODEL FLAT, STDCALL. DATA. CODE START: RET END START . DATA – сегмент програми, що містить дані. Ця програма не використовує стек, тому сегмент. STACK відсутня. . CODE – сегмент програми, що містить код. START – мітка. END START - кінець програми та повідомлення компілятору, що починати виконання програми треба з мітки START. Кожна програма повинна містити директиву END, що позначає кінець вихідного кодупрограми. Усі рядки, які йдуть за директивою END, ігноруються Мітка, вказана після директиви END, повідомляє транслятор ім'я головного модуля, з якого починається виконання програми. Якщо програма містить один модуль, мітку після директиви END можна не вказувати.

Транслятори мови асемблера Транслятор - програма або технічний засіб, що виконує перетворення програми, представленої однією з мов програмування, на програму цільовою мовою, звану об'єктним кодом. Крім підтримки мнемонік машинних команд, кожен транслятор має власний набір директив і макрозасобів, часто ні з чим не сумісних. Основні види трансляторів мови асемблера: MASM (Microsoft Assembler), TASM (Borland Turbo Assembler), FASM (Flat Assembler) - багатопрохідний асемблер, що вільно розповсюджується, написаний Томашем Гриштаром (польськ.), NASM (Netwide Assembler) - вільний 86, був створений Саймон Тетхем спільно з Юліаном Холл і в даний час розвивається невеликою командою розробників на Source. Forge. net.

Src="https://present5.com/presentation/-29367016_63610977/image-15.jpg" alt="Трансляція програми в Microsoft Visual Studio 2005 1) Створити проект, вибравши меню File->New->Project і"> Трансляция программы в Microsoft Visual Studio 2005 1) Создать проект, выбрав меню File->New->Project и указав имя проекта (hello. prj) и тип проекта: Win 32 Project. В дополнительных опциях мастера проекта указать “Empty Project”.!}

Src="https://present5.com/presentation/-29367016_63610977/image-16.jpg" alt="Трансляція програми в Microsoft Visual Studio 2005 2) У дереві проекту (View->Solution Explorer) додати"> Трансляция программы в Microsoft Visual Studio 2005 2) В дереве проекта (View->Solution Explorer) добавить файл, в котором будет содержаться текст программы: Source. Files->Add->New. Item.!}

Трансляція програми Microsoft Visual Studio 2005 3) Вибрати тип файлу Code C++, але вказати ім'я з розширенням. asm:

Трансляція програми Microsoft Visual Studio 2005 5) Встановити параметри компілятора. Вибрати правою кнопкою у файлі проекту меню Custom Build Rules…

Трансляція програми в Microsoft Visual Studio 2005 і у вікні вибрати Microsoft Macro Assembler.

Трансляція програми в Microsoft Visual Studio 2005 Перевірити правою кнопкою у файлі hello. asm дерева проекту меню Properties і встановити General->Tool: Microsoft Macro Assembler.

Src="https://present5.com/presentation/-29367016_63610977/image-22.jpg" alt="Трансляція програми в Microsoft Visual Studio 2005 6) Відкомпілювати файл, вибравши Build->Build hello. prj."> Трансляция программы в Microsoft Visual Studio 2005 6) Откомпилировать файл, выбрав Build->Build hello. prj. 7) Запустить программу, нажав F 5 или выбрав меню Debug->Start Debugging.!}

Програмування в ОС Windows Програмування в OC Windows ґрунтується на використанні функцій API (Application Program Interface, тобто інтерфейс програмної програми). Їхня кількість досягає 2000. Програма для Windows значною мірою складається з таких викликів. Вся взаємодія з зовнішніми пристроямита ресурсами операційної системи відбувається, як правило, за допомогою таких функцій. Windows використовує пласку модель пам'яті. Адреса будь-якого осередку пам'яті визначатиметься вмістом одного 32-бітного регістру. Можливі 3 типи структур програм для Windows: діалогова (основне вікно - діалогове), консольна або безвіконна структура, класична структура (віконна, каркасна).

Виклик функцій Windows API У файлі допомоги будь-яка функція API представлена ​​у вигляді тип ім'я_функції (ФА 1, ФА 2, ФА 3) Тип – тип значення, що повертається; ФАх – перелік формальних аргументів у порядку їхнього прямування Наприклад, int Message. Box (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); Ця функціявиводить на екран вікно з повідомленням та кнопкою (або кнопками) виходу. Сенс параметрів: h. Wnd -дескриптор вікна, у якому з'являтиметься вікно-повідомлення, lp. Text - текст, який з'являтиметься у вікні, lp. Caption - текст у заголовку вікна, u. Type – тип вікна, зокрема можна визначити кількість кнопок виходу.

Виклик функцій Windows API int Message. Box (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); Практично всі параметри API-функцій насправді 32-бітові цілі числа: HWND - 32-бітне ціле, LPCTSTR - 32-бітний покажчик на рядок, UINT - 32-бітне ціле. До імені функцій часто додається суфікс "А" для переходу до нових версій функцій.

Виклик функцій Windows API int Message. Box (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); При використанні MASM необхідно наприкінці імені додати @N N – кількість байт, що займають у стеку передані аргументи. Для функцій Win 32 API це число можна визначити кількість аргументів n, помножене на 4 (байта у кожному аргументі): N=4*n. Для виклику функції використовується команда CALL асемблера. При цьому всі аргументи функції передаються до неї через стек (команда PUSH). Напрямок передачі аргументів: ЗЛІВА НАПРАВО - ЗНИЗУ Вгору. Першим поміщатиметься у стек аргумент u. Тип. Виклик цієї функції буде виглядати так: CALL Message. Box. [email protected]

Виклик функцій Windows API int Message. Box (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); Результат виконання будь-якої функції API - це, як правило, ціле число, яке повертається в регістрі EAX. Директива OFFSET є «зміщення в сегменті», або, переводячи в поняття мов високого рівня, «покажчик» початку рядка. Директива EQU подібно до #define у ​​мові СІ визначає константу. Директива EXTERN вказує транслятору, що функція або ідентифікатор є зовнішнім по відношенню до цього модуля.

Приклад програми "Привіт усім!" . 686 P. MODEL FLAT, STDCALL. STACK 4096. DATA MB_OK EQU 0 STR 1 DB "Моя перша програма", 0 STR 2 DB "Привіт усім!", 0 HW DD? EXTERN Message. Box. [email protected]: NEAR. CODE START: PUSH MB_OK PUSH OFFSET STR 1 PUSH OFFSET STR 2 PUSH HW CALL Message. Box. [email protected] RET END START

Директива INVOKE Транслятор мови MASM дозволяє спростити виклик функцій з використанням макрозасобу – директиви INVOKE: INVOKE функція, параметр1, параметр2, … При цьому немає необхідності додавати @16 до виклику функції; параметри записуються точно в тому порядку, в якому наведено опис функції. макрозасобами транслятора параметри містяться у стек. Для використання директиви INVOKE необхідно мати опис прототипу функції з використанням директиви PROTO у вигляді: Message. Box. A PROTO: DWORD, : DWORD Якщо у програмі використовується безліч функцій Win 32 API, доцільно скористатися директивою include C: masm 32includeuser 32. inc

Структури в мові асемблер

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

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

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

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

За визначенням структура - Це тип даних, що складається з фіксованого числа елементів різного типу.

Для використання структур у програмі необхідно виконати три дії:

    Задати шаблон структури .

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

    Визначити екземпляр структури .

    Цей етап передбачає ініціалізацію конкретної змінної заздалегідь визначеної структурою.

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

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

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

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

Визначити структуру - отже, дати вказівку транслятору виділити пам'ять і надати цій області пам'яті символічне ім'я.

Описати структуру у програмі можна лише один раз, а визначити – будь-яку кількість разів.

Опис шаблону структури

Опис шаблону структури має наступний синтаксис:

ім'я_структури STRUC

ім'я_структури ENDS

Тут є послідовністю директив опису даних db, dw, dd, dqі dt.

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

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

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

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

Для простоти, щоб уникнути проблем перетворення інформації під час введення, умовимося, що це поля символьні.

Визначимо структуру запису цієї бази даних наступним шаблоном:

Визначення даних із типом структури

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

[ім'я змінної] ім'я_структури

    ім'я змінної- Ідентифікатор змінної цього структурного типу.

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

    список значень- Укладений у кутові дужки список початкових значень елементів структури, розділених комами.

    Його завдання також необов'язкове.

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

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

    Наприклад: victor worker.

Наприклад визначимо кілька змінних із типом описаної вище структури.

Методи роботи із структурою

Ідея введення структурного типу у будь-яку мову програмування полягає у поєднанні різнотипних змінних в один об'єкт.

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

    адресний_вираз- ідентифікатор змінної деякого структурного типу або вираз у дужках відповідно до наведених нижче синтаксичними правилами (рис. 1);

    ім'я_поля_структури- ім'я поля шаблон структури.

    Це, насправді, теж адреса, а точніше, усунення поля від початку структури.

Таким чином оператор " . (точка) обчислює вираз

Мал. 5. Синтаксис адресного виразу оператора звернення до поля структури

Продемонструємо на прикладі певної структури worker деякі прийоми роботи із структурами.

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

Будьте уважні, оскільки через принцип зберігання даних "молодший байт за молодшою ​​адресою"старша цифра віку буде поміщена в al, а молодша - у ah.

Для коригування достатньо використати команду xchg al, ah:

mov ax,word ptr sotr1.age; al вік sotr1

а можна й так:

Подальша робота з масивом структур проводиться так само, як і з одновимірним масивом. Тут виникає кілька запитань:

Як бути з розміром та як організувати індексацію елементів масиву?

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

Після того як став відомий розмір екземпляра структури, організувати індексацію в масиві структур не має особливої ​​складності.

Наприклад:

Як виконати копіювання поля з однієї структури до відповідного поля іншої структури? Або як виконати копіювання всієї структури? Давайте виконаємо копіювання поля namтретього співробітника у полі namп'ятого співробітника:

mas_sotr worker 10 dup ()

mov bx,offset mas_sotr

mov si, (type worker) * 2; si = 77 * 2

mov di, (type worker) * 4; si = 77 * 4

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

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

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

За призначенням можна виділити команди (у дужках наводяться приклади мнемонічних кодів операцій команд асемблера ПК типу 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-бітовий регістр (у тому числі і сегментний) або два осередки пам'яті. Прапори не змінюються.

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

Кожна машинна команда складається із двох частин:

  • операційною – визначальною, «що робити»;
  • операндної - визначальною об'єкти обробки, "з чим робити".

Машинна команда мікропроцесора, записана мовою асемблера, є одним рядком, що має наступний синтатичний вигляд:

мітка команда/директива операнд(и); коментарі

При цьому обов'язковим полем у рядку є команда чи директива.

Мітка, команда/директива та операнди (якщо є) поділяються принаймні одним символом пробілу або табуляції.

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

За замовчуванням мова асемблера не розрізняє великі та малі літери в написанні команд або директив.

Приклади рядків коду:

Count db 1 ;Ім'я, директива, один операнд
mov eax,0 ;Команда, два операнди
cbw; Команда

Мітки

Мітка у мові асемблера може містити такі символи:

  • усі літери латинського алфавіту;
  • цифри від 0 до 9;
  • спецсимволи: _, @, $, ?.

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

Першим символом у мітці має бути буква або спецсимвол (але не цифра). Максимальна довжина позначки – 31 символ. Усі мітки, які записуються в рядку, що не містить директиви асемблера, повинні закінчуватися двокрапкою: .

Команди

Команда вказує транслятору, яку дію має виконати мікропроцесор. У сегменті даних команда (або директива) визначає поле, робочу область чи константу. У сегменті коду команда визначає дію, наприклад, пересилання (mov) або додавання (add).

Директиви

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

Операнди

Операнд – об'єкт, над яким виконується машинна команда чи оператор мови програмування.
Команда може мати один або два операнди, або взагалі не мати операндів. Число операндів неявно задається кодом команди.
Приклади:

  • Немає операндів ret ;Повернутись
  • Один операнд inc ecx; Збільшити ecx
  • Два операнди add eax,12 ;Додати 12 до eax

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

Як операнди можуть виступати

  • ідентифікатори;
  • ланцюжки символів, укладених у одинарні чи подвійні лапки;
  • цілі числа у двійковій, вісімковій, десятковій або шістнадцятковій системі числення.
Ідентифікатори

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

Правила запису ідентифікаторів.

  • Ідентифікатор може складатися з одного або кількох символів.
  • Як символи можна використовувати літери латинського алфавіту, цифри та деякі спеціальні знаки: _, ?, $, @.
  • Ідентифікатор не може починатися символом цифри.
  • Довжина ідентифікатора може бути 255 символів.
  • Транслятор сприймає перші 32 символи ідентифікатора, інші ігнорує.
Коментарі

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

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

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

Приклад програми, яка нічого не робить, мовою асемблера:

686P
.MODEL FLAT, STDCALL
.DATA
.CODE
START:

RET
END START

У цій програмі представлена ​​лише одна команда мікропроцесора. Ця команда RET. Вона забезпечує правильне закінчення роботи програми. У загальному випадку, ця команда використовується для виходу з процедури.
Решта програми належить до роботи транслятора.
.686P - дозволено команди захищеного режиму Pentium 6 (Pentium II). Ця директива вибирає підтримуваний набір команд асемблера, вказуючи модель процесора. Літера P, зазначена в кінці директиви, повідомляє транслятор про роботу процесора в захищеному режимі.
.MODEL FLAT, stdcall - Плоска модель пам'яті. Ця модель пам'яті використовується в операційній системі Windows. stdcall
.DATA - сегмент програми, що містить дані.
.CODE - блок програми, що містить код.
START – мітка. В асемблері мітки відіграють велику роль, що не скажеш про сучасні мови високого рівня.
END START — кінець програми та повідомлення транслятору, що розпочинати виконання програми треба з мітки START .
Кожен модуль повинен містити директиву END , що позначає кінець вихідного програмного коду. Усі рядки, які йдуть за директивою END, ігноруються. Якщо опустити директиву END, то генерується помилка.
Мітка, вказана після директиви END повідомляє транслятору ім'я головного модуля, з якого починається виконання програми. Якщо програма містить один модуль, мітку після директиви END можна не вказувати.




Top