Вызов SWI функции из Си в GCC ARM

ARM7, ARM9, ARM11 etc.

Вызов SWI функции из Си в GCC ARM

Сообщение igorkov » 19 май 2008, 12:45

В общем стоит следующая проблема: в компиляторе GCC требуется вызвать SWI-функцию с номером. Функция написана, обработчик SWI-написан и функционирует. Надо, чтобы была функция, допустим syscall(), т.е. когда я напишу в Си коде
Код: Выделить всё
syscall()
, то компилятор сделает:
Код: Выделить всё
SWI 0x123
, где 0x123 номер программного прерывания.

Пока есть следующие решения:
1) Через ассемблерную вставку вида:
Код: Выделить всё
#define syscall()                              \
      asm volatile(                           \
         "swi #0x123"       "\r\n"               \
         : : :                              \
      )

2) Объявление в *.asm функции:
Код: Выделить всё
syscall:
         str SP!,{LR}
         swi 0x123
         ldr SP!,{PC}

И заголовочного файла:
Код: Выделить всё
void syscall(void);


Недостатки:
У первого: при вызове функции с параметрами в макрос добавляются строки mov r0, %1 и т.д. по кол-ву параметров и идут лишние перетасовки между регистрами. GCC не может оптимизировать такой вызов.
У второго: в код вставляется вызов функции на ассемблере:
Код: Выделить всё
BL syscall

И только после перехода по адресу идет вызов swi. Накладные расходы: 3 лишние команды, плюс 4 байта стека на возврат.

Так что вопрос: возможно ли что-то аналогичное Realview MDK:
Код: Выделить всё
void __swi(0x123) syscall(void);

???
igorkov
 
Сообщения: 38
Зарегистрирован: 19 ноя 2006, 20:15
Откуда: Мытищи

Re: Вызов SWI функции из Си в GCC ARM

Сообщение igorkov » 21 июн 2008, 01:19

В итоге реализовал патчером.
В скрипте линкера объявляю специфичные метки с недопустимыми адресами, а потом получившиеся "кривые" BL инструкции
заменяю на соответствующие номерные SWI. Работает :)
igorkov
 
Сообщения: 38
Зарегистрирован: 19 ноя 2006, 20:15
Откуда: Мытищи

Re: Вызов SWI функции из Си в GCC ARM

Сообщение boez » 27 авг 2008, 10:54

Не совсем понял - что не так с первым вариантом (asm volatile() ). У меня на предыдущей работе был арм-проект на LPC - все системные вызовы были объявлены макросами через asm, лишнего вроде ничего не замечал. А если вызов требует аргументов - то они же в любом случае привязаны к регистрам, так что вроде без перемещений компилятору в общем случае не обойтись. Или я чего-то не заметил?
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++


Вернуться в ARM

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6