首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >栈对齐与ISR

栈对齐与ISR
EN

Stack Overflow用户
提问于 2022-01-09 17:33:59
回答 1查看 206关注 0票数 0

如何确保ISR内部的堆栈对齐?arm C编译器在ISR中强制堆栈对齐吗?

例如,在我的理解中,函数中的局部变量被推到堆栈上。假设有一个由3个字节组成的char数组,然后调用一个ISR。在这个ISR中,另一个函数被调用,它需要堆栈的4字节对齐。

ARM编译器是修复了它还是坏了?

我提出这个问题的动机是,我在ISR中遇到了fprintf问题,我认为这可能是堆栈对齐问题。我正在为一个atsam3x设备进行编译,但是在这样的问题中没有那么多标签的空间。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-10 19:30:42

对于ARMv7M (包括atsam3x中的Cortex-M3 ),中断处理程序中的堆栈对齐由硬件控制。

首先,不可能使堆栈指针对齐任何小于4个字节的值。这是因为堆栈指针的下两位始终为零,任何指令都无法更改它们。编译器知道这一点,所以如果您创建char[3],它会将其舍入4字节。

如果CCR控制寄存器的STKALIGN位是0,那么这就是所发生的一切。堆栈指针对齐到中断处理程序函数的条目上的4个字节的倍数。

如果STKALIGN位为1,则硬件在进入中断时自动将堆栈对齐为8字节的边界。

在Cortex-M3上,CCR.STKALIGN的重置值为1,ARM强烈建议您不要更改它。

在ARM ABI中,调用方有责任对齐堆栈。这是因为有一个50:50的机会,它知道它已经对齐了什么都不做,所以这是更有效的。

如果您的编译器被配置为为ARM ABI生成代码,那么它将假设堆栈在任何外部链接函数的条目上正确地对齐到一个8字节的边界,而不生成任何代码来再次在被调用的函数中对齐它。

在ARMv7M (和v6M)上,使用裸函数作为中断处理程序是正常和正确的。没有一些评论中提到的ISR prolog/epilog。

所有这一切都意味着,只要您的编译器配置为使用ARM ABI,并且只要您没有更改CCR.STKALIGN的默认值,那么您的堆栈将始终正确地对齐。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70643854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档