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. python机器学习——感知器

    最近在看机器学习相关的书籍,顺便把每天阅读的部分写出来和大家分享,共同学习探讨一起进步!作为机器学习的第一篇博客,我准备从感知器开始,之后会慢慢更新其他内容. 在实现感知器算法前,我们需要先了解一下神 ...

  2. 二、安装JDK - Java软件的安装

    jdk是 Java 语言的软件开发工具包,主要用于移动设备.嵌入式设备上的java应用程序. 1.安装包的下载:http://pan.baidu.com/s/1mgh58ve (该安装包是绿色的,解压 ...

  3. 『题解』Codeforces2A Winner

    Portal Portal1: Codeforces Portal2: Luogu Description The winner of the card game popular in Berland ...

  4. MySQL系列:Windows 下 MySQL 8.X 的安装

    之前一直使用的是MySQL5.7,但由于MySQL增加了一些新特性,所以选择了更新. 下载MySQL 进入MySQL官网下载地址,选择Windows (x86, 64-bit), ZIP Archiv ...

  5. 使用Git-Rebase合并多次提交

    在平时的软件开发中,我们每个team使用一个公共仓库(这里说的是Git仓库).每当有一个新的需求,我们会拉出一个特性分支,然后在这个特性分支上做开发以及提交个人的代码. 我有个习惯就是:为了确保代码的 ...

  6. python函数的基本语法<二>

    函数的流程控制: if...else... a = 100 b = 200 if a == 100 and b ==300: print('100,200') elif b == 200: print ...

  7. 深入理解计算机系统 第八章 异常控制流 Part2 第二遍

    第二遍读这本书,每周花两到三小时时间,能读多少读多少(这次看了第 508~530 页,共 23 页) 第一遍对应笔记链接 https://www.cnblogs.com/stone94/p/10206 ...

  8. kubernetes实战(二十八):Kubernetes一键式资源管理平台Ratel安装及使用

    1. Ratel是什么? Ratel是一个Kubernetes资源平台,基于管理Kubernetes的资源开发,可以管理Kubernetes的Deployment.DaemonSet.Stateful ...

  9. js的split()和join()的用法

    split() 方法用于把一个字符串分割成字符串数组.split[splɪt]:vt. 分离:使分离:劈开:离开:分解 stringObject.split(separator,howmany) se ...

  10. PHP 富文本解码为 HTML 并显示

    PHP 富文本解码为 HTML 并显示 使用  html_entity_decode 函数 参考文档 PHP实例: // html_entity_decode(待解码内容, 如何处理引号) html_ ...