MIPS架构上函数调用过程的堆栈和栈帧
转载于CSDN:http://blog.csdn.net/do2jiang/article/details/5404566
在计算机科学中,Call stack是指存放某个程序的正在运行的函数的信息的栈。Call stack和stack frames组成,每个stack frame对应于一个未完成运行的函数。
在当今流行的计算机体系架构中,大部分计算机的参数传递,局部变量的分配和释放都是通过操纵程序栈来实现的。栈用来传递函数参数,存储返回值信息,保存寄存器以供恢复调用前处理机状态。每次调用一个函数,都要为该次调用的函数实例分配栈空间。为单个函数分配的那部分栈空间就叫做stack frame,也就是说,stack frame这个说法主要是为了描述函数调用关系的。
Stack frame组织方式的重要性和作用体现在两个方面:
第一:它使调用者和被调用者达成某种约定。这个约定定义了函数调用时函数参数的传递方式,函数返回值的返回方式,寄存器如何在调用者和被调用者之间进行共享。
第二:它定义了被调用者如何使用它自己的stack frame来完成局部变量的存储和使用。

- 上图描述的是一种典型的(MIPS 32)嵌入式芯片的stack frame组织方式。
- 这张图中,计算机的栈空间采用的是向下增长的方式。
- sp(stack pointer)就是当前函数的栈指针,它指向的是栈底的位置。
- Current Frame所示即为当前函数(被调用者)的frame。
- Caller's Frame是当前函数的调用者的frame。
- 每个frame中所存放的内容和存放顺序,则由目标体系架构的调用约定(calling convention)定义。
- MIPS O32调用约定规定了所占空间不大于4个比特的参数应该放在从$4到$8的寄存器中,剩下的参数应该依次放到调用者stack frame的参数域中,并且在参数域中需要前四个参数保留栈空间。
- 如果被调用者需要使用$16到$23这些保留寄存器(saved register),就必须先将这些保留寄存器的值保存在被调用者stack frame的保留寄存器域中,当被调用者返回时恢复这些寄存器值。
- 当被调用者不是叶子函数时,即被调用者中存在对其它函数的调用,需要将RA(return address)寄存器($31)值保存到被调用者stack frame的返回值域中。
- 被调用者所需要的局部变量,应保存在被调用者stack frame的本地变量域中。
- 在没有BP(base pointer)寄存器的目标架构中,进入一个函数时需要将当前栈指针向下移动n比特,这个大小为n比特的存储空间就是此函数的stack frame的存储区域。此后栈指针便不再移动,智能在函数返回时再将栈指针上这个偏移量恢复栈现场。由于不能随便移动栈指针,所以寄存器压栈和出栈都必须指定偏移量。
- 在RISC计算机中主要参与计算的是寄存器,saved registers就是指在进入一个函数后,如果某个保存原函数信息的寄存器会在当前函数中被使用,就应该将此寄存器保存到堆栈上,当函数返回恢复此寄存器值。而且由于RISC计算机大部分采用定长指令或者定变长指令,一般指令长度不会超过32个位。而现代计算机的内存地址范围已经扩展到32位,这样在一条指令里就不足以包含有效的内存地址,所以RISC计算机一般借助于一个返回地址寄存器RA来实现函数的返回。几乎在每个函数调用中都会使用到这个寄存器,所以在很多情况下RA寄存器会被保存在堆栈上以避免被后面的函数调用修改,当函数需要返回时,从堆栈上取回RA然后跳转。移动SP和保存寄存器的动作一般处在函数的开头,叫做function prologue;恢复这些寄存器状态的动作一般放在函数的最后,叫做fuction epilogue。
MIPS架构上函数调用过程的堆栈和栈帧的更多相关文章
- c函数调用过程原理及函数栈帧分析
转载自地址:http://blog.csdn.net/zsy2020314/article/details/9429707 今天突然想分析一下函数在相互调用过程中栈帧的变化,还是想尽量以比 ...
- C函数调用过程原理及函数栈帧分析(转)
在x86的计算机系统中,内存空间中的栈主要用于保存函数的参数,返回值,返回地址,本地变量等.一切的函数调用都要将不同的数据.地址压入或者弹出栈.因此,为了更好地理解函数的调用,我们需要先来看看栈是怎么 ...
- 在C语言中函数及其调用过程
目录 函数 C语言中的变参函数 函数的本质是什么 内存区域的区分技巧 函数的调用过程 栈帧的概念 调用过程细节 按照约定传参 函数 如果一个函数有声明没实现,那么就会出现链接错误: 以上代码会出现链接 ...
- 第5篇-调用Java方法后弹出栈帧及处理返回结果
在前一篇 第4篇-JVM终于开始调用Java主类的main()方法啦 介绍了通过callq调用entry point,不过我们并没有看完generate_call_stub()函数的实现.接下来在ge ...
- Dubbo学习(六) dubbo 架构图 以及调用过程
一.Dubbo结构图 duubo结构图 我们解释以下这个架构图:Consumer服务消费者,Provider服务提供者.Container服务容器.消费当然是invoke提供者了,invoke这条 ...
- 代码 or 指令,浅析ARM架构下的函数的调用过程
摘要:linux程序运行的状态以及如何推导调用栈. 1.背景知识 1.ARM64寄存器介绍: 2.STP指令详解(ARMV8手册): 我们先看一下指令格式(64bit),以及指令对于寄存机执行结果的影 ...
- MIPS指令 MIPS架构
华中科技大学 - 计算机组成原理 华中科技大学 - 计算机硬件系统设计 Microprocessor without Interlocked Pipleline Stages 无内部互锁流水级的微处理 ...
- 如何在linux主机上运行/调试 arm/mips架构的binary
如何在linux主机上运行/调试 arm/mips架构的binary 原文链接M4x@10.0.0.55 本文中用于展示的binary分别来自Jarvis OJ上pwn的add,typo两道题 写这篇 ...
- Hbase的WAL在RegionServer基本调用过程
版权声明:本文由熊训德原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/221 来源:腾云阁 https://www.qclo ...
随机推荐
- Fantacy团队周一站立会议
词频分析模型 1.首先这次站会是周一开的,但是由于我个人的疏忽,没有落实到博客上,请见谅,连累了组长. 2.会议时间:2016年3月28日12:00~12:30. 持续时长:30分钟 会议参加成员:组 ...
- pandas缺失值处理
1.检查缺失值 为了更容易地检测缺失值(以及跨越不同的数组dtype),Pandas提供了isnull()和notnull()函数,它们也是Series和DataFrame对象的方法 - 示例1 im ...
- js對象
js聲明一個數據,即使沒有賦值,也是創建了一個對象: js的所有數據都是對象,對象裡面有屬性也有方法,屬性方法是對象中的成員: 訪問對象的屬性:objectname.屬性名 訪問對象的方法:objec ...
- python之datetime类
datetime.time时间类,一般用于显示当地时间 import datetime # 新建对象 datetime_obj = datetime.time(hour=12, minute=20, ...
- ceph 安装ceph问题汇总
1.在不同节点安装ceph时,出现以下异常: 参考这里 ceph deploy RuntimeError: NoSectionError: No section: 'ceph' 解决方法: 在报错的机 ...
- POJ1611-The Suspects-并查集
记录元素个数的并查集. 利用sz数组保存并查集的大小.每次union时,把小的集合并到大的中去,并更新sz数组. #include <cstdio> #include <algori ...
- java构造函数总结
构造函数总结 概念: 创建对象时由JVM自动调用的函数 作用: 在创建对象的时候给对象的成员变量赋值: 写法: 修饰符:可以用访问权限修饰符(public.private等)修饰:不能用s ...
- 自学Zabbix8.1 Regular expressions 正则表达式
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix8.1 Regular expressions 正则表达式 1. 配置 点击Adm ...
- Android 判定手机是否root
Android获取手机root的状态 package com.app.demo; import java.io.File; import android.app.Activity; import an ...
- 【BZOJ1820】[JSOI2010]快递服务(动态规划)
[BZOJ1820][JSOI2010]快递服务(动态规划) 题面 BZOJ 洛谷 题解 考虑无脑四维\(dp\).\(f[i][a][b][c]\),表示当前处理到第\(i\)个任务,三辆车的位置分 ...