Что делает голый атрибут VC / C ++? - PullRequest
2 голосов
/ 17 февраля 2011

Из MSDN

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

 __declspec(naked) declarator

Что такое "код пролога и эпилога". Я видел библиотеки, написанные на C-коде, работающие на устройстве или прошивке с использованием только libc. Он вызывает функции без проблем, что делает ключевое слово naked и зачем оно нужно?

примечание: я не уверен, какое соглашение о вызовах используют функции в этих библиотеках.

Ответы [ 5 ]

7 голосов
/ 17 февраля 2011

Пролог: код, который выполняется перед телом функции, обычно код, который обрабатывает ввод функции и обработку аргументов.Эпилог: код, который запускается после тела функции, как правило, код, который обрабатывает возврат функции и возвращаемого значения.

С «голым» вам нужно / получить возможность написать этот материал самостоятельно.

4 голосов
/ 17 февраля 2011

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

2 голосов
/ 17 февраля 2011

Директива __declspec(naked) удаляет автоматически сгенерированный пролог / эпилог.

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

Например, __fastcall соглашения о вызовах. Он указывает, что первые два аргумента находятся в регистрах (ECX и EDX), а остальные - справа-> слева в стеке. Итак, для функции:

void __fastcall DoFoo(int first, int second);

Мой ассемблер немного заржавел, но пролог может выглядеть так:

mov %ecx, first
mov %edx, second
pushl %ebp
mov %esp, %ebp
sub bytes, %esp

Однако разные соглашения о вызовах будут генерировать другой код пролога / эпилога.

Wiki

0 голосов
/ 06 ноября 2013

Без __ declspec (naked) ваш компилятор отвечает за правильную обработку соглашения о вызовах (размещение входных аргументов в стеке, «резервирование» пространства для локальных переменных и т. Д.).В некоторых случаях вы можете сделать это самостоятельно.

Например - без __ declspec (голый) первые 3 (пролог) и последние 3 (эпилог) инструкции ниже будут предоставлены вашим компилятором (при условии cdecl используется соглашение о вызовах).

__declspec(naked) void func(inta, intb, int c, intd)
{
    _asm{
        push ebp
        mov ebp, esp

        sub esp, 8  // for 2 local int(32bit) variables - if you need it of course

        mov dword ptr[ebp-4], 3   // set one local var to 3
        mov dword ptr[ebp-8], 4   // set one local var to 4

        mov eax, dword ptr [ebp+8]   // a
        mov ebx, dword ptr [ebp+12]  // b
        mov ecx, dword ptr [ebp+16]  // c
        mov edx, dword ptr [ebp+20]  // d

        add esp, 8 // remove space for local vars

        mov esp, ebp
        pop ebp
        ret
    }
}

теперь вы можете вызывать эту подпрограмму из кода C / C ++ следующим образом:

func(0xAA, 0xBB, 0xCC, 0xDD);

, который станет:

push 0DDh
push 0CCh
push 0BBh
push 0AAh
call func

КСТАТИ - аргументы помещаются в обратном порядке (по сравнению с порядком, найденным при вызове функции), чтобы позволить функциям переменной длины работать

0 голосов
/ 17 февраля 2011

Код пролога и эпилога обычно имеет дело со стеком, для которого часто передаются и возвращаются аргументы. Попросить компилятор не генерировать это означает, что вам придется реализовать правильный способ доступа к аргументам самостоятельно.

Не уверен, включает ли это также выделение стекового пространства для собственных аргументов функции, что часто делается в самом начале функции (и затем не выполняется до выхода из функции), поэтому это кажется вероятным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...