在 ARM Cortex 中,为局部变量分配空间时,堆栈指针会增加而不是减少

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

这是我的C代码

void user_main(void)
{
    u32 asd;

    osGetSysCnt(&asd);
}

这是拆解

void user_main(void)
{
10040230:   b507        push    {r0, r1, r2, lr}
    u32 asd;

    osGetSysCnt(&asd);
10040232:   a801        add r0, sp, #4
10040234:   f000 f801   bl  1004023a <osGetSysCnt>
}
10040238:   bd07        pop {r0, r1, r2, pc}

为什么堆栈指针会递增?这不会覆盖已经推送的寄存器吗?

c assembly arm stm32 cortex-m
1个回答
3
投票

为什么堆栈指针会递增?这不会覆盖 已经推送寄存器了吗?

否,因为

sp
在反汇编代码中并未递增。

10040232:   a801        add r0, sp, #4

add
的用途:
add
指令计算相对于sp(堆栈指针)当前值的内存地址。这里,
add r0, sp, #4
计算地址
sp + 4
,它指向变量
asd
在堆栈上的位置。 结果地址存储在
r0
中,然后作为参数传递给
osGetSysCnt

ARM栈不是全降序吗?含义 sp+4 指的是已经 推入开始寄存器。

是的。

push
指令正在创建足以满足函数需求的堆栈帧。编译器不关心那里有什么,因为 ABI 指定不必保留这些寄存器。所以这个
push
不保留任何东西。

为什么编译器使用

push
指令?它表明您正在启用大小优化的情况下进行编译 (
-Os
)。
push
虽短但耗时。 如果将优化级别更改为 优化速度
-Ofast
-O2
-O3
),编译器将发出不同的代码:

        str     lr, [sp, #-4]!
        ldr     r3, .L4
        sub     sp, sp, #12
        add     r0, sp, #4
        str     r3, [sp, #4]
        bl      osGetSysCnt
        add     sp, sp, #12
        ldr     lr, [sp], #4
        bx      lr

https://godbolt.org/z/7GY63r6vv

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