Вообще программирование на ассемблере в Linux мало распространено и занимаются им, разве что, фанаты ассемблера. Сегодня мы и поговорим о программировании на ассемблере и инструментарий.Что нам понадобится:
Собственно каждый для себя выбирает инструменты сам. Я выбрал для себя эти.
После загрузки архива с офф. сайта распакуем его:
В папке у нас будет бинарный файл fasm, который мы можем использовать для компиляции. Для удобства вы можете создать симлинк на него:
ald и shed устанавливаются не сложнее:
В итоге у нас будет 3 полезных инструмента для программирования на ассемблере.
Как и большинство других операционных систем, Linux предоставляет т.н. API — набор полезных для программиста функций. В большинстве случаев вызов системной функции производится с помощью прерывания 80h. Следует отметить, что Linux используется fastcall-конвенция передачи параметров. Согласно ей параметры передаются через регистры (в windows, например, используется stdcall, где параметры передаются через стек). Номер вызываемой функции кладется в eax, а параметры в регистры:
Номер параметра / Регистр
1 / ebx
2 / ecx
3 / edx
4 / esi
5 / edi
6 / ebp
Как видите все не так сложно. Узнать номер системной функции, ее описание и параметры можно, хотя бы здесь. Возьмем, к примеру
Надеюсь, что все понятно.
Ну что же. Писать мы ничего не будем, т.к. за нас все написано :) В папке
Как видите здесь вызываются 2 системных функции —
Думаю, что самое время заглянуть в наш бинарник. Для начала воспользуемся шестнадцатеричным редактором, чтобы посмотреть что у нас получилось. Выполним команду:
Мы видим всю нашу программу, данные, elf-заголовок. Неплохо? Теперь мы посмотрим на нашу программу в отладчике. Наберем в консоли:
Нас должна поприветствовать строка с предложением ввести команду. Список команд вы можете узнать, набрав
Получить дамп можно командой
Теперь попробуем поработать с командой
Целью данной статьи было показать основы программирования на ассемблере в linux, а не программирования на ассемблере в общем. Надеюсь, что вы подчерпнули для себя что-то полезное от сюда.
PS. Первая статья на хабре.
asm.sourceforge.net
www.int80h.org
- FASM. Берем на flatassembler.net версию для Linux
- ald. Берем на ald.sourceforge.net
- shed. Берем на shed.sourceforge.net
- ld. Есть в большинстве дистрибутивов
Собственно каждый для себя выбирает инструменты сам. Я выбрал для себя эти.
Установка FASM
После загрузки архива с офф. сайта распакуем его:
tar zxvf fasm-1.69.11.tgz
В папке у нас будет бинарный файл fasm, который мы можем использовать для компиляции. Для удобства вы можете создать симлинк на него:
sudo ln -s /home/username/fasm/fasm /usr/local/bin
ald и shed устанавливаются не сложнее:
$ ./configure
$ make
# make install
В итоге у нас будет 3 полезных инструмента для программирования на ассемблере.
Системные вызовы
Как и большинство других операционных систем, Linux предоставляет т.н. API — набор полезных для программиста функций. В большинстве случаев вызов системной функции производится с помощью прерывания 80h. Следует отметить, что Linux используется fastcall-конвенция передачи параметров. Согласно ей параметры передаются через регистры (в windows, например, используется stdcall, где параметры передаются через стек). Номер вызываемой функции кладется в eax, а параметры в регистры:
Номер параметра / Регистр
1 / ebx
2 / ecx
3 / edx
4 / esi
5 / edi
6 / ebp
Как видите все не так сложно. Узнать номер системной функции, ее описание и параметры можно, хотя бы здесь. Возьмем, к примеру
sys_exit
. Как можно увидеть на той странице у нее есть один параметр — код возврата и она имеет порядковый номер 1. Таким образом мы можем вызвать ее следующим кодом:mov eax, 1 ; 1 - номер системной функции
sub ebx, ebx ; Обнуляем регистр (можно было записать mov ebx, 0)
int 80h ; Вызываем прерывание 80h
Надеюсь, что все понятно.
Hello, World!
Ну что же. Писать мы ничего не будем, т.к. за нас все написано :) В папке
fasm/examples/elfexe
есть файл hello.asm, в котором находится следующий код:; fasm demonstration of writing simple ELF executable
format ELF executable 3
entry start
segment readable executable
start:
mov eax,4
mov ebx,1
mov ecx,msg
mov edx,msg_size
int 0x80
mov eax,1
xor ebx,ebx
int 0x80
segment readable writeable
msg db 'Hello world!',0xA
msg_size = $-msg
Как видите здесь вызываются 2 системных функции —
sys_write
(с порядковым номером 4) и sys_exit
. sys_write
принимает 3 параметра — дескриптор потока вывода (1 — stdout), указатель на строку и размер строки. Сам номер функции, как уже говорилось, мы должны положить в eax. Функцию sys_exit
мы уже разобрали. Скомпилировать это чудо можно так: fasm hello.asm
(но не обязательно, т.к. там же, где лежит исходник, есть и бинарник).Посмотрим, что внутри
Думаю, что самое время заглянуть в наш бинарник. Для начала воспользуемся шестнадцатеричным редактором, чтобы посмотреть что у нас получилось. Выполним команду:
shed hello
Мы видим всю нашу программу, данные, elf-заголовок. Неплохо? Теперь мы посмотрим на нашу программу в отладчике. Наберем в консоли:
ald hello
Нас должна поприветствовать строка с предложением ввести команду. Список команд вы можете узнать, набрав
help
или получить помощь по отдельной команде, набрав help command
. Дизассемблировать нашу программу можно командой disassemble
(или ее алиас — "d
"). Вы увидете дизассемблированный листинг вашей программы. Слева — адрес, справа — сама команда, а посередине — опкод команды.Получить дамп можно командой
dump
(странно, но ее нет в выводе команды help
).Теперь попробуем поработать с командой
next
. Выполните ее и в ответ вам покажут значения регистров, установленные флаги, а так же адрес, опкод и дизассемблированную команду, которая должна выполниться следующей. Попробуйте выполнять команды и следите за изменением флагов и регистров. После вызова первого прерывания у вас на экране должна появиться надпись «Hello world!».Целью данной статьи было показать основы программирования на ассемблере в linux, а не программирования на ассемблере в общем. Надеюсь, что вы подчерпнули для себя что-то полезное от сюда.
PS. Первая статья на хабре.
Полезные ссылки
asm.sourceforge.net
www.int80h.org