函数调用时,调用者依次把参数压栈,然后调用函数,函数被调用以后,在堆栈中取得数据,并进行计算。函数计算结束以后,或者调用者、或者函数本身修改堆栈,使堆栈恢复原装。 在参数传递过程中需要解决两个问题:

  • 当参数大于一个时,参数的入栈顺序如何,即:从右向左亦或是由右向左。
  • 恢复堆栈的任务是由调用函数完成,还是被调用者负责。

这就是函数调用约定所需要解决的问题,在高级语言中,通常存在以下几种调用约定:

  • stdcall
  • cdecl
  • fastcall
  • thiscall
  • naked call
stdcall的调用约定

stdcall很多时候被称为pascal调用约定,因为pascal 是早期很常见的一种教学用计算机程序设计语言,其语法严谨,使用的函数调用约定就是stdcall。在Microsoft C++系列的C/C++编译器中,常常用PASCAL宏来声明这个调用约定,类似的宏还有WINAPI和CALLBACK。stdcall的调用约定意味着:

  • 参数从右向左压入堆栈,
  • 函数自身修改堆栈
  • 函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸

对于下面的一段代码:

1
2
3
4
5
6
7
8
9
10
int __stdcall function(int a, int b)
{
	return a + b;
}
 
int main()
{
	int result = function(1, 2);
	return 0;
}

用g++生成相应的汇编代码:

$ g++ test.cpp -o test.s -S

汇编代码(部分核心代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
_function__Fii@8:                     ;函数名
	pushl %ebp                 ;保存堆栈指针
	movl %esp,%ebp
	movl 8(%ebp),%eax      ;参数int a
	movl 12(%ebp),%ecx    ;参数int b
	leal (%ecx,%eax),%edx ;计算a + b并保存至寄存器edx
	movl %edx,%eax          ;将结果移至寄存器eax,即返回值
	movl %ebp,%esp     
	popl %ebp
	ret $8                         ;又被调用函数负责恢复堆栈
_main:
	pushl %ebp
	movl %esp,%ebp
	subl $16,%esp
	call ___main
	pushl $2                     ;压入参数int b
	pushl $1                     ;压入参数int a
	call _function__Fii@8    ;调用函数function
	movl %eax,%eax
	movl %eax,-4(%ebp)
	xorl %eax,%eax
	xorl %eax,%eax
	movl %ebp,%esp
	popl %ebp
	ret
cdecl调用约定

默认情况下,g++采用这种约定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
_function__Fii:
	pushl %ebp
	movl %esp,%ebp
	movl 8(%ebp),%eax
	movl 12(%ebp),%ecx
	leal (%ecx,%eax),%edx
	movl %edx,%eax
	movl %ebp,%esp
	popl %ebp
	ret
_main:
	pushl %ebp
	movl %esp,%ebp
	subl $16,%esp
	call ___main
	pushl $2
	pushl $1
	call _function__Fii
	addl $8,%esp             ;由调用者负责清理堆栈
	movl %eax,%eax
	movl %eax,-4(%ebp)
	xorl %eax,%eax
	movl %ebp,%esp
	popl %ebp
	ret

未完待续……

Tags: ,,.
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!
Home

Be the first to comment on this entry.

Name(required)
Mail (required),(will not be published)

RFC: Request For Comments. Orz..

Website(recommended)