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
Alex Otwagin 2002-12-16
Спонсори:
Хостинг: