__cdecl、__stdcall、__fastcall 与 __pascal 浅析
call 指令与 retn 指令 首先我们得了解 CALL 和 RETN 指令的作用,才能更好地理解调用规则,这也是先决条件。 实际上,CALL 指令就是先将下一条指令的 EIP 压栈,然后 JMP 跳转到对应的函数的首地址,当执行完函数体后,通过 RETN 指令从堆栈中弹出 EIP,程序就可以继续执行 CALL 的下一条指令。 __cdecl 与 __stdcall 调用规则 C/C++ 中不同的函数调用规则会生成不同的机器代码,产生不同的微观效果,接下来让我们一起来浅析四种调用规则的原理和它们各自的异同。首先我们通过一段 C 语言代码来引导我们的浅析过程。 这里我们编写了三个函数,它们的功能都是返回两个参数的相加结果,只是每个函数都有不一样的调用规则。 我们使用 printf 函数主要是为了在 OllyDBG 中能够快速下断点,以确定后边调用三个函数的位置,便于分析。在这里我给每个函数都用了内联的 NOP 指令来分隔开,图中也用红框标明,这样可以便于区分每个函数的调用过程。通过一些简单的步骤,我们用 OllyDBG 查看了编译后代码的“真面目”。代码中有 4 个 CALL,第一个是 printf,我们不关心这个。后面三个分别是具有 __cdecl,__stdcall,__fastcall 调用规则的函数 CALL(这里我已经做了注释)。 在这里为了循序渐进,我们先介绍 _