我正在使用ARM Cortex-M0指令集编写汇编代码。由于我已将相当多的元素推入堆栈,有没有什么方法可以完全清除堆栈,而不是逐个弹出元素?一些指导意见将不胜感激
答案 0 :(得分:1)
如果要完全丢弃堆栈中的任何数据,例如,如果要调用永远不会返回的函数(并且已经获取了传入的任何参数的副本),那么您只需将SP设置为其初始值即可(或任何其他有效值)。但请记住,您将丢失最初存储在堆栈中的所有数据。
如果要将数据检索到寄存器,则需要LDM(LDMIA)指令。在M0上,您只能将数据加载到R0-R7(与M3 / 4不同)。 M0 / 1使用ARMv6-M指令集,M3使用ARMv7-M,M4使用ARMv7E-M。您正在使用的指令集的ARM通用用户指南应该有所帮助。
答案 1 :(得分:1)
要在@Realtime Rik的答案的第一部分添加一些附加信息,SP
(具体为MSP
)的初始值将从向量表中的第一个条目加载。根据您的微型和启动模式,矢量表的位置可能不同。
如果尚未重定位向量表(不复制此值),则可以使用以下伪C访问初始堆栈指针:
void * sp = *(SCB->VTOR);
SCB
包含一些核心配置寄存器,其中一个是VTOR
或向量表偏移寄存器。这基本上包含向量表的当前地址。通过解除引用该寄存器,我们访问VTOR
指向的表的第一个元素,这是应该存储初始堆栈指针的地方。
例如,如果您正在编写引导加载程序,则可以执行类似的操作,除了查看SCB->VTOR
之外,您需要查看指定应用程序的位置开始。 ST的USB Bootloader的示例代码如下:
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) USBD_DFU_APP_DEFAULT_ADD);
在这种情况下,它们具有向量表的默认地址,将其强制转换为指针,取消引用它读取表中的第一个条目,并将MSP
设置为该值。这只是在跳转到应用程序之前。