Главная

Ассемблер в BeOS

Перевод статьи http://old.beunited.org/articles/jbq/nasm.shtml

Жан–Батист М. Керуdjaybee@cyberdude.com
BeDevID #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 соглашение о вызовах:

  1. Параметры находятся в стеке. Самый первый параметр находится по младшему адресу esp+4. Из стека параметры выбираются вызываемой функцией.
  2. Возвращаемое значение находится в al/ax/eax если оно размером 8/16/32 бит соответсвенно, в edx:eax если 64–х битное и в st0 если возращаемое значение — число с плавающей точкой.
  3. Каждая функция должна сохранить ebx,esi,edi,ebp и конечно esp. Эти регистры должны сохраняться и востанавливаться.
  4. Функция не может изменять сегментные регистры. Регистры cs, ds, es и селекторы ss имеют тот–же базовый адрес и размер.
  5. Флаг направления должен быть равен нулю при вызове и возврате из функции.
  6. При завершении функция должна приводить стек в исходное состояние.

Какие бывают директивы компиляции 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 ---–

а чего ж так код разползся.. читать дюже неудобно (-)

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Allowed HTML tags: <a> <em> <i> <img> <strong> <b> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и параграфы переносятся автоматически.

Подробнее о форматировании

CAPTCHA
Введите перечисленные символы, чтобы мы убедились, что вы не робот. Не требуется для зарегистрированных пользователей.
n
n
B
b
b
c
Enter the code without spaces and pay attention to upper/lower case.