调用约定的参数传递顺序

都是学习过程中做的笔记。

在编程的过程中,函数是必不可少的基础之一。c语言的程序完全由函数构成,所有的代码都在某一个函数中;pascal区分函数和过程,但是本质是类似的。而对计算机硬件而言CPU只关心一条条的指令,而不是它们是什么样的结构组织。callret只是为了函数调用的方便而已,并不是函数存在的证据。最简单的例子就是在木马免杀过程中call+retjmp是等价的。因此一种高级语言如何实现函数调用并不受约束,故出现了不同的函数调用规则。

windows平台上常用的函数调用方式有pascal方式(psscal调用约定)WINAPI方式(StdCall调用约定),c方式(Cdedel调用约定)。

假设有一高级语言函数Message(p1,p2,p3)

 

c方式(Cdedel调用约定):

1.参数从右到左进入堆栈;

2.在函数返回后,调用者要负责清除堆栈,所以这种调用会生成较大的可执行程序。

push p3

push p2

push p1

call Message

add esp,0ch ;之前压入了3个四字节的参数

 

WINAPI方式(StdCall调用约定):

    1.函数从右到左进入堆栈;

   2.被调用的函数在返回之前自行清理堆栈,所以生成的代码较小。

push p3

push p2

push p1

call Message

 

 

pascal方式(psscal调用约定):主要用于win16函数库中,现在基本不用

    1.参数从左到右进入堆栈

    2.被调用的函数在返回前自行清理堆栈

   3.不支持可变参数的函数调用。

push p1

push p2

push p3

call Message

 

此外在windows内核中还有快速调用方式(_fastcall);在C++编译的代码中有this call方式(_thiscall)

 

你可能感兴趣的:(编程,windows,语言,pascal,平台,winapi)