【发布时间】:2017-10-26 08:24:57
【问题描述】:
为什么在AVR汇编编程的程序开始时需要初始化栈指针
【问题讨论】:
-
我很困惑,什么链接?
标签: pointers avr stack-pointer
为什么在AVR汇编编程的程序开始时需要初始化栈指针
【问题讨论】:
标签: pointers avr stack-pointer
您的汇编程序正在调用一个子程序。当您这样做时,返回地址使用堆栈指针存储在堆栈中,因此初始化它以指向 RAM 中的适当位置很重要。 ATmega328P datasheet 说:
在中断和子程序调用期间,返回地址程序计数器 (PC) 存储在堆栈中。这 堆栈在通用数据 SRAM 中有效分配,因此堆栈大小仅受 SRAM 的总大小和 SRAM 的使用情况。所有用户程序都必须在复位例程中初始化 SP (在执行子程序或中断之前)。堆栈指针 (SP) 可在 I/O 空间中进行读/写访问。 数据 SRAM 可以通过 AVR 支持的五种不同寻址模式轻松访问 架构。
【讨论】:
非常简单,答案直接来自数据表 - 查找堆栈指针。堆栈指针初始值为 0x0000,表示如果未初始化,它将指向寄存器 R0(地址为 0x0000)。您不希望这样,因为您使用 R0 和其他寄存器来执行操作。这就是为什么要将堆栈设置为其他一些内存区域,特别是内部 SRAM(通用 RAM 区域)。
【讨论】:
这取决于您使用的微控制器。较旧的 AVR 的堆栈指针由硬件初始化为 0x0000。在使用子例程或中断之前,您必须将其更改为合理的内容(通常是RAMEND)。较新的 AVR 的堆栈指针由硬件初始化为 RAMEND,因此您不需要软件初始化。
您必须查看数据表以了解您的特定 MCU 是否需要该软件初始化。如有疑问,无论如何都要这样做:它不会造成伤害(它只需要 4 个 CPU 周期)并且它可以使您的代码更具可移植性。此外,引导加载程序可能更改了堆栈指针。
【讨论】: