У меня есть приложение, написанное на чистом C, смешанное с некоторыми функциями, содержащими чистый ASM. Атрибут Naked недоступен для x86 (почему? Почему ?!), и мои функции asm не любят, когда пролог и эпилог возятся со стеком. Возможно ли каким-то образом создать чистую функцию ассемблера, на которую можно ссылаться из частей кода C? Мне просто нужен адрес такой функции ASM.
Эквивалент голого атрибута GCC
Ответы (3)
Просто используйте asm()
вне функционального блока. Аргумент asm()
просто игнорируется компилятором и передается непосредственно ассемблеру. Для сложных функций отдельный исходный файл сборки - лучший вариант, чтобы избежать неудобного синтаксиса.
Пример:
#include <stdio.h>
asm("_one: \n\
movl $1,%eax \n\
ret \n\
");
int one();
int main() {
printf("result: %d\n", one());
return 0;
}
PS: Убедитесь, что вы понимаете соглашения о вызовах вашей платформы. Часто вы не можете просто скопировать / прошить ассемблерный код.
PPS: если вам важна производительность, используйте вместо этого расширенный asm. Расширенный asm по существу встраивает ассемблерный код в ваш код C / C ++ и работает намного быстрее, особенно для коротких ассемблерных функций. Для более крупных функций сборки предпочтительнее отдельный исходный файл сборки, поэтому этот ответ действительно является хаком для того редкого случая, когда вам нужен указатель функции на небольшую функцию сборки.
asm()
внешние функциональные блоки не работают в c99
.
- person hauzer; 10.10.2013
__asm
или __asm__
вместо asm
.
- person Mackie Messer; 10.10.2013
asm
, которая конфликтует с этим расширением GCC. Но имена, начинающиеся с двух знаков подчеркивания, зарезервированы для реализации (например, GCC). Таким образом, расширение GCC может использовать __asm
и __asm__
и по-прежнему соответствовать стандарту, но не asm
.
- person Mackie Messer; 10.10.2013
undefined reference to 'one'
, и мне пришлось изменить объявление на int one() asm ("_one");
(в Linux).
- person Ben C; 04.12.2017
Всем хорошие новости. Разработчики GCC наконец-то реализовали атрибут ((naked)) для x86. Эта функция будет доступна в GCC 8.
attribute((interrupts))
вместе с соответствующей опцией командной строки -mgeneral-regs-only
. Реализация оставляет желать лучшего, но она уже не завершена нереализованной.
- person Michael Petch; 01.08.2017
Конечно, просто создайте .s
файл (источник сборки), который будет запущен через gas
(ассемблер) для создания обычного объектного файла.
.S
(заглавная S), ваш ассемблерный код также будет предварительно обработан cpp.
- person Mackie Messer; 04.12.2011