IAR之RAM的操作
轉自:http://www.cnblogs.com/pang123hui/archive/2011/12/01/2309828.html
SARM空間是AVR單片機最重要的部分,所有的操作必須依賴該部分來完成。變量在SARM空間的存儲模式有tiny,small,large 三種,也就是對應於__tiny, __near,__far三中存儲屬性。一旦選擇爲哪種存儲模式,對應的數據默認屬性也就確定了,但可以採用__tiny, __near,__far關鍵字來更改。
對於程序中的局部變量,編譯器會自動處理的,我們也不可能加什麼儲存屬性,但IAR提供了強大的外部變量定義。
IAR編譯器內部使用了部分工作寄存器,留給用戶的只有R4-R15供12個寄存器供用戶使用,要使用工作寄存器必須在工程選項裏打開鎖定選項。
例:
定義兩個變量使用工作寄存器R14,R15。
#include<iom8.h> __regvar __no_init char g @ 15; __regvar __no_init char P @ 14; void main(void) { g++; P++; }
在工程選項裏c/c++ complier>code裏打開要使用的寄存器R14-R15。
編譯結果就如下,看看是不是直接使用了寄存器做爲數據應用
// 4 void main(void) main: CFI Block cfiBlock0 Using cfiCommon0 CFI Function main // 5 { g++; REQUIRE ?Register_R14_is_global_regvar REQUIRE ?Register_R15_is_global_regvar INC R15 // 6 P++; } INC R14 RET
注意:定義在寄存器裏變量不能帶有初始值。最好不要使用超過9個寄存器變量,不然可能引起潛在的危險,因爲建立庫的時候沒有鎖定任何寄存器。
定義變量的絕對地址.沒有特性的變量是隨機分配的,要給變量分配地址必須加以特性修飾注意在定義地址的時候千萬不要和片內寄存器地址重合了。
定義沒有存儲特性的絕對地址變量必須加__no_init 或者const對象特性
__no_init char t @ 0x65;//定義在I/O地址以外
const char t @ 0x65;//定義只讀變量的地址
例:
#include<iom8.h> __no_init char u @ 0x65 ; void main(void) { u++; }
對應彙編:
void main(void) \ main: {u++;} \ 00000000 E6E5 LDI R30, 101 \ 00000002 E0F0 LDI R31, 0 \ 00000004 8100 LD R16, Z \ 00000006 9503 INC R16 \ 00000008 8300 ST Z, R16 \ 0000000A 9508 RET
帶存儲特性的關鍵字定義變量的絕對地址__io,__ext_io定義變量在i/o空間
#include<iom8.h> __io char u @ 0x65 ; void main(void) { u++; }
對應彙編:
void main(void) \ main: {u++;} \ 00000000 91000065 LDS R16, 101 \ 00000004 9503 INC R16 \ 00000006 93000065 STS 101, R16 \ 0000000A 9508 RET