概念

两个都是寄存器

pc(program counter)程序计数器

SP (stack pointer)堆栈指针

原理

pc 存放下一条指令的寄存器,cpu从内存中拿指令 ,寄存器是属于cpu的一部分,不属于内存

sp 堆栈指针,本质是寄存器,指向堆栈的顶部,

爬论坛:https://www.cnblogs.com/uestcliming666/p/11488782.html

假设有如下函数Fun

Fun()

{

…………………

Sub-fun(a, b);

…………………

}

cpu执行程序时的逻辑和步骤如下:

前提储备知识:

单片机对于堆栈的内存分配,一般栈空间由cpu自行分配,堆空间程序员可以用malloc进行申请,

栈空间一般储存非malloc分配的局部变量,全局变量和静态变量保s存在.date区域。一般对于函数内的局部变量,都保存在栈空间中,栈空间自动分配,自动释放,堆空间需要程序员自己free。

基于以上共识,开始对程序进行分析

执行CPU指令call,CPU会把目前PC寄存器的值push到stack 栈中,这个动作意味着存储返回地址。(很重要,要返回,向下)

cpu将参数a,b入栈,即根据CPU SP寄存器的值,把a、b的值存入SP指向的地址,并把SP减1(栈通常从高地址向低地址生长)。注意是减一不是加一

cpu把pc寄存器的值指向子函数的地址,则下一个被执行的代码就是sub-fun的第一句

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

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

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

补充

堆栈和寄存器的关系,寄存器是内存吗

堆栈(Stack)和寄存器(Registers)是计算机体系结构中的两个不同的概念,它们在处理数据和控制程序流程方面扮演着不同的角色。

堆栈(Stack):

堆栈是计算机内存中的一部分,用于存储临时数据,如局部变量、函数参数、返回地址等。它遵循后进先出(LIFO)的原则,即最后推入(push)堆栈的数据会最先被弹出(pop)。

在函数调用时,当前函数的局部变量和参数会被推入调用者的堆栈帧(stack frame),当函数返回时,这些数据会被弹出,同时恢复调用者的程序计数器和栈指针。

寄存器(Registers):

寄存器是CPU内部的一组高速存储单元,用于存储指令、数据和地址等信息。寄存器的访问速度远远快于内存,因此它们被用来存储当前正在处理的数据和指令。

寄存器的种类很多,包括通用寄存器、浮点寄存器、指令指针寄存器(如程序计数器PC)、栈指针寄存器(如SP)和帧指针寄存器(如FP)等。其中,栈指针寄存器(SP)和帧指针寄存器(FP)与堆栈管理密切相关。

寄存器与内存的关系:

寄存器不是内存,它们是CPU的一部分,具有极快的访问速度。寄存器用于存储当前执行的指令和处理的数据,而内存(包括堆栈)则用于存储程序的代码、全局变量、静态数据以及在一定时间内不会被频繁访问的数据。

寄存器与堆栈的关系:

堆栈是内存的一部分,而寄存器(特别是栈指针寄存器SP)用于指向当前堆栈的顶部。当数据被推入堆栈时,SP寄存器的值会相应减少,指向新的堆栈顶部;当数据从堆栈弹出时,SP寄存器的值会增加,指向新的堆栈顶部。

在函数调用过程中,寄存器(如SP)和堆栈紧密协作,以确保函数的参数、局部变量和返回地址得到正确的管理。

总结来说,寄存器是CPU内部的高速存储单元,用于快速访问和处理数据;堆栈是内存的一部分,用于存储临时数据和控制信息。两者在程序执行过程中相互配合,但它们的功能和存储位置是不同的。


十大餐饮点菜系统如何选择?哪个好?
游戏专区问道台湾版