vc如何返回函数结果及压栈参数
首先说明,本文的分析对象是运行在IA32平台上的程序,试验用的编译器是Visual C++ 6.0中的cl.exe(Microsoft 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86)。IA32程序利用程序堆栈来支持过程(procedure)调用,比如创建局部数据、传递参数、保存返回值信息、保存待今后恢复的寄存器等。为了一个过程调用而分配的堆栈空间称为一个stack frame。最顶层的stack frame由两个寄存器标识:ebp保存stack frame的基址,esp保存栈顶地址,因为在过程执行的时候栈顶寄存器的值会经常变化,所以绝大多数的信息都是通过ebp来相对寻址的。图1描绘了stack frame的基本结构。注意在IA32机器上,栈是向低地址方向增长,所以栈顶的地址值小于等于栈底的地址值。stack "bottom"________________ ______| | || . | || | || . | || | |--->Earlier frames| . | || | || . | || | | || |________________|__|___| | . | || | . | || | . | |Decreasing |________________| |address | Argument n | || 4m-->|________________| || (m为整数) | . | |-->Caller's frame| | . | || |________________| || | Argument 1 | || +8-->|________________| |V | Return address | |+4-->|________________|__|___| Saved ebp | |Frame Pointer-->|________________| |ebp |Saved registers| ||local variables| || and | |-->Current frame| temporaries | ||________________| || Argument | || build area | |Stack pointer-->|________________|__|___esp stack "top"图1调用C函数时,不管参数类型如何(包括浮点和struct类型)调用者(caller)负责从右至左将参数依次压栈,最后压入返回地址并跳转到被调函数入口处执行,其中每个参数都要按4字节地址对齐。按照地址来说被传递的参数和返回地址都是位于调用者stack frame中的。如果函数的返回值类型是整型(包括char,short,int,long及它们的无符号型)或指针类型的话,那么就利用EAX寄存器来传回返回值。请看下面的函数:long foo_long(long offset){long val = 2006 + offset;return val;}用 /c /Od /FAsc 的编译选项(下文均同)编译出如下的汇编码:PUBLIC _foo_long_TEXT SEGMENT_offset$ = 8_val$ = -4_foo_long PROC NEAR; 38 : {push ebp ;保存调用者的stack frame基址mov ebp, esppush ecx; 39 : long val = 2006 + offset;mov eax, DWORD PTR _offset$[ebp]add eax, 2006mov DWORD PTR _val$[ebp], eax; 40 : return val;; 将返回值保存进eax寄存器mov eax, DWORD PTR _val$[ebp]; 41 : }mov esp, ebppop ebpret 0_foo_long ENDP_TEXT ENDS如果函数返回的是结构体数据(非结构体指针)那得通过哪个中转站传递呢?这就要分三种情况:1、结构体大小不超过4字节,那么仍然使用EAX寄存器传递返回值。比如:/* 4字节大小结构体 */typedef struct small_t{char m1;char m2;char m3;char m4;} small_t;small_t create_small(void){small_t small = {'s','m','a','l'};return small;}void call_small(void){small_t small_obj = create_small();}编译出的汇编码是:;create_small函数PUBLIC _create_small_TEXT SEGMENT_small$ = -4_create_small PROC NEAR; 16 : {push ebpmov ebp, esppush ecx; 17 : small_t small = {'s','m','a','l'};mov BYTE PTR _small$[ebp], 115 ; 00000073Hmov BYTE PTR _small$[e补充:软件开发 , Vc ,
上一个:VC常用数据类型使用转换详解
下一个:VC++中对话框数据交换
- 更多VC++疑问解答:
- VC++ 算法。
- MFC CListCtrl获取列数出错了,怎么回事?
- 谁有VC++6.0企业版中文版的下载地址
- vc++,关于TextOut的一个小问题
- 定义一个三维的CStringArray//一定要使用CArray模板?那操作的时候,使用那个类的函数对数组进行操作呢?
- 关于mfc消息映射的问题
- MFC中用TextOut输出的问题
- 请问如何在VC6.0里MFC下对万年历进行编程
- iArray.Add(iValue);//Add函数的参数不可以用CArray模板???
- 'USES_CONVERSION' : undeclared identifier;'A2W' : undeclared identifier
- vc6.0能不能用CImage,能的话给个例子,以及atlimage.h,
- VC 对话框 标题栏 怎么变成这个样子????如图!
- spin控件的UDN_DELTAPOS消息//下面代码什么作用? [
- VC修改DNF
- vc 套接字 struct