【问题标题】:How does this asm for a stdcall function clean args from the stack?stdcall 函数的这个 asm 如何从堆栈中清除 args?
【发布时间】:2014-05-17 13:19:18
【问题描述】:

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

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

现在,StdCall 有责任从堆栈中删除其 args,但反汇编不会显示任何弹出 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生成清除堆栈代码是运行时活动还是我错误地理解了概念?

【问题讨论】:

  • 被调用方恢复堆栈指针的旧术语是 pacscal 调用约定,但在您的情况下,它现在是 __stdcall。

标签: c assembly x86 calling-convention stdcall


【解决方案1】:

它是ret 8 指令的一部分 - 8 是弹出返回地址后要添加到堆栈指针的字节数。

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

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

【讨论】:

  • 想详细说明一下,返回值正在存储在寄存器中。 ret 指令只会通过控制。对吗?
  • @pranitkothari 是的,没错。返回值已经在eax中。
  • (编辑问题和答案以便更好地复制MessageBox program in x86 assembly)。 PS,马克,你可以@reply 给编辑过帖子的人,即使他们没有评论。同意如果有一个 PM 机制,而不是弄清楚如何“邀请某人聊天”,我认为这可能不需要在任何地方发表评论,但你必须启动一个聊天室,所以我不能被打扰了。
  • @PeterCordes 再次感谢。我想我是因为 @ 没有像往常那样提供自动完成选项。
  • 哦,是的,这很奇怪。出于某种原因,自动完成功能不适用于只编辑而不评论的人。我想这只是运行客户端的一个因素。
猜你喜欢
  • 1970-01-01
  • 2013-10-11
  • 2015-04-13
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 1970-01-01
  • 1970-01-01
  • 2018-12-01
相关资源
最近更新 更多