CPU提供的栈机制

http://blog.sina.com.cn/s/blog_4caf02490100eqn3.html

CS:IP 中存放这当前指令的段地址和偏移地址。段寄存器SS:SP 指向栈顶元素。

3.7 CPU提供的栈机制

  现今的 CPU 中都有栈的设计, 8086 CPU 也不例外。 8086 CPU 提供相关的指令来以栈的方式访问内存空间。这意味着,我们在基于 8086 CPU 编程的时候,可以将一段内存当作栈来使用。

  8086 CPU 提供入栈和出栈指令,最基本的两个是 PUSH (入栈) 和 POP (出栈).比如: push ax 表示将寄存器 ax 中的数据送入栈中. pop ax 表不从栈顶取出数据送入 ax。 8086cpU 的入栈和出栈操作都是以字为单位进行的。

  下面举例说明,我们可以将 10000H ~ 1O00FH 这段内存当作栈来使用。

  图 3.9 描述了下面一段指令的执行过程:

CPU提供的栈机制

mov ax, 0123h
push ax
mov bx, 2266h
push bx
mov cx, 1122h
push cx
pop ax
pop bx
pop cx

  注意,字型数据用两个单元存放,高地址单元放高 8 位,低地址单元放低 8 位.

  读者看到图 3.9 所描述的 push 和 pop 指令的执行过程,是否有一些疑惑?总结一下,大概是这两个问题:

  其一,我们将 10000H ~ 1O00FH 这段内存当作栈来使用, CPU 执行 push 和 pop 指令时,将对这段空间按照栈的后进先出的规则进行访问。但是,一个重要的问题是, CPU 如何知道 10000H ~ 1O00FH 这段空间被当作栈来使用?

  其二, push ax 等入栈指令执行时,要将寄存器中的内容放入当前栈顶单元的上方,成为新的栈顶元素; pop ax 等指令执行时,要从栈顶单元中取出数据,送入寄存器中.显然, push 、pop 在执行的时候,必须知道哪个单元是栈项单元,可是,如何知道呢?

  这不禁让我们想起另外一个讨论过的问题,就是, CPU 如何知道当前要执行的指令所在的位置?我们现在知道答案,那就是 CS : IP 中存放这当前指令的段地址和偏移地址。现在的问题是: CPU 如何知道栈顶的位置?显然,也应该有相应的寄存器来存放栈顶的地址, 8086CPU 中,有两个寄存器,段寄存器 SS 和寄存器 SP ,栈顶的段地址存放在 SS 中,偏移地址存放在 SP 中。任意时刻, SS : SP 指向栈顶元素。 push 指令和 pop 指令执行时, CPU 从 SS 和 SP 中得到栈顶的地址。

  现在,我们可以完整地描述 push 和 pop 指令的功能了,例如 push ax :

  push ax 的执行,由以下两步完成:

  (1) SP = SP - 2 , SS : SP 指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶;
  (2) 将ax中的内容送入 SS : SP 指向的内存单元处. SS : SP 此时指向新栈顶.

  图 3.10 描述了 8086CPU 对 push 指令的执行过程。

CPU提供的栈机制


  从图中我们可以看出,8086CPU中,入栈时,栈顶从高地址向低地址方向增长。












