Использование атрибута «голый» для функций в GCC - PullRequest
10 голосов
/ 27 апреля 2010

В документации GCC указано 6.30 Объявление атрибутов функций :

naked

Используйте этот атрибут на портах ARM, AVR, IP2K, RX и SPU, чтобы указать, что указанной функции не нужны последовательности пролога / эпилога, сгенерированные компилятором. Программист должен предоставить эти последовательности. Единственные операторы, которые можно безопасно включать в голые функции, это операторы asm, которые не имеют операндов. Следует избегать всех других операторов, в том числе объявлений локальных переменных, операторов if и т. Д. Голые функции должны использоваться для реализации тела функции ассемблера, позволяя при этом компилятору создавать объявление необходимой функции для ассемблера.

Могу ли я безопасно вызывать функции с использованием синтаксиса C из голых функций или только с использованием asm?

Ответы [ 3 ]

5 голосов
/ 27 апреля 2010

Если единственное, что вы делаете в голой функции, это вызываете другую функцию, вы можете просто использовать одну инструкцию машинного кода JMP.

Функция, к которой вы переходите, будет иметь действительный пролог и должна возвращаться непосредственно к вызывающей стороне голой функции, поскольку JMP не помещает адрес возврата в стек.

5 голосов
/ 20 ноября 2013

Вы можете безопасно вызывать функции из обнаженной функции, при условии, что вызываемые функции имеют полный пролог и эпилог.

Обратите внимание, что утверждать, что вы можете «безопасно» использовать язык ассемблера в «голой» функции, - это немного глупо. Вы несете полную ответственность за все, что делаете с использованием ассемблера, так же как и за любые вызовы, которые вы делаете для «безопасных» функций.

Чтобы убедиться, что ваша общая вызываемая функция не является статической или встроенной, она должна находиться в отдельном модуле компиляции.

«Голые» функции не включают пролог или эпилог - они голые. В частности, они не включают операции со стеком для локальных переменных, для сохранения или восстановления регистров или для возврата к вызывающей функции.

Это не означает, что стек не существует - стек инициализируется при инициализации программы, а не при какой-либо инициализации функции. Поскольку стек существует, прологи и эпилоги с именем функции работают правильно. Вызов функции может безопасно передать ее адрес возврата, любые используемые регистры и место для любых локальных переменных. По возвращении (используя адрес возврата) регистры восстанавливаются и пространство стека освобождается.

Статические или встроенные функции могут не иметь полного пролога и эпилога. Они могут и могут зависеть от вызывающей функции для управления стеком и восстановления поврежденных регистров.

Это приводит к следующему пункту: пролог и эпилог нужны только для инкапсуляции операций вызываемой функции. Если вызываемая функция также безопасна (без явных или неявных локальных переменных, без изменений в регистрах состояния), она может быть безопасно статической и / или встроенной. Как и в случае с asm, вы должны убедиться, что это правда.

0 голосов
/ 27 апреля 2010

Единственные операторы, которые можно безопасно включать в голые функции, - это операторы asm, у которых нет операндов. Следует избегать всех других операторов, включая объявления локальных переменных, операторов if и т. Д.

Исходя из описания, которое вы уже дали, я предполагаю, что даже вызовы функций не подходят для ключевого слова "голый".

...