2

私は簡単なコードを持っています。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;

}

StdCall の main() の Disassabmbly の一部 (MainはStdCall のスタックをクリアしません)

push    20                  ; 00000014H
push    10                  ; 0000000aH
call    ?StdCall@@YGHHH@Z           ; StdCall

CdeclCall の main() の Disassabmbly の一部 (MainCdeclCall のスタックをクリアします)

push    20                  ; 00000014H
push    10                  ; 0000000aH
call    ?CdeclCall@@YAHHH@Z         ; CdeclCall
add esp, 8   ; Stack cleared here

現在、スタックから引数を削除するのは StdCall の責任ですが、逆アセンブルでは ags をポップしてスタックをクリア/クリーンするコードは表示されません。

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それとも概念が間違っていますか?

4

1 に答える 1

4

これは命令の一部ですret 8。8 は、戻りアドレスをポップした後にスタック ポインターに追加するバイト数です。

https://www.felixcloutier.com/x86/ret

__stdcall の意味と使用法は何ですか?も参照してください。@Windows での C 関数名の装飾の詳細については、 を参照してください。

于 2014-04-05T03:22:44.157 に答える