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

от Уикипедия, свободната енциклопедия
Направо към: навигация, търсене

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

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

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

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[редактиране | edit source]

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

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

ret 6

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

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

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

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

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

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

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

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

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

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

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

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