数的局部变量、全局变量、形参和实参的关系

从现在到寒假的这段时间内,笔者会进行数据结构的学习,要想学好数据结构的话,需要了解基本的概念,比如说局部变量和全局变量是在内存的什么位置放着 汇编语言的代码段和数据段里面会存放什么(因为c语言预处理 编译 汇编 链接的过程中会生成对应的汇编语言) 还有实参与形参的关系。

堆栈的初步了解

函数的局部变量、全局变量、形参和实参的关系,要涉及到内存中的一些概念:
1、系统堆栈空间
2、系统堆空间
3、代码区和数据区

堆栈的大致概念和特点:
堆栈在OS中的作用(在函数调用关系中的作用):
main( ) -> fun1( ) -> fun2( ) -> fun3( ) -> fun4( )
当fun4函数结束执行后,应该返回哪个函数?
一定是fun3

如图,堆栈就像一个子弹夹
堆栈像极了子弹夹
当main函数调用fun1时,会先将main函数的下一步要执行的指令地址入栈,简称main,但是,这个main的
本质是,当fun1回来后应该执行的main函数下一条指令的首地址!

系统堆栈区

系统堆栈区,仅仅是一段存储空间,或许还可以是多段存储空间,但每一个瞬间只有一个“当前系统堆栈”。
系统堆栈存在一个由CPU管理的“栈底指针”:edp,其本质是寄存器。
系统堆栈还存在一个由CPU管理的“栈顶指针”:esp,其本质还是寄存器。
edp和esp的应用:
(1)汇编语言中的应用
汇编语言指令:push X;
将执行如下操作:
将X的值入系统堆栈
对esp自动减X所占用的长度,通常是4
汇编语言指令:popX;
将执行如下操作:
将系统堆栈栈顶元素的值,赋值给X
对esp自动加X所占用的长度,通常是4
(2)C语言中的应用
C语言中的函数调用语句:
fun(。。。)
其对应的汇编指令是:
call fun //注意这个fun本质是该函数的入口地址,其内部操作如下:
1、将call指令的下一条指令的首地址入系统堆栈,这会引起esp的减少。
2、以fun所表达的首指令为下一条指令地址,更改CPU的IP寄存器(指令指针寄存器,这个寄存器直接决定了当前程序到底执行那里的代码!)
只要改变计算机IP寄存器的值,计算机取的指令就不再是顺序往下取了,可以实现跳转。
ip的值不能通过汇编语言修改,它是被保护的,call才能修改它。

函数的局部变量、全局变量、形参和实参的关系

  • 形参与实参的关系:
    (1)全局变量和静态存储类变量所占用的空间,将被 “入栈” 到系统堆栈。
    (2)形参变量所占用的空间,其实就是对应实参的值在系统堆栈的空间。
    (3)这里就是 “ 值传递 ” 的实现过程。
  • 全局变量和静态存储类变量所占用的空间,是exe文件就指定好的空间。即,数据段空间。全局变量和静态变量在主函数运行之前就申请空间了。
  • 局部变量和形参变量(事实上,在c语言中我们就已经定义过:局部变量包括该函数的形参变量),占用的是系统堆栈空间。
  • 如果一个函数要调用另外一个函数,必然要进行call指令。call指令必须要入栈一个返回值地址(4字节的),任何函数保护上一个函数的系统栈底指针(4字节的)。所以得出一个结论:哪怕调用了一个函数,该函数是无参函数,且该函数没有任何的局部变量。都需要在系统堆栈中消耗8字节,其中4字节的返回地址,再4字节的上一个函数的栈底指针。结论:函数调用会消耗系统空间。
    如果是递归,而且不做限制,那么系统堆栈空间会消耗光,会出现系统堆栈溢满,让系统崩溃。函数调用是有代价的,这使得递归不是一个明智的决策。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值