dementiy 20.05.2010 01:27
Coding — Ассемблер в Linux. Инструменты
Вместо введения"... Ассемблер - это язык процессора и, следовательно, он будет нужен до тех пор, пока будут существовать процессоры... Программирование на ассемблере дает ощущение власти над компьютером, а жажда власти - один из сильнейших инстинкотов человека" - Пирогов В.Ю. (на обороте книги "Ассемблер для Windows" :-))
Для чего изучать ассемблер в Linux? Это хороший вопрос и мне трудно на него ответить. Можно было бы сказать, что ассемблер нужен для более глубокого понимания работы железа, ядра ОС (или самих ОС, например KolibriOS), увеличения производительности программ (хотя конечно в первую очередь надо попробовать выбрать наиболее оптимальный алгоритм), а можно сказать проще "Just for fun". Поэтому оставим этот вопрос без ответа (или с ответом, но в комментариях). В этой небольшой статье я хотел бы упомянуть о некоторых инструментах на пути к "безумию" :-)
Все необходимые инструменты, которые нам понадобятся уже присутствуют в вашей системе, а именно:
GAS (GNU Assembler)
LD (GNU Linker)
GCC (GNU Compiler Collection)
GDB (GNU Debugger)
Для того, чтобы показать как они работают напишем простую программу, которая ничего не делает, разве что завершает свою работу:
1 |
#example.s
|
Используя GAS и GNU linker получим исполняемый файл:
$ as example.s -o example.o
$ ld example.o -o example
Если вы вносите какие-либо изменения в программу, то ее необходимо заново ассемблировать (as) и линковать (ld)
При необходимости можно включить листинг в вывод результатов работы ассемблера при помощи ключа -a:
$ as -a example.s -o example.o
Рис. 1. Вывод листинга
Если листинг получается довольно большим, то вывод можно перенаправить в отдельный файл: as -a example.s -o example >> listing
Теперь запустим программу на выполнение и посмотрим на результат ее работы:
$ ./example
$ echo $?
0
$
Наша программа ничего выводит, поэтому мы не должны видеть каких-либо сообщений. Мы можем только посмотреть действительно ли системный вызов exit вернул 0 (echo $?).
Вы можете поэкспериментировать с возвращаемым значением, оно может находиться в диапазоне от 0 до 255 (FF)
Запустим программу в отладчике ALD (Assembly Language Debugger) (не торопитесь его устанавливать, ниже будет объяснено почему):
Рис. 2. Отладчик ALD
По первой же инструкции (mov eax, 0x1) вы можете заметить, что она несколько отличается от той, которая у нас в программе (movl $1, %eax). Дело в том, что мы используем синтаксис AT&T;, а в отладчике используется синтаксис Intel, отсюда и различие. ALD удобно использовать в том случае, если вы используете ассемблер с синтаксисом Intel, например NASM.
Для того, чтобы запустить нашу программу в GDB ее необходимо ассемблировать с флагом -gstabs, который включает отладочную информацию в исполняемый файл (в противном случае в GDB будет выведена надпись «No debugging symbols found»), а также добавить инструкцию nop (инструкция nop — No Operation, ничего не делает, ее добавление в код связано с багом в GDB):
1 |
|
$ as -gstabs example.s -o example.o
$ ld example.o -o example
Если не добавить инструкцию nop, то GDB всегда будет проскакивать breakpoint, завершая работу программы
Теперь все готово для запуска программы в GDB:
Рис. 3. Отладчик GDB
b (break) адрес — устанавливает точку, где программа должна приостановить свое выполнение;
r (run) — запускает программу на выполнение, программа работает до тех пор пока не встретит breakpoint или не завершит свою работу;
s (step) — пошаговый режим выполнения инструкций.
Для того, чтобы просмотреть содержимое всех основных регистров, используется команда i r (info registers), если необходимо просмотреть только определенные регистры, то их можно перечислить через пробел: i r eax ebx.
Вместо GAS+LD можно использовать GCC, тогда в программе необходимо заменить _start на main (инструкцию nop можно убрать, так как у GDB «непонятки» только с GAS):
1 |
|
$ gcc -g example.s -o example
Флаг -g аналогично -gstabs включает отладочную информацию в исполняемый файл. В GDB теперь breakpoint можно указывать «по человечески»: (gdb) b main
В GCC и GAS можно использовать, как флаг -g, так и флаг -gstabs. Флаг -g включает дополнительную отладочную информацию специально для GDB.
Упомяну еще об одном инструменте, который может пригодиться — это HT. С сайта: «HT is a file editor/viewer/analyzer for executable». У HT довольно богатые возможности (он собой заменяет некоторые утилиты из пакета binutils, такие как objdump, readelf, nm и др.), поэтому рекомендую с ними ознакомиться на сайте и поэкспериментировать самостоятельно. Единственный «минус» HT заключается в том, что он отображает образ программы в стиле синтаксиса Intel:
$ ht example
Рис. 4. HT Editor
Еще одна «загвоздка» в том, что если использовался GCC, то в исполняемом файле много дополнительной информации, это можно легко увидеть хотя бы сравнив размеры программы, полученной при помощи GAS с размером программы, которую мы получили при помощи GCC:
Рис. 5. Сравнение размеров программ
Если вы собрали программу, используя GCC, то для того, чтобы в HT быстро перейти к функции main можно нажать F5 (goto), затем написать ее адрес (можно так и писать main), затем Ok.
Напоследок, можно использовать любой текстовый редактор для набора кода. Я использую Gedit. Вот пара цветовых схем (одна для синтаксиса Intel, вторая для синтаксиса AT&T;):
Intel
AT&T;P.S. Первое - pdf с текстом статьи. Второе - был замысел сделать серию небольших статей о ассемблере в Linux (на базе того, что я уже знаю и на базе того, что еще изучу). Но сейчас довольно туго со временем. Может быть кто-то подхватит эту идею (например пользователь mrded). И последнее, если Вы заметите в статье какие-либо ошибки (что вполне возможно), то пожалуйста напишите об этом.
chemikadze 20.05.2010 01:45 #
+ 0 -
Когда-то давно пробовал учить асм по Калашникову, сейчас все забыл, да и речь в книге шла про DOS и MASM, поэтому почитать здесь про ассемблер в linux будет интересно =)
> Вы можете поэкспериментировать с возвращаемым значением, оно может находиться в диапазоне от 0 до 255 (FF)
Странно, я думал, что оно типа int. Ну, типа как int main, знаете ли :)
> был замысел сделать серию небольших статей о ассемблере в Linux
Обязательно продолжай, интересно :)
Странно, я думал, что оно типа int. Ну, типа как int main, знаете ли :)
> был замысел сделать серию небольших статей о ассемблере в Linux
Обязательно продолжай, интересно :)
Все верно - int. Я имел ввиду, что само значение (которое мы указываем либо в return, либо в exit - код возврата или код ошибки) должно быть в диапазоне от 0 до 255. Вы можете указать 256, но восприниматься оно будет как 0 (257 - 1, 258 - 2 и т.д.).
Когда-то изучал асм под виндовс, интересно было узнать как все работает по в линуксе. Спасибо за статью, с удовольствием почитал бы еще :)
Асм штука полезная, но что-то как-то никому нет до него дела в последнее время :(
WASM.RU и тот уже почти загнулся, статей 2 года как нет... Эх.
WASM.RU и тот уже почти загнулся, статей 2 года как нет... Эх.
Вот это я понимаю, пост. Мегакруто. Хоть я и не программер, почитать было очень интересно. Жду продолжения.
Спасибо, я как раз искала информацию про асм под линукс, только-только начала вникать.
Продолжай писать обязательно, буду с интересом читать :)
Продолжай писать обязательно, буду с интересом читать :)
А если не секрет, то с какой целью Вы решили изучать ассмеблер (для себя, по учебе, по работе и т.д.)?
Я люблю интеловский синтаксис, как в FASM. http://flatassembler.net/download.php
Продолжайте в том же духе! А если кому интересно более фундаментальное изучение сабжа то можно почитать "Guide to Assembly Language Programming in Linux" за авторством Sivarama P. Dandamudi
mealsforall +100500 за FASM ,) Воистину лучший макроассемблер. Используйте его, я например не понимаю, как это, писать на асме и получать программы по 6кб(при использовании иного макроассемблера и линкера), с фасмом же, программы будут от примерно 150 байт.
Отладчик рекомендую radare, лучшее что я видел под GNU\Linux. Можно и edb(жалкое подобие OllyDbg) попробовать, трейсить вроде умеет.
Вместо всяких книжек\учебников и прочей фигни(я не хочу никого обидеть, просто авторы этих творений редко затрагивают многие интересные вещи и формы\особенности инструкций) качаем Intel Manuals и изучаем, там есть всё, от описания архитектуры до рекомендаций к оптимизации. А главное — нет воды.
Удачи Вам в изучении!
Отладчик рекомендую radare, лучшее что я видел под GNU\Linux. Можно и edb(жалкое подобие OllyDbg) попробовать, трейсить вроде умеет.
Вместо всяких книжек\учебников и прочей фигни(я не хочу никого обидеть, просто авторы этих творений редко затрагивают многие интересные вещи и формы\особенности инструкций) качаем Intel Manuals и изучаем, там есть всё, от описания архитектуры до рекомендаций к оптимизации. А главное — нет воды.
Удачи Вам в изучении!