<think>嗯,用户想了解嵌入式系统中的工作机制。首先,我需要回忆的基本概念,然后结合嵌入式系统的特点来展开。在计算机科学中是一种后进先出的数据结构,但在嵌入式环境中,它的实现和用途可能有所不同。 我记得在通用计算机中,用于函数调用、局部变量存储等。嵌入式系统通常资源有限,比如内存较小,处理器可能没有复杂的MMU,所以的管理会更关键。可能需要考虑的大小设置,溢出检测等问题。 接下来,应该分步骤解释的工作机制。首先,的结构,包括指针、帧。然后,函数调用时的入和出操作,比如保存返回地址、寄存器、局部变量等。此外,中断处理中的使用也是一个重点,因为嵌入式系统经常处理中断。 还要考虑不同处理器架构的影响,比如ARM和AVR可能有不同的操作方式。例如,ARM通常使用满减,而AVR可能有所不同。需要提到这些细节吗?用户可能对具体架构感兴趣,但作为概述,可能不需要太深入,但可以提及架构差异的影响。 溢出是嵌入式系统中的常见问题,可能导致系统崩溃或被攻击。需要解释溢出的原因和防护措施,比如静态分配大小、使用保护机制或硬件检测功能。 可能还需要比较静态分配和动态分配在嵌入式中的使用情况。由于资源限制,嵌入式系统通常避免动态内存分配,和堆都是静态预留的,但是自动管理的。 最后,应用实例有助于理解。例如,在实时操作系统中,每个任务可能有独立的空间,这样任务切换时需要切换指针。 需要确保语言通俗易懂,结构清晰,分点说明。可能的结构:定义、结构、函数调用流程、中断处理、溢出与防护、架构差异、应用实例。 检查是否有遗漏的关键点,比如在内存中的位置,通常位于RAM的高地址向下增长或低地址向上增长,取决于架构。这点对理解溢出很重要。 还要注意术语的中文表达是否正确,比如“指针”、“帧”、“压”、“弹”等。避免直接使用英文术语,除非必要。 最后,是否需要给出示例代码?可能不需要,但可以用伪代码或流程图说明函数调用时的操作。 总结:需要涵盖的基本结构、函数调用机制、中断处理、溢出问题及防护措施,以及嵌入式系统中的特殊考虑。</think>嵌入式系统中的工作机制可分为以下层次逐步解析: --- ### 一、的定义与核心作用 (Stack)是嵌入式系统中**连续的内存区域**,遵循**LIFO(后进先出)**原则,核心功能包括: 1. **函数调用**:保存返回地址、参数、局部变量 2. **中断响应**:保存处理器上下文(如程序计数器、状态寄存器) 3. **临时数据存储**:寄存器的自动保存与恢复 --- ### 二、的物理结构 ```plaintext 高地址 |----------------| ← 顶(SP初始位置) | 帧n | |----------------| | ... | |----------------| | 帧1 | |----------------| ← 底(内存分配起始点) 低地址 ``` - **指针(SP)**:始终指向当前顶位置 - **帧(Stack Frame)**:每个函数调用分配的独立数据块 --- ### 三、函数调用时的操作流程(以ARM Cortex-M为例) 1. **调用前准备** ```c int add(int a, int b) { int sum = a + b; return sum; } ``` - 调用`add(3,5)`时: - 参数压:`b=5` → `a=3`(按从右到左顺序) - 返回地址(PC+4)压 2. **帧创建** $$ \text{新SP} = \text{原SP} - (\text{局部变量大小} + \text{寄存器保存空间}) $$ 3. **函数返回时** - 恢复父函数的帧 - SP回退到调用前的地址 --- ### 四、中断场景的特殊处理 当发生硬件中断时: 1. **自动压**:CPU将`xPSR`, `PC`, `LR`, `R12`, `R3-R0`按顺序压入当前 2. **切换**(若使用RTOS):从任务切换到中断 3. **中断返回**:通过`BX LR`指令触发数据弹回寄存器 --- ### 五、嵌入式的典型问题与防护 | 问题类型 | 产生原因 | 防护措施 | |----------------|---------------------------|-----------------------------------| | **溢出** | 递归过深/局部变量过大 | 静态分析工具检测、增加保护区 | | **腐蚀** | 指针越界操作 | 启用编译器的保护选项(-fstack-protector) | | **多任务冲突** | 共享空间 | 为每个任务分配独立 | --- ### 六、嵌入式系统优化实践 1. **大小计算** 通过`-Wstack-usage`编译选项获取函数最大深度 ```bash arm-none-eabi-gcc -Wstack-usage -c main.c ``` 2. **内存布局配置**(链接脚本示例) ```ld MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K } _estack = ORIGIN(RAM) + LENGTH(RAM); /* 设置在RAM末端 */ ``` 3. **调试手段** - 填充魔术字(如`0xDEADBEEF`)检测溢出 - 通过JTAG/SWD接口实时监测SP寄存器值 --- ### 七、典型架构差异对比 | 特性 | ARM Cortex-M | AVR8 | |-----------------|------------------------|----------------------| | **增长方向** | 满递减(向低地址) | 空递增(向高地址) | | **硬件压** | 支持中断自动压 | 需手动保存关键寄存器 | | **双支持** | MSP(主)+ PSP(进程) | 单模式 | 通过以上机制理解,开发者可更安全地进行中断服务程序编写、RTOS任务分配等关键操作。实际项目中建议结合内存映射文件和调试器实时监控使用情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值