Знайомство з асемблером

556 Глава 7. Рівень асемблера

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

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

Що таке «мова асемблера»?

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

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

Знайомство з асемблером 557

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

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

призначення асемблера

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

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

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

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

558 Глава 7. Рівень асемблера

Формат операторів в асемблері

Хоча структура ассемблерного оператора відображає структуру відповідної машинної команди, мови асемблера для різних машин і різних рівнів багато в чому схожі, що дає підстави говорити про мову асемблера в цілому. У лістингах 7.1-7.3 наведено фрагмент програми на асемблері x86, що обчислює формулу N = I + J. Оператори під символом нового рядка резервують пам'ять для змінних I. J і N. тобто не є символьними уявленнями машинних команд.

Лістинг 7.1. Обчислення виразу N = I + Jна асемблері x86

; і їх ініціалізація значенням 0

Для комп'ютерів сімейства Intel (тобто x86) існують кілька ассемблеров, які відрізняються один від одного синтаксисом. У цьому розділі ми будемо використовувати мову асемблера Microsoft MASM. Також існує чимало ассемблеров для процесорів ARM, але за своїм синтаксису вони близькі до асемблеру x86, тому одного прикладу має бути достатньо.

У лістингу прикладу присутні мітки: FORMULA, I, J і N. У асемблері MASM двокрапка ставиться тільки після міток команд, але не після міток даних. Дана відмінність зовсім не є чимось фундаментальним, просто

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

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

У кожній машині є кілька регістрів, але назви у них абсолютно різні. Регістри Core i7 називаються EAX, EBX, ECX і т. Д.

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

Знайомство з асемблером 559

різні розробники називають їх по-різному. Розробники асемблера MASM вирішили використовувати позначення MOV і для завантаження регістра з пам'яті, і збереження регістра в пам'ять. З таким же успіхом вони могли використовувати MOVE в парі з LOAD або STORE.

Програмами на мові асемблера часто потрібно резервувати простір для даних. Розробники MASM вибрали для цієї операції назва DD (Define Double - визначити подвійне слово), оскільки слово процесора 8088 мало довжину 16 біт.

Асемблерна програма визначає не тільки машинні команди, які потрібно виконувати процесору, але і команди, які потрібно виконувати самому асемблеру (наприклад, виділити трохи пам'яті або видати нову сторінку лістингу). Команди для асемблера називаються псевдокоманди. або асемблерними директивами. У лістингу 7.1 ми вже зустрічали типову псевдокоманди DD. У табл. 7.1 перераховані деякі інші псевдокоманди (директиви) асемблера MASM для платформи x86.

Таблиця 7.1. Деякі директиви асемблера MASM

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

Директива EQU дає символічну назву деякого виразу. Наприклад, після наступної Директиви символ BASE можна використовувати в програмі замість значення 1000:

Вираз, який слідує за директивою EQU. може містити кілька символів, з'єднаних знаками арифметичних та інших операцій, наприклад:

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

Директиви DB. DD. DW і DQ виділяють пам'ять для однієї або декількох змінних розміром 1, 2, 4 і 8 байт відповідно. наприклад:

TABLE DB 11, 23, 49

Директиви PROC і ENDP визначають початок і кінець асемблерних процедур. Процедури в асемблері виконують ту ж роль, що і в мовах програмування високого рівня. Директиви MACRO і ENDM визначають початок і кінець макросу. Про макросах ми поговоримо в наступному розділі.

Схожі статті