У меня есть простой код. StdCall
является __stdcall
а также CdeclCall
является __cdecl
,
#include <stdio.h>
int __stdcall StdCall(int a,int b)
{
return a + b;
}
int __cdecl CdeclCall(int a,int b)
{
return a + b;
}
int main(int argc, char **argv) {
StdCall(10,20);
CdeclCall(10,20);
printf("Done");
return 0;
}
Часть разборки main () для StdCall (Main не очистить стек для StdCall)
push 20 ; 00000014H
push 10 ; 0000000aH
call ?StdCall@@YGHHH@Z ; StdCall
Часть разборки main () для CdeclCall (Main делает очистить стек для CdeclCall)
push 20 ; 00000014H
push 10 ; 0000000aH
call ?CdeclCall@@YAHHH@Z ; CdeclCall
add esp, 8 ; Stack cleared here
Теперь StdCall несет ответственность за очистку стека, но дизассемблирование не показывает никакого кода, что предполагает, что StdCall очистил стек.
Разбирать для StdCall
push ebp
mov ebp, esp
sub esp, 192 ; 000000c0H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-192]
mov ecx, 48 ; 00000030H
mov eax, -858993460 ; ccccccccH
rep stosd
mov eax, DWORD PTR _a$[ebp]
add eax, DWORD PTR _b$[ebp]
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 8
Это выполнение во время выполнения для генерации кода очистки стека для __stdcall
или я неправильно понял концепцию?
Благодарю.
Это часть ret
инструкция — 8 — число байтов, добавляемых к указателю стека.
Других решений пока нет …