27 December 2009

Разработка на ассемблере в Linux

Lumber room
Вообще программирование на ассемблере в Linux мало распространено и занимаются им, разве что, фанаты ассемблера. Сегодня мы и поговорим о программировании на ассемблере и инструментарий.Что нам понадобится:
  • 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

image

Мы видим всю нашу программу, данные, elf-заголовок. Неплохо? Теперь мы посмотрим на нашу программу в отладчике. Наберем в консоли:

ald hello

Нас должна поприветствовать строка с предложением ввести команду. Список команд вы можете узнать, набрав help или получить помощь по отдельной команде, набрав help command. Дизассемблировать нашу программу можно командой disassemble (или ее алиас — "d"). Вы увидете дизассемблированный листинг вашей программы. Слева — адрес, справа — сама команда, а посередине — опкод команды.

Получить дамп можно командой dump (странно, но ее нет в выводе команды help).

image

Теперь попробуем поработать с командой next. Выполните ее и в ответ вам покажут значения регистров, установленные флаги, а так же адрес, опкод и дизассемблированную команду, которая должна выполниться следующей. Попробуйте выполнять команды и следите за изменением флагов и регистров. После вызова первого прерывания у вас на экране должна появиться надпись «Hello world!».

Целью данной статьи было показать основы программирования на ассемблере в linux, а не программирования на ассемблере в общем. Надеюсь, что вы подчерпнули для себя что-то полезное от сюда.

PS. Первая статья на хабре.

Полезные ссылки


asm.sourceforge.net
www.int80h.org
Tags: ассемблер fasm linux
Hubs: Lumber room
+23
2.5k 25
Comments 19
Ads
Top of the day