PC(program counter)是CPU中用于存放下一条指令地址的寄存器,SP为堆栈指针。下面将介绍函数调用过程中CPU对PC和SP这两个寄存器的操作。

假设有如下函数Fun

Fun()
{
…………………
Sub-fun(a, b);
…………………
}

当函数Fun调用其子函数sub-fun时,CPU内部执行情况如下:

1. 执行CPU指令push,将参数a、b入栈,即根据CPU SP寄存器的值,把a、b的值存入SP指向的地址,并把SP减1(栈通常从高地址向低地址生长)。

2. 执行CPU指令call,CPU会把目前PC寄存器的值push到heap中,这个动作意味着存储返回地址。

3. 接着CPU把PC寄存器的值设为函数sub-fun的地址,则下个被执行的指令就是函数sub-fun的第一行语句。

4. 当函数sub-fun在执行时,可以根据目前SP寄存器的值计算出参数a、b的地址。

5. 如果函数sub-fun有定义局部变量,这些变量的地址会从目前heap的顶端继续生长(这就是为什么我们在嵌入式开发时,总是会要求应用程序工程不要定义size太大的局部变量,否则容易导致栈溢出的原因)。

6. 当函数sub-fun执行完毕后,CPU会执行ret指令,这个命令会从heap顶端pop出返回地址——即调用sub-fun之前Fun函数执行到的语句的地址,然后更改PC寄存器的值为这个返回地址,则下个指令就会返回执行函数sub-fun的下一行语句,从而完成了函数调用。

程序计数器(PC)、堆栈指针(SP)与函数调用过程的更多相关文章

  1. 51单片机的堆栈指针(SP)

    堆栈指针(SP,Stack Pointer),专门用于指出堆栈顶部数据的地址. 那么51单片机的堆栈在什么地方呢?由于单片机中存放数据的区域有限,我们不能够专门分配一块地方做堆栈,所以就在内存(RAM ...

  2. 从一个新手容易混淆的例子简单分析C语言中函数调用过程

    某天,王尼玛写了段C程序: #include <stdio.h> void input() { int i; ]; ; i < ; i++) { array[i] = i; } } ...

  3. c函数调用过程原理及函数栈帧分析

    转载自地址:http://blog.csdn.net/zsy2020314/article/details/9429707       今天突然想分析一下函数在相互调用过程中栈帧的变化,还是想尽量以比 ...

  4. Keil C51里关于堆栈指针的处理

    Keil C是非常优秀的C51编译器,可能是最好的C51编译器,提供各种优化模式,对变量的优化和地址安排做得非常好.这是用C语言写代码的好处之一,如果用汇编写,得费一大番功夫给各个变量安排内存物理地址 ...

  5. Linux驱动调试-根据oops的栈信息,确定函数调用过程

    上章链接入口: http://www.cnblogs.com/lifexy/p/8006748.html 在上章里,我们分析了oops的PC值在哪个函数出错的,那如何通过栈信息来查看出错函数的整个调用 ...

  6. C语言的函数调用过程

    从汇编的角度解析函数调用过程 看看下面这个简单函数的调用过程: int Add(int x,int y) { ; sum = x + y; return sum; } int main () { ; ...

  7. (转)UCOSII在任务切换与出入中断时堆栈指针的使用

    1 uc/os ii在M3中的堆栈结构 1.1 M3入账序列  1.2 加上手工入栈序列  2 PendSV在Cortex-M3中的应用 Systick为嵌入到内核中,优先级比一般中断优先级高.若在一 ...

  8. 37.Linux驱动调试-根据oops的栈信息,确定函数调用过程

    上章链接入口: http://www.cnblogs.com/lifexy/p/8006748.html 在上章里,我们分析了oops的PC值在哪个函数出错的 本章便通过栈信息来分析函数调用过程 1. ...

  9. C语言的函数调用过程(栈帧的创建与销毁)

    从汇编的角度解析函数调用过程 看看下面这个简单函数的调用过程: int Add(int x,int y) { ; sum = x + y; return sum; } int main () { ; ...

随机推荐

  1. VM小技巧——虚拟机解决vm窗口太小的办法

    ——" 慢下来总结才能增大效率" 很多人在装虚拟机的时候,遇到了窗口过小不能自适应的问题.我也是查了好多资料,都说安装Vmware Tools即可解决,还有说修改分辨率也可以.两种 ...

  2. C++程序员学Python

    目录 C++程序员学Python 第二章.变量和数据类型 1.注释语句前用#: 2.常用于大小写函数: 第三章.列表 1.列表简述 2.修改,增加,插入,删除列表元素 第四章操作列表 1.遍历 2.创 ...

  3. 201871010114-李岩松《面向对象程序设计(java)》第四周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  4. JavaScript: 遍历Array的同时删除指定项

    一个简单的需求是,在遍历一个数组时,移除指定的项. 下列代码是不能正常工作的: var elements = [1, 5, 5, 3, 5, 2, 4]; for(var i = 0; i < ...

  5. 【Elasticsearch 7 探索之路】(三)倒排索引

    上一篇,我们介绍了 ES 文档的基本 CURE 和批量操作.我们都知道倒排索引是搜索引擎非常重要的一种数据结构,什么是倒排索引,倒排索引的原理是什么. 1 索引过程 在讲解倒排索引前,我们先了解索引创 ...

  6. java编程思想第四版第十一章习题

    第一题 package net.mindview.holding.test1; import java.util.ArrayList; import java.util.List; /** * 沙鼠 ...

  7. Python3.7.1学习(三)求两个list的差集、并集与交集

    在python3.7.1对列表的处理中,会经常使用到Python求两个list的差集.交集与并集的方法. 下面就以实例形式对此加以分析. # 求两个list的差集.并集与交集# 一.两个list差集# ...

  8. ZeroC Ice发送大数据

    继上文,我们使用ZeroC Ice传递大块数据时,通常有两种做法,一种是一次请求,另一种就是分多次请求(,这种做法在官方文档有例子).选哪一种根据需要而定. 当分多次请求来完成一大块数据,到底选择每次 ...

  9. AV时间戳dts,pts。从ffmpeg解码过程看过来。

    解码过程中,dts由媒体流读入的包推动(解码包中的dts标记),dts在前进.pts是在dts前进到某处(截点)而进行动作的标记. 物理时间自然流逝,dts可以被控制同步与物理时间同一脚步节奏,也可以 ...

  10. GitHub注册失败,卡在第一步

    同事说他无法注册GitHub,我一开始以为GitHub又无法登录进去,我就登录了自己的GitHub账号,没有问题,可以登录啊,见第一个标签页.同一局域网,不可能我能登录,你无法完成注册啊.于是,我就在 ...