В листинге 6-1 показан пример всех соглашений о вызовах из окна Disassembly отладчика Visual C++. В нем объединены все инструкции, рассмотренные до настоящего момента, и соглашения о вызовах. Исходный код примера (CALLING.CPP) находится на сопровождающем компакт-диске.
Для облегчения просмотра код листинга 6-1 имеет отладочную структуру; кроме того, код фактически ничего не делает. Каждая функция просто вызывается с подходящим соглашением о вызове. Обратите особое внимание на то, как размещены параметры в функциях, и как очищается стек. Чтобы сделать листинг более легким для чтения, между функциями вставлены инструкции NOP.
Листинг 6-1 Пример соглашений о вызовах
6: // Строки , передаваемые каждой функции -
7: static char * g_szStdCall = "_stdcall";
8: static char * g_szCdeclCall = "_cdecl";
9: static char * g_szFastCall = "_fastcall" ;
10: static char * g_szNakedCall = "_naked" ;
11:
12: // extern "С" отключает всю декорацию имен C++ .
13: extern "С"
14: {
15: .
16: // _cdecl-функция
17: void CDeclFunction { char * szString ,
18: unsigned long ulLong ,
19: char chChar ) ;
20:
21: // stdcall-функция
22: void _stdcall StdCallFunction ( char * szString ,
23: unsigned long ulLong ,
24: char chChar ) ;
25: // _fastcall-функция
26: void _fastcall FastCallFunction ( char * szString ,
27: unsigned long ulLong ,
28: char chChar ) ;
29:
30: /'/ "Голая" функция. Нет спецификатора ни для определения,
31: //ни для декларирования функции.
32: int NakedCallFunction ( char * szString ,
33: unsigned long ulLong ,
34: ' char chChar ) ;
35: }
36:
37: void main ( void )
38: {
00401000 55 push ebp
00401001 8B EC mov ebp,esp
00401003 53 push ebx
00401004 56 push esi
00401005 57 push edi
39: // Вызвать каждую функцию для генерации кода. Я разделяю
40: // каждую функцию парой NOP-байтов, чтобы облегчить чтение
41: // кода дизассемблера
42: _asm NOP _asm NOP
00401006 90 nор