【问题标题】:Why do I need to subtract 1 from label in LDR instruction?为什么我需要从 LDR 指令中的标签中减去 1?
【发布时间】:2019-12-31 10:05:17
【问题描述】:

我正在使用 IAR Embedded Workbench 开发 ARM Cortex-M4 处理器。当主堆栈溢出时,我得到一个总线故障。因此,我在汇编中编写了一个小函数来检查总线故障是否是由堆栈溢出引起的,设置堆栈指针并调用专用的堆栈溢出处理程序。

以下代码显示了该功能,并且可以正常工作。我的问题是我必须从两个 LDR 指令中的标签中减去 1,我不明白为什么。

StackBegin:     DC32        SFB(CSTACK) ; Start of main stack
StackEnd:       DC32        SFE(CSTACK) ; End of main stack
BusFault_Handler:
                LDR         R0, StackBegin-1 ; No idea why we need to subtract 1
                CMP         SP, R0
                IT  GT
                BGT         BusFault_Post_Handler   ; Call if SP is OK
                LDR         SP, StackEnd-1          ; On stack overflow, set SP to top of main stack; No idea why we need to subtract 1
                B           MainStackOverflow_Handler

如果我不减 1,LDR 指令会在标签后一个字节加载数据。 StackEnd 包含值 0x20000400,但 SP 加载为 0x5F200004,除非我从标签中减去 1。 0x5F 是 BusFault_Handler 中的第一个字节。

谁能解释为什么我需要减去 1。我是否配置错误。我已检查数据是否为字(4 字节)对齐。

【问题讨论】:

  • 程序内存中的两个常量可能没有正确对齐。尝试在两条DC32 指令之前添加ALIGN 2。此外,您需要IT HS(“无符号更高或相同”),因为指针是无符号的,并且最低堆栈地址SFB(CSTACK)有效地址。
  • 可能CSTACK 部分未按 4 对齐?在这两种情况下生成什么 asm 代码? StackEnd 包含值 0x20000400 你是怎么发现的?
  • 有可能是汇编器给标签地址加了1,因为标签在拇指模式下的文本部分。
  • @fuz - 非常好。根据IAR manual:“在使用 DC8、DC16 或 DC32 定义 Thumb 代码部分中的数据时,始终使用 DATA 指令,否则数据上的标签将设置位 0。”。实现目标的更简单方法是LDR R0, =(SFB(CSTACK))
  • 你最好清除位 0 (bic address, address, #1) 而不是减去 1。

标签: assembly arm cortex-m iar


【解决方案1】:

当为拇指模式下定义的标签计算地址时,汇编器将自动设置最低有效位,因为它假定代码标签是分支目标而不是其他任何东西。因此,当 StackBeginStackEnd 标签被定义为代码的一部分时,它们将设置 LSB。

为避免此问题,请确保在定义 StackBeginStackEnd 标签时汇编器处于数据模式。

        THUMB
BusFault_Handler:
        LDR         R0, StackBegin
        CMP         SP, R0
        IT  GT
        BGT         BusFault_Post_Handler   ; Call if SP is OK
        LDR         SP, StackEnd            ; On stack overflow, set SP to top of main stack;
        B           MainStackOverflow_Handler

        DATA
StackBegin:     DC32        SFB(CSTACK) ; Start of main stack
StackEnd:       DC32        SFE(CSTACK) ; End of main stack
        THUMB

【讨论】:

  • 非常感谢。我不知道为代码部分中的标签设置了 LSB。将它放在数据部分可以解决问题。
猜你喜欢
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多