[英]How does this disassembly correspond to the given C code?
環境:適用於ARM Cortex m4f的GCC 4.7.3(arm-none-eabi-gcc)。 裸機(實際上是MQX RTOS,但這無關緊要)。 CPU處於Thumb狀態。
這是我正在查看的一些代碼的反匯編程序列表:
//.label flash_command
// ...
while(!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}
// Compiles to:
12: bf00 nop
14: f04f 0300 mov.w r3, #0
18: f2c4 0302 movt r3, #16386 ; 0x4002
1c: 781b ldrb r3, [r3, #0]
1e: b2db uxtb r3, r3
20: b2db uxtb r3, r3
22: b25b sxtb r3, r3
24: 2b00 cmp r3, #0
26: daf5 bge.n 14 <flash_command+0x14>
常量(在擴展宏等之后)是:
address of FTFE_FSTAT is 0x40020000u
FTFE_FSTAT_CCIF_MASK is 0x80u
這是使用NO優化(-O0)進行編譯的,因此GCC不應做任何花哨的事情...但是,我沒有得到此代碼。 答案后編輯:永遠不要做這個。 我的問題是關閉優化后會產生一種錯誤的安全感。
我讀過“ uxtb r3,r3”是截斷32位值的常用方法。 為什么要截斷兩次然后進行符號擴展? 到底這與C代碼中的位屏蔽操作等效嗎?
我在這里想念什么?
編輯:涉及的事物的類型:因此FTFE_FSTAT的實際宏擴展可以歸結為
((((FTFE_MemMapPtr)0x40020000u))->FSTAT)
結構定義為
/** FTFE - Peripheral register structure */
typedef struct FTFE_MemMap {
uint8_t FSTAT; /**< Flash Status Register, offset: 0x0 */
uint8_t FCNFG; /**< Flash Configuration Register, offset: 0x1 */
//... a bunch of other uint_8
} volatile *FTFE_MemMapPtr;
兩條uxtb
指令是愚蠢的編譯器,如果您打開優化功能,則應該對其進行優化。 sxtb
是一種出色的編譯器,它使用了在未優化的代碼中不會出現的技巧。
第一個uxtb
是由於您從內存中加載了一個字節。 編譯器會將寄存器r3的其他24位清零,以便字節值填滿整個寄存器。
第二個uxtb
是由於您要與8位值進行“與” uxtb
。 編譯器意識到結果的高24位始終為零,因此它使用uxtb
清除高24位。
uxtb
指令都沒有任何用處,因為sxtb
指令無論如何sxtb
覆蓋r3
的高24位。 在啟用優化的情況下進行編譯時,優化器應意識到並刪除它們。
sxtb
指令將您關心的一位0x80
移到寄存器r3
的符號位。 這樣,如果將位0x80
置1,則r3
變為負數。 因此,現在編譯器可以將其與0
進行比較,以確定是否設置了該位。 如果未設置該位,則bge
指令分支回到while
循環的頂部。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.