C语言基础-函数调用栈
来源:互联网 发布:昆山远洋数据怎么样 编辑:程序博客网 时间:2024/05/17 04:25
程序的执行流程,实际是连续的函数调用。函数调用通常使用堆栈实现,每个用户进程对应一个调用栈(call stack)结构。编译器使用堆栈传递函数参数、保存返回地址、临时保存寄存器原有值(即函数调用的上下文)以备恢复以及存储本地局部变量。
1 寄存器
寄存器用于存放程序执行中用到的数据和指令 EAX(Return value of function) EBX(Local variables) ECX(counter for shifting and string operation) EDX(Dividend for division operation) ESI(store local variables) EDI(store local variables) (通用寄存器),ESP(stack pointer) EBP(base pointer)。在X86处理器中,EIP是特殊寄存器,指向处理器下条等待执行的指令地址(代码段内偏移量),每次执行完相应汇编指令EIP值就会增加,因而不能像访问通用寄存器一样访问他,EIP可以被jmp, call, ret等指令隐含改变。ESP存放堆栈指针寄存器,存放执行函数对应栈帧的栈顶地址(系统栈顶部),且始终指向栈顶;EBP是栈帧基址指针寄存器,存放执行函数对应栈帧的栈底地址,用于C运行库访问栈中共的局部变量和参数。
栈寄存器是唯一能被所有函数共享的资源,虽然某一时刻只有一个函数在执行,但需要保证当某个函数调用其他函数时,被调用的函数不会修改或覆盖主调函数稍后会使用的寄存器值。主调函数保存寄存器(eax, ecx, edx )。
2 栈帧结构
栈帧(stack frame)指每个未完成运行函数占用的一个独立连续区域。函数调用经常是嵌套的,同一时刻,堆栈中会有多个函数信息。栈帧是堆栈的逻辑片段,当调用函数时逻辑栈被压入堆栈,当函数返回时逻辑栈从堆栈弹出。堆栈存放着函数参数、局部变量和恢复前一栈需要的数据。
编译器将控制权交给函数,将函数参数压入栈帧,并分配足够的内存空间用于存放函数中的局部变量。使用栈帧好处之一就是使递归变为可能,对函数的每次递归调用,都分配给函数一个新的栈帧,将当前调用和上次调用隔开。栈帧边界有栈帧基址指针和堆栈指针界定,函数中对大部分数据的访问都基于EBP进行。
高地址是栈帧基址,压栈就是把ESP指针逐渐往低地址移动的过程。结构体成员变量的入栈顺序与其在结构体中声明顺序相反。函数调用以值传递时,传入的实参和被调函数内操作的形参两者存储地址不同,因而被调函数无法直接修改主调函数实参值,为达到修改目的,需要向被调函数传递实参变量的指针(变量地址)。
- C语言基础-函数调用栈
- C语言函数调用栈
- C语言函数调用
- 【C语言】调用函数
- C语言函数调用
- 编程基础-----c语言打印调用栈
- 编程基础-----c语言打印调用栈
- C语言基础 函数
- C语言基础 函数
- C语言函数调用栈浅析
- C语言函数调用栈剖析
- C语言函数调用栈侦
- C语言函数调用栈剖析
- C语言函数调用栈一
- C语言函数栈调用二
- C语言函数栈调用三
- c语言函数调用栈的变化
- C语言函数调用栈剖析
- LeetCode Problem No'169 Majority Element
- 200万像素网络摄像机一天要多少容量
- Redis Sentinel 机制与用法
- 学习python[1] Python入门教程 超详细1小时学会Python
- intellij idea 上使用git提交代码
- C语言基础-函数调用栈
- Linux NFS服务器性能优化
- 逗号运算符
- 嵌入式面试题——ARM面试题(六)
- 从零开始学Java(二十)注解
- 《自顶向下法》学习笔记——第五章:链路、接入网和局域网
- 20170301-leetcode-215-Kth Largest Element in an Array
- HDU5247:找连续数(打表)
- Linux初学注意