天天看点

大神洗礼第四讲——函数相关及编程技巧

Author:bakari       Date:2012.11.2

1、参数传递问题:

< 1 >、堆栈传参

< 2 >、寄存器传参(利用通用寄存器进行函数参数传递的方法)

< 3 >、全局变量或静态变量传参

2、 Call Convention(函数调用约定)

< 1 >、_cdecl

a、 参数从右向左压入堆栈

b、 函数被调用者修改堆栈

c、 在win32应用程序里,宏APIENTRY,WINAPI,都表示_stdcall,非常常见.

d、 C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。

< 2 >、_stdcall

a、 压栈方式与_cdecl一样,与之不一样的是堆栈的平衡不是由函数调用者完成,而是自身完成,在退出时自己清空堆栈。

b、 此种方式在函数返回是以 ret 8 指令来平衡堆栈,此处:ret 8 = add esp , 8。

< 3 >、上两种方式最为常用,此外还有fastcall ,thiscall, naked call,_pascal等 _pascal 入栈方式是从左到右。

下面通过一些例子来深入理解。

3、 跟踪汇编代码看函数参数的调用机制 我们看这样一个简单的函数,

编译器翻译的汇编指令如下:

< 1 >、void Test1(){} 

 据此画出内存布局图为:

大神洗礼第四讲——函数相关及编程技巧

< 2 >、有参数的情况

内存布布局如下:

大神洗礼第四讲——函数相关及编程技巧

4、 编写裸函数(不让系统加汇编的代码,而是人为的加上去)

比如:

在main函数调用的结果printf("%d\n", MyFunc());

大神洗礼第四讲——函数相关及编程技巧

练习:

< 1 >、无参数的情况(不在堆栈上展开)

< 2 >、有参数的情况(在堆栈上展开)

继续阅读