Ассемблер в BeOS
thorn 26 апреля, 2002 - 18:35.Перевод статьи http://old.beunited.org/articles/jbq/nasm.shtml
Жан–Батист
М. Керуdjaybee@cyberdude.comBeDevID #E–1145
Многие спрашивают, как использовать ассемблерный код в их проектах. Эта статья с небольшим примером в конце немного приоткроет эту тему. Подразумевается, что у вас есть опыт программирования в x86 ассемблере.
Я рассмотрю пример модуля, написанного полностью на ассемблере. Если вы интересуетесь ассемблерными вставками в Си, то лучше всего начинать с этого места — http://www.castle.net/~avly/djasm.html, неплохой статьи описывающей все причуды gcc ассемблера.
Какой ассемблер лучше всего использовать?
Я настоятельно рекомендую NASM. Он доступен для целого ряда платформ, понимает большинство объектных форматов, знает последние расширения x86–х инструкций, включая MMX, 3D–Now! и SSE.
Официальную страницу NASM и бинарники NASM, исполняемые в BeOS вы найдете здесь — %nasm_for_beos%.
Формат исполняемых файлов в BeOS — ELF, следовательно, вы должны компилировать свои проекты в этом формате, используя при для компиляции команду nasm -f elf.
Как вызывать ассемблерный код из C/C++
Самый лучший способ — писать ваши функции совместимыми с C или C++. Это позволит избежать конфликтов имен и прочих трудностей, связанных с C++. Для того, чтобы это сделать, функции надо обявлять как extern C (см. пример).
Обратите внимание, что в ELF имена ассемблерных функций идентичны C и вам не надо добавлять подчеркивание в начале имени функции.
Что такое «Соглашение о вызовах»?
Я проигнорирую здесь особые случаи, такие как функции возвращающие структуры и и случаи с mmx регистрами.
В BeOS существует стандартное для x86 соглашение о вызовах:
- Параметры находятся в стеке. Самый первый параметр находится по младшему адресу esp+4. Из стека параметры выбираются вызываемой функцией.
- Возвращаемое значение находится в al/ax/eax если оно размером 8/16/32 бит соответсвенно, в edx:eax если 64–х битное и в st0 если возращаемое значение — число с плавающей точкой.
- Каждая функция должна сохранить ebx,esi,edi,ebp и конечно esp. Эти регистры должны сохраняться и востанавливаться.
- Функция не может изменять сегментные регистры. Регистры cs, ds, es и селекторы ss имеют тот–же базовый адрес и размер.
- Флаг направления должен быть равен нулю при вызове и возврате из функции.
- При завершении функция должна приводить стек в исходное состояние.
Какие бывают директивы компиляции NASM?
В этом примере используются не все директивы, которые вы должны знать. Здесь описаны наиболее часто используемые директивы:
GLOBAL делает видимым линкеру символ a_label. Обычно надо определять глобальными те символы, которые будут описаны в заголовочном файле C/C++.
EXTERN сообщает NASM, что символ a_label существует в другом объектном файле. Больше информации вы найдете в документации NASM.
Что делает этот пример?
Этот пример повторяет 32–х битный memcpy() и 32–x битный memset() используя инструкции rep movsd и rep stosd. Обычно использование этих инструкций не рекомендованно, но они очень быстры в одном случае: на любом процессоре семейства P6 (PPro, PII, PIII, Celeron, Xeon), когда источник и приемник выравнены по 8 байтной границе и размер передаваеммых данных больше 64 двойных слов (т.е. 256 байт). Эти инструкции работают, обрабатывая полную строку кэша, т.е. 32 байта за такт и они могут быть очень полезными, если вы обрабатываете графические данные, особенно в 32 битном режиме. ОБратите внимание, что аргумент num — исчисляется в двойных словах ( что есть 32 битные объекты), а не в байтах.
Сам пример:
-–- begin repmovsd.h -–-
#ifndef REPMOVSD_H_
#define REPMOVSD_H_
#ifdef __cplusplus
extern C {
#endif
void repmovsd(int*dest,int*src,int num);
void repstosd(int*dest,int data,int num);
#ifdef __cplusplus
}
#endif
#endif
--–-
end repmovsd.h --–--–-
begin repmovsd.asm -–- GLOBAL repmovsd
GLOBAL repstosd
SECTION .text
repmovsd :
push esi
push edi
mov edi,[esp+12]
mov esi,[esp+16]
mov ecx,[esp+20]
rep movsd
pop edi
pop esi
ret
repstosd :
push edi
mov edi,[esp+8]
mov eax,[esp+12]
mov ecx,[esp+16]
rep stosd
pop edi
ret
--–-
end repmovsd.asm ---–
Отправить комментарий