c - stdcall 函数的 asm 如何从堆栈中清除 args?

标签 c assembly x86 calling-convention stdcall

我有简单的代码。 StdCall__stdcallCdeclCall__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 的一部分(Main 确实清除 CdeclCall 的堆栈)

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

现在,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 指令的一部分 - 8 是弹出返回地址后添加到堆栈指针的字节数。

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

另请参阅What is the meaning and usage of __stdcall?有关 Windows 中 C 函数名称上的 @ 修饰的更多信息。

关于c - stdcall 函数的 asm 如何从堆栈中清除 args?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22876147/

相关文章:

c - 查找数组中不同元素数量的最快方法

char 和 int 不能是同一个函数吗?

使用 MPI_Reduce 计算数字的平均值

c - 在Assembly中打印多个值

c - _mm_testc_ps 和 _mm_testc_pd 与 _mm_testc_si128

assembly - 是什么导致这个程序出现段错误?

c - GCC 与 mysql 库编译

c++ - 海湾合作委员会 assembly "+t"

linux - 将 500 字节缓冲区用于简单的大写转换器有什么好处吗?

linux - 使用 Assembly 在屏幕上打印字符