异常条目时堆栈未与 8 字节对齐

问题描述 投票:0回答:1

我正在为我的 STM32F0 板编写一个迷你操作系统,该板具有基于 ARMv6-M 架构的 Cortex-M0 CPU。 特别是,在为调度程序创建进程队列后,我正在执行 msp/psp 切换。 当且仅当我已经完成切换时,对齐问题才会出现,否则它似乎不存在。

即使堆栈指针之前未对齐,ARMv6-M 架构也能保证异常条目时的 8 字节堆栈对齐。在我的陷阱处理程序中,我仔细检查了 sp 在异常进入时自动更改为 msp 并且它无论如何都没有对齐。

涉及的代码如下:

extern "C" fn kmain() -> ! {
    // initialization code
    Process::spawner().new(task).new(shell).spawn();
    // infinite loop waiting for interruptions
}

#[inline(always)]
pub fn spawn(self) {
    unsafe {
        // Initialize the current process with the first one
        // when we're terminating the builder
        CURR_PROC.write(ptr::read(PROC_LIST.0));
    }

    Scheduler::init(self.idle_task_stack); // <--- THIS LINE
    SysTick::enable();
}

#[inline(always)]
pub fn init(psp: *mut u8) {
    unsafe {
        // Set PSP as default stack, flush the pipeline
        //  standard procedure. Using barriers.
        _switch_to_psp(psp); // <--- THIS LINE
    }
}
.global _switch_to_psp
.thumb
.thumb_func
_switch_to_psp:
    MSR psp, r0
    MOV r1, #2
    MSR CONTROL, r1
    ISB
    BX lr

只需注释突出显示的行,当系统定时器中断触发时,msp 就会正确对齐到中断处理程序中的 8 个字节,即使以前没有触发。 请注意,我正在检查程序集包装器和 Rust 处理程序中的这些寄存器,以确保处理程序序言不会使堆栈错位,但事实并非如此。 (我内联每个函数,因为堆栈指针在调用和返回之间发生变化,因此尾声会破坏所有内容。)

您对为什么会发生这种情况有任何提示吗?

assembly arm embedded cortex-m stack-pointer
1个回答
0
投票

我得出的结论是,对齐的堆栈不是当前堆栈,而是异常条目之前的堆栈,因此我不应该担心。

有一段模棱两可的段落提到:

CCR.STKALIGN 位指示作为异常条目的一部分,处理器是否将 SP 对齐到 4 字节或 8 字节

这让我将 SP 视为当前堆栈指针。然而,更仔细地研究,我找到了更好的解释:

在异常入口处,异常入口顺序确保在异常入口之前使用堆栈指针 具有 8 字节对齐方式,必要时可调整其对齐方式

© www.soinside.com 2019 - 2024. All rights reserved.