Асемблери gas і nasm


Next: Усунення несправностей GDB Up: Засоби програмування в ОС Previous: Основні групи системних функцій Contents Index

Використання мови асемблера в Linux відбувається набагато рідше, ніж, наприклад, в DOS. Драйвери пристроїв в Linux набагато частіше пишуться на мові C, а потім обробляються компілятором з оптимізацією, наприклад, GCC. Однак, якщо Вам неодмінно потрібно асемблер, можливість його використання присутній.

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

GAS - це скорочення від GNU Assembler. Оскільки GAS був розроблений для підтримки 32-бітних компіляторів Unix, він використовує стандартний синтаксис AT & T, який дещо відрізняється від звичайного асемблера DOS. Основні відмінності синтаксису GAS від синтаксису Intel:

  • Імена регістрів починаються з символу%, тобто% eax,% dl, замість eax, dl, і т.д. Це дозволяє включати в код зовнішні змінні C, не побоюючись помилок і не використовуючи префіксів з підкресленням (_).
  • Порядок операндів - спочатку джерело, потім приймач, а не навпаки, як в синтаксисі Intel. Тому, команда в синтаксисі Intel mov eax, edx (передати вміст регістра edx в регістр eax) буде виглядати в GAS як mov% edx,% eax.
  • Розмір операнда визначається як суфікс імені інструкції. Суфікс b використовується для (8-bit) байта, w для (16-bit) слова, і l для (32-bit) подвійного слова. Наприклад, правильна інструкція в попередньому прикладі буде movl% edx,% eax. Однак, gas не вимагає дотримання суворого синтаксису AT & T, так що суфікс необов'язковий, якщо розмір може бути визначений для реєстрового операнда, або за замовчуванням приймається 32-bit.
  • Константи оптмечаются префіксом $, наприклад, addl $ 5,% eax (додати константу 5 до регістру% eax).
  • Відсутність префікса операнда вказує на адресу в пам'яті; тому movl $ foo,% eax поміщає адресу змінної foo в регістр% eax, а movl foo,% eax поміщає в% eax вміст змінної foo.

Індексація виконується за допомогою укладення індексного регістра в дужки, наприклад, in testb $ 0x80,17 (% ebp) (перевірити установку старшого біта в байті по зсуву 17 від осередку, зазначеної% ebp).

Примітка: Існує кілька програм, які можуть допомогти Вам перетворити вихідний код для ассемблеров AT & T і Intel; деякі з них здатні на перетворення в двох напрямках.

Асемблер NASM розробляється в рамках The Netwide Assembler project, і являє собою потужний асемблер на базі i386, написаний на C, який побудований за модульним принципом і забезпечує підтримку практично вссех відомих синтаксисів і форматів об'єктних файлів.

Використовується синтаксис Intel. Підтримується обробка макроозначень.

Серед підтримуваних форматів об'єктних файлів є bin, aout, coff, elf, as86, obj (DOS), win32, rdf (власний формат). Крім того, NASM поставляється з дизассемблером NDISASM.

Як і для GAS, для NASM існує кілька програм для проебразованія синтаксису.

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

Програма зазвичай ділиться на розділи: .text - для програмного коду (тільки для читання), .data - для запису даних (читання-запис), .bss - для неініціалізіруемих даних (читання-запис); можуть також бути присутнім і інші стандартні розділи, а також розділи, визначені користувачем. У програмі повинен бути присутнім як мінімум розділ .text.

Приклад для NASM (hello.asm)

section .data; опис розділу msg db "Hello, world!", 0xa; виводиться рядок len equ $ - msg; довжина рядка section .text; опис розділу; нам потрібно передати точку входу компонувальнику або global _start; завантажувачу ELF. Зазвичай вони розпізнають _start за замовчуванням. ; Використовуйте ld -e foo, щоб перевизначити її. _start:; записуємо рядок в стандартний висновок mov edx, len; третій аргумент: довжина рядка mov ecx, msg; другий аргумент: покажчик на рядок mov ebx, 1; перший аргумент: дескриптор файлу (stdout) mov eax, 4; номер системного виклику (sys_write) int 0x80; звернення до ядру; і виходимо mov ebx, 0; перший аргумент: код повернення mov eax, 1; номер системного виклику (sys_exit) int 0x80; звернення до ядру

Приклад для GAS (hello.S)

.data # опис розділу msg: .string "Hello, world! \ n" # виводиться рядок len =. - msg # довжина рядка .text # опис розділу # нам потрібно передати точку входу компонувальнику або global _start # завантажувачу ELF. Зазвичай вони розпізнають _start за замовчуванням. # Використовуйте ld -e foo, щоб перевизначити її. _start: # записуємо рядок в стандартний висновок movl $ len,% edx # третій аргумент: довжина рядка movl $ msg,% ecx # другий аргумент: покажчик на рядок movl $ 1,% ebx # перший аргумент: дескриптор файлу (stdout) movl $ 4, % eax # номер системного виклику (sys_write) int $ 0x80 # звернення до ядру # і виходимо movl $ 0,% ebx # перший аргумент: код повернення movl $ 1,% eax # номер системного виклику (sys_exit) int $ 0x80 # звернення до ядру

Основні опції асемблера GAS:

--defsym sym = value

Визначає символом sym величину value перед розбором вхідного файлу. value має бути цілою константою. Як і в C, префікс 0x визначає шестнадцатиричное число, а префікс 0 - вісімкове.

--help

Виводить список опцій командного рядка.

-I dir

Додати каталог dir в список пошуку для директив `.include '.

-o objfile

Ім'я об'єктного файлу для виведення з `as '.

-R

Розпізнавати вкладені в код розділи даних.

--no-warn

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

--fatal-warnings

Розглядати попередження як помилки.

Основні опції асемблера NASM: -h

Виведення інформації про опції і підтримуваних форматах вихідних файлів nasm.

-a

Ассембліровать файл без попереднього препроцессінга.

-e

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

-M

Вивести в stdout залежності в стилі make-файлу.

-E filename

Перенаправляти повідомлення про помилки в файл filename. Опція призначена для операційних систем, в яких stderr не можна перенаправити.

-f format

Визначити формат вихідного файлу. Формати включають в себе bin для плоских довічних файлів, і aout або elf для створення об'єктних фалів типу Linux a.out і ELF, відповідно.

-o outfile

Визначити точний ім'я вихідного файлу, перевизначивши ім'я за замовчуванням.

-l listfile

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

-s

Виводити повідомлення про помилки в файл стандартного виводу.

-w [+ -] foo

Підключити або відключити деякі класи попереджувальних повідомлень, наприклад, -w + orphan-labels або -w-macro-params, щоб, відповідно, дозволити повідомлення про мітки в порожній рядку або відключити повідомлення про невірний кількості параметрів у викликах макросів.

-I directory

Додати каталог в шлях пошуку включення файл.

Next:  Усунення несправностей GDB Up:  Засоби програмування в ОС Previous:  Основні групи системних функцій   Contents   Index
Next: Усунення несправностей GDB Up: Засоби програмування в ОС Previous: Основні групи системних функцій Contents Index

Alex Otwagin 2002-12-16

Спонсори:

Хостинг: