簡體   English   中英

Cortex-m4 asm vs cortex-m0 asm

[英]Cortex-m4 asm vs cortex-m0 asm

如何將 CM4 的這個匯編代碼重寫為 CM0? 這是來自 FreeRTOS 頁面的硬故障處理示例。 它檢查在硬故障發生之前哪個堆棧指針處於活動狀態,並提供指向堆棧寄存器開頭的指針:

" tst lr, #4                                                \n"
" ite eq                                                    \n"
" mrseq r0, msp                                             \n"
" mrsne r0, psp                                             \n"
" ldr r1, [r0, #24]                                         \n"
" ldr r2, handler2_address_const                            \n"
" bx r2                                                     \n"
" handler2_address_const: .word prvGetRegistersFromStack    \n"

如果沒有任何更改,它會產生多個錯誤:

 Error: unshifted register required -- tst r0,#4''
 Error: selected processor does not support 'ite eq' in Thumb mode
 Error: Thumb does not support conditional execution
 Error: Thumb does not support conditional execution
 Error: invalid offset, target not word aligned (0x00000002)
 Error: invalid offset, value too big (0x00000002)

我嘗試過的:

以這種方式替換tst並刪除IT

" mov r1, lr\n"
" lsr r0, r1, #3\n"    // Replace tst with lsr and cmp
" cmp r0, #1\n"
" mrseq r0, msp\n"     // <- Error: Thumb does not support conditional execution
" mrsne r0, psp\n"     // <- Error: Thumb does not support conditional execution

好的。 啟用稱為統一語法的東西:

".syntax unified\n"
".thumb\n"
" mov r1, lr\n"
" lsrs r0, r1, #3\n"  // tst gives "Can not honor suffix width" so replaced it with lsrs and cmp
" cmp r0, #1\n"
" ite eq\n"          // <- Error: selected processor does not support `ite eq' in Thumb mode. If I remove it compiler states that mrseq must be in IT block
" mrseq r0, msp\n"
" mrsne r0, psp\n"
" ldr r1, [r0, #24]\n"
" ldr r2, handler2_address_const\n"
" bx r2\n"
" handler2_address_const: .word prvGetRegistersFromStack\n"

這些錯誤的原因是什么以及如何修復它們? 仍然不知道導致對齊問題的原因。

當然,CM0 不支持某些指令。 但我不明白錯誤“Thumb 不支持條件執行”以及如何在沒有條件執行的情況下生存。

還有錯誤“不能接受寄存器寬度”是什么意思,以及為什么在啟用統一語法時會發生這種情況。 據我了解,它是關於 16/32 位指令的。 嘗試添加 .W 后綴,但出現另一個錯誤。

Cortex-M0 顯然根本不支持預測; 沒有條件執行。 顯而易見的選擇是分支。

您的 lsrs 序列看起來沒有正確實現測試正確的位或測試單個位。 看起來這取決於所有更高的位為零。

GCC 輸出https://godbolt.org/z/aphU5G展示了一種巧妙的方法,可以通過一個移位指令在單個位上進行分支: lsls r3, r0, #29 bpl .skip - 將位移至符號位,其中僅根據該位設置標志。 r3目標可以是任何可編碼的虛擬寄存器; 你不在乎價值; 你只想要標志設置。

暫無
暫無

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

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