簡體   English   中英

為什么我需要在LDR指令中從標簽中減去1?

[英]Why do I need to subtract 1 from label in LDR instruction?

我正在使用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字節)對齊。

當計算在拇指模式下定義的標簽的地址時,匯編器將自動設置最低有效位,因為它假定代碼標簽是分支目標而沒有別的。 因此,當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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM