Вы не зашли.
Часто задаваемые вопросы по использованию ассемблера в юниксах.
Прим.:
○ Далее под термином "юникс" подразумеваются такие операционные системы как FreeBSD, Linux и тп.
○ Данный FAQ ориентирован на русскоязычных пользователей.
○ Изначальный адрес этого документа в интернет http://stakanov.nm.ru/as/asm_unix_faq.html
○ Составители:A.STAKANOV, rgo с форума WASM.UNIX, cresta с форума WASM.UNIX
○ Особая благодарность участникам фидошной эхи RU.UNIX.PROG
○ Использованы материалы с сайта http://wasm.ru
○ Последние изменения: 25.11.2005 01:39 MSK
Q: Какие ассемблеры бывают в юникс и где их взять?
A:
• AS: Во FreeBSD as и все утилиты из пакета binutils присутвуют в системе по умолчанию. В Linux потребуется дополнительно установить пакет binutils (формат пакета зависит от дистрибутива) или скачать его с ftp://ftp.gnu.org/gnu/binutils/.
• NASM: Во FreeBSD установите порт /usr/ports/devel/nasm/. В Linux установите из соответвующего пакета или скачайте с сайта http://www.kernel.org/pub/software/devel/nasm/ (или http://sourceforge.net/projects/nasm/).
• FASM: Скачайте с официального сайта http://www.flatassembler.net/
Важно! AS использует синтаксис AT&T, а NASM и FASM синтаксис Intel.
Q: У юникса есть API ?
A: Да. Называется это системные вызовы (syscalls). Осуществляются они путем вызова прерывания номер 0x80. Кроме того, практически везде действует "lcall $7,$0" ("call 7:0" в синтаксисе интел) как его полный аналог. Так же в системе обязательно присутствует библиотека libc.
Q: Как передаются параметры системных вызовов?
A: Во FreeBSD параметры передаются через стек, сначала последний, затем предпоследний и первый параметр помещается в стек последним. Так же при испотьзовании прерывания необходимо поместить в стек любое 32-битное значение. В Linux через регистры по порядку первый в EBX, и тд - ECX, EDX, ESI, EDI, EBP. Если количество параметров больше 6, то в памяти формируется структура с параметрами и в EBP помещается адрес этой стурктуры. В EAX в обоих случаях номер системного вызова. Если хотите использовать функции из libc, то передача параметров при этом осуществляется так как принято в Си (в мире Windows такой способ известен как CDECL). Результат всегда возвращается в EAX.
Q: Где узнать номера системных вызовов?
A: Самый простой способ для FreeBSD(должны быть установлены исходники системы!) - смотреть файл /usr/srs/sys/kern/syscalls.master. Там и номера и параметры. Способ для Linux - /usr/src/linux/arc/i386/kernel/syscall_table.S или файл entry.S из того же каталога для версий 2.4 и 2.6.
Q: Где найти описания системный вызовов или функций libc?
A: Как обычно в юникс - справочник man (например man 2 write) или info.
Q: Покажите маленькую программку типа "Hello,world!"
A: См. примеры в архиве (~4K, http://stakanov.nm.ru/as/unixwasmfaq.zip)
• Вариант 1 (as,FreeBSD) - hello.s
• Вариант 2 (fasm,FreeBSD) - hello.asm
• Вариант 3 (as, все платформы, используем libc) - hello-world.s
• Вариант 4 (nasm, Linux) - hello-nasm.asm
Q: Как ее запустить (слинковать, ассемблировать)?
A:
• Вариант 1:
as hello.s -o hello.o ld -s hello.o -o hello ./hello
• Вариант 2:
fasm hello.asm hello.o ld -s hello.o -o hello ./hello
• Вариант 3:
as hello-world.s -o hello-world.o gcc -Wl,-s hello-world.o -o hello-world ./hello-world
• Вариант 4:
nasm -f elf hello-nasm.asm ld -s hello-nasm.asm -o hello-nasm ./hello-nasm
Q: А покажите "Hello,world!" с GUI.
A: Примеры в том-же файле (http://stakanov.nm.ru/as/unixwasmfaq.zip) что и консольные ;-)
• Вариант 1 (as, все платформы) - hello-gui.s
• Вариант 2 (fasm, все платформы) - gui_fasm.asm
Собирать и запускать так:
• Вариант 1:
as hello-gui.s -o hello-gui.o gcc -Wl,-s hello-gui.o -lX11 -L/usr/X11R6/lib -o hello-gui ./hello-gui
• Вариант 2:
fasm gui_fasm.asm gcc -Wl,-s gui_fasm.o -lX11 -L/usr/X11R6/lib -o gui_fasm ./gui_fasm
Q: Как мне получить аргументы командной строки и переменные окружения?
A: В точке входа в программу (_start:) в стеке содержатся следующие данные
• AT&T - Intel - Описание
• (%esp) - dword [esp] - n, количество аргументов командной строки
• 4(%esp)- dword [esp+4] - адрес первого аргумента, имя программы
• 4*2(%esp) - dword [esp+4*2] - адрес второго аргумента
• ...
• 4*n(%esp) - dword [esp+4*n] - адрес последнено аргумента
• 4*n+4(%esp) - dword [esp+4*n+4] - нулевой адрес (NULL)
• 4*n+8(%esp) - dword [esp+4*n+8] - адрес переменных окружения
Q: Какие порекомендуете ссылки?
A:
• GNU Binutils (англ) - http://www.gnu.org/software/binutils
• NASM (рус) - http://www.opennet.ru/docs/RUS/nasm/
• GNU AS(рус) - http://www.opennet.ru/docs/RUS/gas
• FASM (рус) - http://mythrillus.land.ru/tajga-tut/index.html
• Форум WASM.UNIX (рус) на http://wasm.ru/forum
• Справочник man (рус, англ) http://man.opennet.ru
• Архитектура операционной системы UNIX (пер. с THE DESIGN OF THE UNIX OPERATING SYSTEM by Maurice J. Bach)
Скачать примеры к FAQ (~4k) - http://stakanov.nm.ru/as/unixwasmfaq.zip
Еще есть YASM:
Yasm is a complete rewrite of the NASM assembler under the new" BSD Licens (some portions are under other licenses, see COPYING for details). It is designed from the ground up to allow for multiple assembler syntaxes to be supported (eg, NASM, TASM, GAS, etc.) in addition to multiple output object formats and even multiple instruction sets. Another primary module of the overall design is an optimizer module.
Сайт стаканов на нм в ру отсутствует -- откуда можно примеры скачать?
AS использует синтаксис AT&T, а NASM и FASM синтаксис Intel.
Последняя версия AS поддерживает синтаксис Intel. Для этого предусмотрена директива ".intel_syntax".
Q: Как ее запустить (слинковать, ассемблировать)?
Я бы не советовал использовать LD напрямую, как указано в вариантах 1 и 2 (и 4, но в нём есть ошибка). Проще использовать gcc для линковки, т.к. gcc обычно правильно настроен и автоматически задаёт имена динамического линкера и crt-файлов, если нужно. Те имена, которые используются по умолчанию LD, не всегда соответсвуют системным и экзешник потом не запускается (такое наблюдается на разных версиях FreeBSD и некоторых Linux'ах). Поэтому лучше использовать вариант №3.
Quantum, я как то столкнулся с такой проблемой, и просто бросил сее дело не додумав пропустить через гцц
будте добры по подробнее опишите как что, да почему... и я, и ногие "начинающие" будут Вам благодарны
Отредактировано NoResponse (23-12-2006 05:23:21)
NoResponse
по подробнее опишите как что
Первым делом собираем обьектник:
FASM: fasm test.asm test.o NASM: nasm -O3 -felf -otest.o test.asm GAS: as -o test.o test.s
Получаем test.o. Далее линкуем gcc:
gcc -s -nostdlib test.o -o test
Опция -nostdlib отключает использование CRT. Конечно, если мы используем стандартные main(), _exit() и т.д. отключать CRT нельзя.
Опция -s указывает линкеру, что экзешник желательно избавить от лишнего веса (strip the executable).
Если прога использует сишные функции, нужно включить в опции цишную либу: -lc
gcc -s -nostdlib test.o -o test -lc
Если вдруг пакет libc6-dev не установлен (в таком случае компилятор скажет, что файл -lc не найден), то вместо -lc нужно указать полный путь к динамической библиотеке:
gcc -s -nostdlib test.o -o test /usr/lib/libc.so.6
-s действует не очень эффективно. Поэтому получившийся экзешник можно ещё немного почикать командой strip:
strip -R .comment -R .gnu.version test
Можете воспользоваться утилитой objdump чтобы посмотреть какие ещё секции там лишние и их тоже можно стрипнуть:
objdump -x test | less
Наконец можно ещё скачать утилиту sstrip, которая убирает из экзешника заголовок таблицы секций, т.к. этот заголовок в экзешниках не используется:
sstrip test
Или же можно попробовать собрать полностью статический экзешник вручную на фасме или насме (без линкера). Примеры для фасма можно найти в самом дистрибутиве фасма и на форуме, а тут есть минимальный пример для насма:
http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
Но по ряду причин этот пример не будет грузиться на ядре 2.6.x, т.к. требования нового загрузчика ужесточились: секция bss должна быть последней в файле, секции не могут пересекаться (т.е. не может быть участка файла, принадлежащего более чем одной секции и это распространяется даже на заголовок), первая секция (а, следовательно, и все остальные) не может начинаться по нулевому адресу в файле, т.е. заголовок ELF уже не может входить в первую секцию. Рабочие безлинкерные примеры на насме и фасме под ядра 2.4.x и 2.6.x можно найти в последнем релизе uFMOD 1.20 под Linux.
Чтобы не учитывать все эти тонкости можно просто использовать gcc в качестве линкера (вернее фронтэнда для линкера). Цена удобства не так уж и велика - пара сотен лишних байт (учитывая -s, strip и sstrip).
FAQ стаканова с исходниками найден тут: http://tula.bofh.ru/articles/433
случайно нашел один полезный линк по теме
http://asm.sourceforge.net//resources.html
пофикси
http://asm.sourceforge.net/resources.html
изначально линк был такой
http://www.linuxassembly.org/resources.html
там стоит редирект на
http://asm.sourceforge.net//resources.html
именно с двумя //
Странно у меня и с одним слешем заходит :\
Где взять номера системных вызовов для прирывания int 80h для LINUX ???
_ir4_Y_
http://wasm.ru/article.php?article=asminunix
#Описание системных функций
После того как вы разобрались с вызовом функций, будет логичным вопрос: "А где взять описание этих самых функций?".
Ничего похожего на msdn, в unix среде к сожалению не существует, но не нужно забывать: unix - система с открытым исходном кодом и все нужное, можно найти там.
Для linux:
arch/i386/kernel/entry.S
include/asm-i386/unistd.h
include/linux/sys.h
Для FreeBSD:
i386/i386/exception.s
i386/i386/trap.c
sys/syscall.h
Для каждой функции можно посмотреть описание, используя man(2).
_ir4_Y_
Не все номера и есть ошибки, но удобнее, чем копаться в заголовочных сишных файлах:
http://www.lxhp.in-berlin.de/lhpsyscal.html
И еще один квесчин где можна скачать компилятор gas ?-)
дайти линк pls...
_ir4_Y_
дайти линк pls...
aptget'ом из самого линукса качается вместе с пакетом binutils. Отдельно врядли можно скачать.
Скажите как выделить динамическую память не используя стандартные сишные функции ?
Заранее благодарен)
Через mmap() кусками по 4 Кб (4096 б):
; В eax - размер буфера.
push edi
push ebx
xor edi,edi
mov edx,eax
push edi ; offset
add edx,4095
push -1 ; fd
and edx,-4096
push 22h ; flags <- MAP_ANONYMOUS | MAP_PRIVATE
push 3 ; prot <- PROT_READ | PROT_WRITE
push edx ; length
push edi ; start
mov ebx,esp
sub edx,eax
lea eax,[edi+90] ; #90 == mmap
int 80h ; mmap
; Test for error condition
cmp eax,-4096
ja alloc_error
; В eax - указатель на буфер.Через brk() ещё можно.
Отредактировано Quantum (09-04-2007 19:02:09)
http://sysbin.com/docs_ll.html
документация и инструменты необходимые для низкоуровневой разработки
Отредактировано Headerx (27-04-2007 17:23:05)
Начнем по возрастающей...
http://download.savannah.gnu.org/releases/pgubook/ProgrammingGroundUp-1-0-lettersize.pdf
(GAS) Обязательно к прочтению я считаю.
http://webster.cs.ucr.edu/AoA/Linux/aoapdf.tar.gz
(x86)
http://membres.lycos.fr/placr/a2i.html
Конвертер AT&T в GAS(Полезная вещь)
http://www.janw.dommel.be/eng.html
(норм хелп)
Можно пару примеров написания и использования динамических (shared) библиотек на ассемблере? В документации NASM есть немного об этом, но нормально тема не освещена (ИМХО). Буду очень благодарен!
Отредактировано drunken_tux (17-01-2008 23:42:45)
drunken_tux
FASM: http://board.flatassembler.net/topic.php?t=5345
В документации NASM есть немного об этом, но нормально тема не освещена (ИМХО).
Полностью согласен. В документации насма тема освещена отвратительно, но это частично связано с тем, что SO не сильно дружественный для ассемблера формат.
Спасибо, разобрался довольно быстро. Как я понял, нужно писать обычный базонезависимый код. Плохо, что в никсах нет ничего похожего на dll, чтобы можно было писать как обычно, не задумываясь над стартовым адресом. Сразу видна ориениация на C программистов. А базонезависимый код я и вручную загрузить сумею, зачем мне механизмы системы?
drunken_tux
Плохо, что в никсах нет ничего похожего на dll, чтобы можно было писать как обычно, не задумываясь над стартовым адресом.
SO (Shared Object) - полная аналогия DLL