26 Ağustos 2016 Cuma

__cdecl Calling Convention

__cdecl - C Dili
Şöyledir. Metod çağrısı yapan stack'i eski haline getirir.
push b;
push a;
call fnAdd;
add esp, 8    # restore stack.
Bu calling convention'da value olarak geçilen bir sınıf, metod'dan çıkarken yok edilir. Şöyle bir kod olsun.
#include <stdio.h>

struct Foo {
    Foo() { puts("created"); }
    Foo(const Foo&) { puts("copied"); }
    ~Foo() { puts("destroyed"); }
};

void __cdecl x(Foo f) { }

int main() {
    Foo f;
    x(f);
    return 0;
}
x'in assemly koduna bakarsak Foo f parametresi için destructor çağrısı yapıldığını görebiliriz.
x:
    mov     qword ptr [rsp+8],rcx
    sub     rsp,28h
    mov     rcx,qword ptr [rsp+30h]
    call    module!Foo::~Foo (00000001`400027e0)
    add     rsp,28h
    ret
__stdcall - Windows 
Şöyledir. Metod kendisi stack'i eski haline getirir.
push b;
push a;
call fnAdd;    # stack is restored by the callee. with ret 8
Bu Windows'ta kullanılan calling convention. Windows'ta DLL metodları şöyle tanımlanır.
#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif

TESTAPI int __stdcall myadd(int a, int b);
Bazı Win32 metodlarının imzası şöyledir.
WINADVAPI LSTATUS APIENTRY RegQueryValueExW(...);
Burada APIENTRY aslında __stdcall için macro'dur. Bazen de WINAPI __stdcall için macro olarak kullanılır.





Hiç yorum yok:

Yorum Gönder