Конвенции на извикване

от Уикипедия, свободната енциклопедия

Конвенция на извикване (от англ. Calling convention) се нарича методът на езика за програмиране за предаване и получаване на информация от функция.

Конвенциите на извикване биват различни според това как се предава информация в стека, как се връща информация от функция и др.

cdecl[редактиране | редактиране на кода]

cdecl конвенцията на извикване се използва в много C и C++ системи за x86 архитектура. В cdecl, параметрите на функциите се поставят в стека от дясно-на-ляво. Връщаните от функцията стойности се поставят в EAX регистъра, ако е до размер двойна дума. При по-големи стойности се използват регистрите EDX:EAX. При числа с плаваща запетая се използва регистъра на математическия копроцесор ST(0).

Например следващият код на функция при С:

int function(int, int, int);

int a, b, c, x;

...

x = function (a, b, c);

се преобразува в следващия x86 Асемблерен код:

push c ; поставяне на параметрите

push b ; от дясно наляво

push a

call function

add esp, 12 ; изчистване на стека

mov [x], eax ;

Изчистването на стека става след мястото на извикване на функцията.

Cdecl конвенцията на извикване се използва обикновено в x86 С компилатори, като в други компилатори автоматично се променя конвенцията на извикване. За ръчно задаване на функция да използва cdecl се използва:

void _cdecl function(параметри);

Модификаторът _cdecl трябва да бъде поставен в прототипа на функцията и в декларацията на функцията.

Pascal[редактиране | редактиране на кода]

Конвенцията на извикване pascal е противоположна на cdecl. Параметрите се поставят в стека от ляво надясно, а освен това изчистването на стека се извършва от самата функция.

Изчистването на стека става като се постави необходимия брой байтове след инструкцията ret. Например ако трябва да се изчистят 6 байта, то кода има вида:

ret 6

FastCall[редактиране | редактиране на кода]

FastCall конвенцията е специфична за компилатора. В повечето случаи при във функция с 2 – 3 параметъра с размер 32 бита или по-малък се предават посредством EAX, EDX и евентуално ECX. Останалите аргументи се поставят в стека от дясно-на-ляво, точно както cdecl. Връщаната стойност от функцията се предава чрез регистрите AL, AX или EAX.

stdcall[редактиране | редактиране на кода]

Конвенцията за извикване stdcall е стандартната конвенция, която се използва в API на Microsoft Windows NT. Параметрите на функциите се предават от дясно-на-ляво. Регистрите EAX, ECX и EDX се резервират вътре във функцията. Връщаната стойност се предава по регистъра EAX. За разлика от cdecl, стека се изчиства от извиканите функции, защото stdcall функциите не поддържат променлив брой на аргументите.

При Microsoft Windows, функциите могат да бъдат декларирани като stdcall, използвайки следния синтаксис в прототипа и в декларацията им:

void __stdcall function(параметри);

Intel ABI[редактиране | редактиране на кода]

Intel Application Binary Interface (Приложен бинарен интерфейс) е компютърен програмен стандарт, който повечето компилатори следват. Според Интел ABI, регистрите EAX, EDX и ECX трябва да бъдат свободни за използване вътре във функциите, за това е необходимо тяхното предварително съхранение в стека.

Microsoft x64 конвенция на извикване[редактиране | редактиране на кода]

х64 конвенция за извикване дава предимство, като добавя повече пространство при използваните регистри на x86-64 / Интел EM64T. Регистрите RCX, RDX, R8, R9 се параметри за аргументи на цели числа, а XMM0, XMM1, XMM2, XMM3 се използват за параметри с плаваща запетая. Допълнителните параметри се поставят в стека. Връщаната от функцията стойност се поставя в RAX.

Външни препратки[редактиране | редактиране на кода]

  Тази страница частично или изцяло представлява превод на страницата Calling_convention в Уикипедия на английски. Оригиналният текст, както и този превод, са защитени от Лиценза „Криейтив Комънс – Признание – Споделяне на споделеното“, а за съдържание, създадено преди юни 2009 година – от Лиценза за свободна документация на ГНУ. Прегледайте историята на редакциите на оригиналната страница, както и на преводната страница, за да видите списъка на съавторите. ​

ВАЖНО: Този шаблон се отнася единствено до авторските права върху съдържанието на статията. Добавянето му не отменя изискването да се посочват конкретни източници на твърденията, които да бъдат благонадеждни.​