The stack frame at the top of the stack is for the currently executing routine. The stack frame usually includes at least the following items (in push order):

  • the arguments (parameter values) passed to the routine (if any);
  • the return address back to the routine's caller (e.g. in the DrawLine stack frame, an address into DrawSquare's code); and
  • space for the local variables of the routine (if any).

 

Call stack layout

Stack and frame pointers[edit]

When stack frame sizes can differ, such as between different functions or between invocations of a particular function, popping a frame off the stack does not constitute a fixed decrement of the stack pointer. At function return, the stack pointer is instead restored to the frame pointer, the value of the stack pointer just before the function was called. Each stack frame contains a stack pointer to the top of the frame immediately below. The stack pointer is a mutable register shared between all invocations. A frame pointer of a given invocation of a function is a copy of the stack pointer as it was before the function was invoked.[2]

The locations of all other fields in the frame can be defined relative either to the top of the frame, as negative offsets of the stack pointer, or relative to the top of the frame below, as positive offsets of the frame pointer. The location of the frame pointer itself must inherently be defined as a negative offset of the stack pointer.

Storing the address to the caller's frame[edit]

In most systems a stack frame has a field to contain the previous value of the frame pointer register, the value it had while the caller was executing. For example, the stack frame of DrawLine would have a memory location holding the frame pointer value that DrawSquare uses (not shown in the diagram above). The value is saved upon entry to the subroutine and restored upon return. Having such a field in a known location in the stack frame enables code to access each frame successively underneath the currently executing routine's frame, and also allows the routine to easily restore the frame pointer to the caller's frame, just before it returns.

Lexically nested routines[edit]

Further information: Nested function and Non-local variable

Programming languages that support nested subroutines also have a field in the call frame that points to the stack frame of the latest activation of the procedure that most closely encapsulates the callee, i.e. the immediate scope of the callee. This is called an access link or static link (as it keeps track of static nesting during dynamic and recursive calls) and provides the routine (as well as any other routines it may invoke) access to the local data of its encapsulating routines at every nesting level. Some architectures, compilers, or optimization cases store one link for each enclosing level (not just the immediately enclosing), so that deeply nested routines that access shallow data do not have to traverse several links; this strategy is often called a "display".[3]

Access links can be optimized away when an inner function does not access any (non-constant) local data in the encapsulation, as is the case with pure functions communicating only via arguments and return values, for example. Some historical computers, such as the Burroughs large systems, had special "display registers" to support nested functions, while compilers for most modern machines (such as the ubiquitous x86) simply reserve a few words on the stack for the pointers, as needed.

Overlap[edit]

For some purposes, the stack frame of a subroutine and that of its caller can be considered to overlap, the overlap consisting of the area where the parameters are passed from the caller to the callee. In some environments, the caller pushes each argument onto the stack, thus extending its stack frame, then invokes the callee. In other environments, the caller has a preallocated area at the top of its stack frame to hold the arguments it supplies to other subroutines it calls. This area is sometimes termed the outgoing arguments area or callout area. Under this approach, the size of the area is calculated by the compiler to be the largest needed by any called subroutine.

最新文章

  1. Tween Animation---Scale渐变尺寸缩放动画
  2. window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法
  3. Swift基础语法(二)
  4. office2016各个版本 以及 解决visio搜索任何都提示无匹配项问题
  5. 37 网络相关函数(五)——live555源码阅读(四)网络
  6. 特性节点Attribute
  7. 根据数据库内容动态生成html页面
  8. 如何:在 Winform 动态启动、控制台命令行?
  9. JavaScript 数据类型转换(显式与隐式)
  10. jquery+easy ui 实现表格列头筛选
  11. python读取EXCLE文件数据
  12. ios发电子邮件
  13. Telnet 在win7 和 xp中的使用
  14. Version 1.7.0_80 of the JVM is not suitable for this product.Version: 1.8 or greater is required.
  15. js:基于原生js的上啦下啦刷新功能
  16. node.js之十大Web框架
  17. labelImg 工具
  18. Python args kwargs 技巧
  19. Python全栈问答小技巧_1
  20. postman测试post请求参数为json类型

热门文章

  1. Android GMS无法通过网络定位
  2. Justinmind使用教程(2)——计算表达式及条件用法
  3. 1062. Talent and Virtue (25)【排序】——PAT (Advanced Level) Practise
  4. java 翻页工具类
  5. cocos2dx游戏开发学习笔记2-从helloworld開始
  6. P2030 遥控车
  7. beego2---入门
  8. go8---函数function
  9. [odb-users] query results not being cached?
  10. 3-1 vue生存指南 - todolist实现-数据渲染