【Linux学习笔记】栈与函数调用惯例—下篇

本文深入探讨了Linux环境下栈与函数调用的惯例,包括栈帧结构、函数调用时的栈帧变化、寄存器使用约定以及函数调用惯例的细节。重点讲解了参数传递顺序、栈的维护方式和函数返回值的处理方法,帮助读者理解函数调用过程中的内存管理和效率优化。
摘要由CSDN通过智能技术生成

栈与函数调用惯例(又称调用约定)— 正篇

       在前篇笔记的基础上,本文继续介绍栈与函数调用约定的相关内容。

1. 函数调用的栈帧结构

        IA32程序用栈来实现函数调用。机器用栈来传递函数参数、保存返回地址、保存寄存器(即函数调用的上下文)及存储本地局部变量等。为单个函数调用分配的那部分栈称为栈帧(stack frame),栈帧的边界由2个指针界定:寄存器%ebp为帧指针(严谨的说法是,帧指针存放在%ebp中),指向当前栈帧的起始处,通常较固定;寄存器%esp为栈指针,指向当前栈帧的栈顶位置,当程序执行时,栈指针可以移动,因此大多数数据的访问都是相对于帧指针的。

        下图给出了栈帧的通用结构。

                             

        结合前篇笔记介绍的进程虚拟地址空间和上图的栈帧结构,我们可以看到,在经典的操作系统(如各种类UNIX操作系统)中,栈总是向下增长的,压栈(push)时栈顶地址减小,弹栈(pop)时栈顶地址增大。另外还可以注意到,堆通常是向上增长的,但在Windows系统中,大部分堆由HeapCreate()产生,而HeapCreate系列函数却完全不遵照堆向上增长的规律。

       下面根据函数调用中典型的栈帧结构,对函数调用栈的实现过程做如下描述:

        若函数P(调用者caller)调用函数Q(被调用者,callee),则Q的参数存放在P的栈帧中࿰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值