首页 > 其他分享 >单片机开发中pc和sp的作用

单片机开发中pc和sp的作用

时间:2024-03-01 14:47:14浏览次数:22  
标签:SP pc sp 单片机 地址 内存 寄存器 堆栈 CPU

概念

两个都是寄存器
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执行程序时的逻辑和步骤如下:
前提储备知识:

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

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

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

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

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

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

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

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

补充

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

  2. 堆栈(Stack)

    • 堆栈是计算机内存中的一部分,用于存储临时数据,如局部变量、函数参数、返回地址等。它遵循后进先出(LIFO)的原则,即最后推入(push)堆栈的数据会最先被弹出(pop)。
    • 在函数调用时,当前函数的局部变量和参数会被推入调用者的堆栈帧(stack frame),当函数返回时,这些数据会被弹出,同时恢复调用者的程序计数器和栈指针。
  3. 寄存器(Registers)

    • 寄存器是CPU内部的一组高速存储单元,用于存储指令、数据和地址等信息。寄存器的访问速度远远快于内存,因此它们被用来存储当前正在处理的数据和指令。
    • 寄存器的种类很多,包括通用寄存器、浮点寄存器、指令指针寄存器(如程序计数器PC)、栈指针寄存器(如SP)和帧指针寄存器(如FP)等。其中,栈指针寄存器(SP)和帧指针寄存器(FP)与堆栈管理密切相关。

寄存器与内存的关系

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

寄存器与堆栈的关系

  • 堆栈是内存的一部分,而寄存器(特别是栈指针寄存器SP)用于指向当前堆栈的顶部。当数据被推入堆栈时,SP寄存器的值会相应减少,指向新的堆栈顶部;当数据从堆栈弹出时,SP寄存器的值会增加,指向新的堆栈顶部。
  • 在函数调用过程中,寄存器(如SP)和堆栈紧密协作,以确保函数的参数、局部变量和返回地址得到正确的管理。

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

标签:SP,pc,sp,单片机,地址,内存,寄存器,堆栈,CPU
From: https://www.cnblogs.com/codedingzhen/p/18046537

相关文章

  • VMware vSphere 8.0 Update 2b 下载 - Broadcom VMware 首次重大更新
    VMwarevSphere8.0Update2b下载-BroadcomVMware首次重大更新VMwarevSphere8.0Update2b下载-企业级工作负载平台2月29日(北京时间3月1日),VMwarebyBroadcom停更5个月后,终于发布了首次重大更新!ESXi8.0U2&vCenterServer8.0U2请访问原文链接:https:......
  • spring cloud gateway使用 uri: lb://方式配置时,服务名的特殊要求
    在gateway中配置uri配置有三种方式,包括第一种:ws(websocket)方式:uri:ws://localhost:9000第二种:http方式:uri:http://localhost:8130/第三种:lb(注册中心中服务名字)方式:uri:lb://brilliance-consumer  其中ws和http方式不容易出错,因为http格式比较固定,但是lb方式比......
  • SpringBoot定时任务:使用shedlock解决SpringBoot分布式定时任务
    第一步:引入shedlock包maven中pom文件添加如下配置:<dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-spring</artifactId><version>4.33.0</version>使用其他版本</dependency>第二步:添加shedlock-p......
  • KubeSphere 社区双周报|2024.02.01-02.29
    KubeSphere社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过commit的贡献者,并对近期重要的PR进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。因假期,上期双周报停更,因此本次双周报会包含四周的内容。本次双周报涵盖时间为:2......
  • Rust的Display和ToString:将对象转换为字符串
    在写代码的时候,我们经常需要将对象输出到屏幕上,或者转换为字符串;在Python中,我们可以为类型定义魔法函数__str__,print和str()都会调用它;在C++中,我们可以为对象重载ostream&operator<<(ostream&os)函数,使用ostringstream、fstream和cout的时候会调用它。在Rust中该实现什么,想必大......
  • 为什么会有幽灵空白元素,display:inline/inline-block会出现空隙的原因
    display:inline-block样式会在一些情况下产生间隙,这通常是由于元素之间的空白符或换行符所致。具体来说,以下情况可能导致display:inline-block元素之间出现间隙:HTML源代码中的换行符和空格:如果display:inline-block元素之间有换行符或空格,浏览器会将这些空白符解释为......
  • 界面控件Telerik UI for ASP. NET Core教程 - 如何为网格添加上下文菜单?
    TelerikUIforASP.NETCore是用于跨平台响应式Web和云开发的最完整的UI工具集,拥有超过60个由KendoUI支持的ASP.NET核心组件。它的响应式和自适应的HTML5网格,提供从过滤、排序数据到分页和分层数据分组等100多项高级功能。上下文菜单允许开发者为应用程序的最终用户提供额外的......
  • Spring Boot + liteflow 规则引擎,太香了!
    作者:豫州牧链接:https://juejin.cn/post/72967717700987453441、前言在日常的开发过程中,经常会遇到一些串行或者并行的业务流程问题,而业务之间不必存在相关性。在这样的场景下,使用策略和模板模式的结合可以很好的解决这个问题,但是使用编码的方式会使得文件太多,在业务的部分环......
  • Spring @Configuration 和 @Component 区别
    Spring@Configuration和@Component区别一句话概括就是@Configuration中所有带@Bean注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。 @Configuration注解:@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic@......
  • springboot应用中根据特定条件使用CommandLineRunner
    PS使用SpringBoot3.1.2进行测试1.使用@ConditionalOnProperty仅当特定属性存在或具有特定值时,注释@ConditionalOnProperty才会创建bean。在此示例中,仅当或文件中的CommandLineRunner属性db.init.enabled设置为true时才会执行application.propertiesapplication.ymlpac......