- Мова асемблера організовує свої інструкції за призначенням: передача, обчислення, керування потоком тощо.
- Кожна інструкція складається з коду операції та операндів, з різними форматами залежно від архітектури.
- Існує кілька режимів адресації для доступу до даних, таких як негайний, прямий та непрямий.
Мова асемблера була одним із фундаментальних стовпів розробки програмного забезпечення з самого початку обчислювальної техніки. Хоча сьогодні на сцені домінують високорівневі мови програмування, асемблер залишається широко використовуваним та актуальним у середовищах, де пріоритетом є керування обладнанням, оптимізація або обмеження ресурсів.
У цій статті ми заглибимося в типи інструкцій мови асемблера, проаналізувавши їхню структуру, призначення, режими адресації та те, як вони організовані в різних архітектурах. Ви також знайдете приклади, формати та вичерпний огляд, який дозволить вам повністю зрозуміти логіку цих інструкцій, що тісно пов'язані з апаратним забезпеченням.
Що таке інструкція мовою асемблера?
Асемблерна інструкція — це команда, яку процесор може безпосередньо зрозуміти (після того, як її перетворює в машинний код програмою асемблера). Кожна інструкція має певне призначення і зазвичай складається з мнемоніки, яка представляє операцію, та одного або кількох операндів , які вказують, звідки беруться дані та/або де зберігаються результати.
Ці інструкції сильно залежать від архітектури процесора, тому кожен тип процесора (чи то x86, ARM, MIPS тощо) має свій власний набір інструкцій з певним синтаксисом та можливостями.
Структура інструкції
Інструкції зазвичай складаються з двох частин:
- Код операції (опкод): Вказує на дію, яку потрібно виконати, такі як додавання, переміщення даних, порівняння тощо.
Операнди надають інформацію, необхідну для виконання операції, і можуть зберігатися в регістрах, пам'яті або бути константами. Не всі інструкції потребують операндів, а в деяких випадках вони можуть бути неявно присутні в інструкції або зберігатися в попередньо визначених регістрах.
Типи інструкцій мовою асемблера
Залежно від функціональності, яку вони виконують у програмі, інструкції мови асемблера можна класифікувати на кілька груп. Найбільш актуальні з них детально описані нижче:
1. Інструкції щодо передачі даних
Ці інструкції дозволяють копіювати дані з одного місця в інше без зміни їхнього вмісту в джерелі. Вони необхідні для переміщення інформації між регістрами, пам'яттю та периферійними пристроями.
Деякі з найпоширеніших інструкцій у цій групі:
- MOV: Копіює вміст одного операнда в інший. Наприклад,
MOV AX, BXскопіювати вміст BX до AX. - MOVS / MOVSB / MOVSW: Переміщує рядки з адреси джерела (SI) до адреси призначення (DI), автоматизуючи процес передачі.
- LODS / LODSB / LODSW: Завантажує значення з адреси, вказаної регістром SI, в акумулятор (AL або AX).
- ЧИТАЙТЕ: Завантажує ефективну адресу замість значення. Корисно для отримання адреси змінної або структури.
2. Інструкції щодо акумулятора
Стек — це структура LIFO (останній прийшов, перший вийшов), яка використовується для тимчасового зберігання даних, передачі параметрів або збереження контексту виконання.
- PUSH: Зберігає значення в стеку, зменшуючи значення покажчика SP.
- POP: Отримує останнє значення, що зберігається в стеку, збільшуючи SP на одиницю.
- ШТОУК / ПОФП: Вони зберігають та отримують стан прапорців процесора у стеку.
3. Арифметичні та логічні інструкції
Вони дозволяють виконувати обчислення та операції з бітами. Ці інструкції необхідні для маніпулювання числовими даними та прийняття рішень у процесі виконання програми.
Серед найбільш використовуваних ми знаходимо:
- ДОДАТИ / ПІДПИСАТИ: Додавання та віднімання.
- МУЛ / ІМУЛ: Множення двійкових чисел.
- DIV / IDIV: Ділення (ціле або зі знаком).
- І / АБО / XOR / НІ: Побітові логічні операції.
- ШЛ / ШР / РОЛ / РОР: Зміщення та обертання бітів.
4. Інструкції з керування потоком
Вони дозволяють змінювати послідовність виконання програми , вводячи переходи або умовні та безумовні виклики інших інструкцій.
- ЖМП: Безумовно переходить на іншу адресу в програмі.
- ВИКЛИК / ПОВЕРНЕННЯ: Виклик підпрограми та повернення.
- JE/JNE/JG/JL/JZ/JNZ: Умовні переходи, вони виконуються, якщо виконуються певні умови (після порівняння).
5. Інструкції введення/виведення (I/O)
Вони забезпечують зв'язок між процесором та зовнішніми пристроями. Ці інструкції дозволяють зчитувати та записувати дані на/з портів (апаратне забезпечення).
- IN: Зчитує дані з вхідного порту.
- ЗНО: Надсилає дані на вихідний порт.
6. Інструкції з плаваючою комою
Багато процесорів мають математичні співпроцесори (або спеціальні інструкції), призначені для роботи з десятковими числами (числами з плаваючою комою). Ці інструкції дозволяють виконувати такі операції, як:
- Додавання, віднімання, множення та ділення дійсних чисел.
- Тригонометричні операції (синус, косинус, тангенс).
- Логарифмічні, експоненціальні та кореневі операції.
Ці інструкції зазвичай відповідають стандарту IEEE 754 щодо числової точності.
Режими адресації
Фундаментальною частиною проектування інструкцій є те, як визначається розташування операндів. Режими адресації визначають, як процесор отримує доступ до даних.
1. Негайне звернення
Дані включаються безпосередньо в інструкцію. Це швидко, але не дозволяє змінювати значення без зміни інструкції.
MOV AX, 5
2. Пряма адресація
Адреса пам'яті, що містить дані, вказується явно.
MOV AX,
3. Непряма адресація
Ефективна адреса отримується з вмісту запису. Дуже гнучка та використовується для структур та зв'язаних списків.
MOV AX,
4. Індексована адресація
Адреса обчислюється шляхом додавання бази та індексу (наприклад, для обходу масивів). Для цього використовуються спеціальні регістри, такі як SI, DI або регістри бази + зміщення.
MOV AX,
Формати інструкцій: різні типи залежно від архітектури
Структура інструкції може відрізнятися залежно від архітектури. Поширені формати включають:
4-сторонній формат
Він містить два операнди, розташування результату та адресу наступної інструкції. Зараз він застарів через свою складність.
3-сторонній формат
Він визначає два операнди та адресу призначення. Це поширено в сучасних RISC-архітектурах.
2-сторонній формат
Використовуйте операнд джерела та операнд призначення (операнд призначення також може вносити певний внесок). Популярний на x86 та інших CISC архітектурах.
Односторонній формат
Визначається лише один операнд; інший вважається акумулятором. Поширений у старіших процесорах та простих системах.
Формат 0-адреси (на основі стеку)
Операції використовують стек для вибору та зберігання операндів і результатів. Дуже ефективно для машин на основі стеку, таких як деякі програмовані калькулятори.
Макрокінструкції та псевдокоди операцій
Для підвищення продуктивності багато асемблерів пропонують макроінструкції , які розширюють один рядок на кілька фактичних інструкцій. Вони корисні для уникнення повторення складних шаблонів або для створення високорівневих структур, таких як цикли чи умовні оператори.
L псевдо-коди операцій Це інструкції, які асемблер перетворює внутрішньо в реальну послідовність інструкцій. Наприклад, NOP (без операції) можна перекласти як XCHG AX, AX на процесорі x86.
Директиви асемблера
Директиви ( також звані псевдоопераціями ) не є інструкціями у строгому сенсі. Вони служать для керування процесом асемблювання, визначення даних, розділів коду, макросів, умов компіляції тощо.
Загальні приклади:
- .дані / .код: Вони вказують на розділ даних або коду.
- .org: Встановлює адресу, з якої почнеться збірка.
- .equ: Визначає символьні константи.
Випадки використання мови асемблера
Незважаючи на зростання популярності мов високого рівня, мова асемблера залишається ключовою в кількох областях:
- Розробка вбудованих систем та мікроконтролерів.
- Програмування драйверів, завантажувачів та BIOS.
- Екстремальна оптимізація в таких додатках, як відеоігри або криптографія.
- Зворотне проектування, налагодження та низькорівневий хакінг.
Крім того, навчання мові асемблера все ще займає важливе місце в галузі інформатики та електроніки, оскільки воно забезпечує глибоке розуміння того, як працює процесор, як зберігаються та обробляються дані, а також як виконуються інструкції на двійковому рівні.
Розуміння всіх типів інструкцій асемблерного програмування, їхньої структури, функціональності та режимів адресації забезпечує міцну основу для будь-якого програміста, який хоче заглибитися в низькорівневе програмування або зрозуміти, як мови високого рівня зрештою транслюються в машинний код. Хоча його використання стало більш специфічним, він залишається важливим інструментом у багатьох критично важливих сферах розробки програмного забезпечення та систем.