Отладка приложений

       

Пример соглашений о вызовах


В листинге 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ор


00401007 90 nор
43: CDeclFunction ( g_szCdeclCall , 1 , 'а' ) ;
00401008 6А 61 push 61h
0040100A 6A 01 push 1
0040100C Al 14 30 40 00 mov eax,[g_szCdeclCall (00403014)]
00401011 50 push eax
00401012 E8 45 00 00 00 call CDeclFunction (0040105с)
00401017 83 C4 ОС add esp,OCh
44: _asm NOP _asm NOP
0040101A 90 nор
0040101B 90 nор
45: StdCallFunction ( g_szStdCall , 2 , 'b' ) ;
0040101C 6A 62 push 62h
0040101E 6A 02 push 2
00401020 8B OD 10 30 40 00 mov ecx,dword ptr
[g_szStdCall (00403010)]
00401026 51 push ecx
00401027 E8 3D 00 00 00 call StdCallFunction (00401069)
46: _asm NOP _asm NOP
0040102C 90 nор
0040102D 90 nор
47: FastCallFunction ( g_szFastCall , 3 , 'c' ) ;
0040102E 6A 63 push 63h
00401030 BA 03 00 00 00 mov edx,3
00401035 8B OD 18 30 40 00 mov ecx,dword ptr
[g_szFastCall (00403018)]
0040103В Е8 38 00 00 00 call FastCallFunction (00401078)
48: _asm NOP _asm NOP
00401040 90 nор
00401041 90 nор
49: NakedCallFunction ( g_szNakedCall , 4 , 'd' ) ;
00401042 6A 64 , push 64h
00401044 6A 04 push 4
00401046 8B 15 1C 30 40 00 mov edx,dword ptr
[g-_szNakedCall (0040301с)]
0040104C 52 push edx
0040104D E8 40 00 00 00 call NakedCallFunction (00401092) 
00401052 83 C4 ОС add esp,OCh 
50: _asm NOP _asm NOP
00401055 90 nор
00401056 90 nор
51:
52: }
00401057 5F pop edi
00401058 5E pop esi
00401059 5B pop ebx
0040105A 5D pop ebp
0040105В СЗ ret
53:
54: void CDeclFunction ( char * szString ,
55: unsigned long ulLong ,
56: char chChar )
57: {
0040105C 55 push ebp
0040105D 8B EC mov ebp,esp
0040105F 53 push ebx
00401060 56 push esi
00401061 57 push edi 58: _asm NOP _asm NOP
00401062 90 nор
00401063 90 nор 
59: }
00401064 5F pop edi
00401065 5E pop esi
00401066 5B pop ebx
00401067 5D pop ebp
00401068 C3 ret
60:
61: void _stdcall StdCallFunction ( char * szString ,
62: unsigned long ulLong ,
63: char chChar )
64: {
00401069 55 push ' ebp
 0040106A-8B EC mov ebp,esp 
0040106C 53 push ebx


 0040106D 56 push esi 
0040.106E 57 push edi 
65: _asm NOP _asm NOP 
0040106F 90 nор
00401070 90 nор 
66: }
00401071 5F pop edi
00401072 5E pop esi
00401073 5B pop ebx
00401074 5D pop ebp
00401075 C2 ОС 00 ret OCh
67:
68: void _fastcall FastCallFunction ( char * szString ,
69: unsigned long ulLong ,
70: char chChar )
71: {
00401078 55 push ebp
00401079 8B EC mov ebp,esp
 0040107B 83 EC 08 sub , esp,8
 0040107E 53 push ebx 
0040107F 56 push esi
00401080 57 push edi
00401081 89 55 F8 mov dword ptr [ebp-8],edx 
00401084 89 4D FC mov dword ptr [ebp-4],ecx 
72: _asm NOP _asm NOP
00401087 90 nор
00401088 90 nор 
73: }
00401089 5F pop edi 
0040108A 5E pop esi 
0040108В 5В pop ebx
 0040108C 8В Е5 , mov esp,ebp
0040108Е 5D pop ebp
0040108F C2 04 00 ret 4
74:
75: _declspec(naked) int NakedCa11Function ( char * szString ,
76: unsigned long ulLong ,
77: . char chChar )
78: {
00401092 90 nор
00401093 9.0 nор
79: _asm NOP _asm NOP
80: // Голые функции должны явно выполнять возврат.
81: _asm RET
00401094 СЗ ret

Содержание раздела