[英]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字節)對齊。
當計算在拇指模式下定義的標簽的地址時,匯編器將自動設置最低有效位,因為它假定代碼標簽是分支目標而沒有別的。 因此,當StackBegin
和StackEnd
標簽被定義為代碼的一部分時,它們將具有LSB集。
要避免此問題,請確保在定義StackBegin
和StackEnd
標簽時匯編程序處於數據模式。
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.