// Register: BAUDCTL
extern volatile unsigned char BAUDCTL @ 0x09B;
#ifndef _LIB_BUILD
asm("BAUDCTL equ 09Bh");
#endif
@ sign是什麼?這是否意味着在地址0x09B處定義了一個不可緩存的無符號字符? 那麼爲什麼它需要彙編中的asm函數?以下定義在C中
// Register: BAUDCTL
extern volatile unsigned char BAUDCTL @ 0x09B;
#ifndef _LIB_BUILD
asm("BAUDCTL equ 09Bh");
#endif
@ sign是什麼?這是否意味着在地址0x09B處定義了一個不可緩存的無符號字符? 那麼爲什麼它需要彙編中的asm函數?以下定義在C中
這是一個編譯器擴展,而不是標準C的一部分。它將變量放在地址0x09b
上。它僅用於嵌入式平臺的一小部分編譯器,其中通常有用於硬件寄存器的變量。
此另一種常用的技術,在不支持在它們的聲明@
(即它們符合多個標準)編譯器是使用指針。然後,它會看起來像
volatile unsigned char *BAUDCTL = (unsigned char *) 0x09b;
這樣做的缺點是,波特控制寄存器現在佔用內存中的兩個地方,一個是實際的硬件寄存器,另一個用於指針變量。另一個缺點是你必須使用指針解引用操作符來訪問寄存器。
這不是標準的C,它是某種形式的擴展,所以它的含義取決於實現。但是,我會說你有一個很好的機會,並且基本上說明角色的地址是0x9b
。
這通常是如何在嵌入式系統中完成內存映射I/O的。
至於需要對asm
位,這同樣是假設(儘管受過良好教育的):你extern
可能定義BAUDCTL爲C
代碼,但是,如果你想以後asm
塊內使用另外,它可能需要彙編程序定義。從asm
區塊內部很難找到C的定義。
我認爲Microchip已經開始將其留給鏈接器。我不完全理解它,但我認爲他們編寫與頭文件相匹配的鏈接器腳本,因此您可以在代碼中使用這些名稱並將它們視爲內存映射寄存器,但仍會寫入適當的C. – detly