C語言中的 @ 符號是什么意思?


Global Variable Address Modifier (@address)
You can assign global variables to specific addresses with the global variable address modifier. These variables are called 'absolute variables'. They are useful for accessing memory mapped I/O ports and have the following syntax:

Declaration = <TypeSpec> <Declarator>[@<Address>|@"<Section>"]
[= <Initializer>];
<TypeSpec> is the type specifier, e.g., int, char

<Declarator> is the identifier of the global object, e.g., i, glob

<Address> is the absolute address of the object, e.g., 0xff04, 0x00+8

<Initializer> is the value to which the global variable is initialized.

A segment is created for each global object specified with an absolute address. This address must not be inside any address range in the SECTIONS entries of the link parameter file. Otherwise, there would be a linker error (overlapping segments). If the specified address has a size greater than that used for addressing the default data page, pointers pointing to this global variable must be "__far". An alternate way to assign global variables to specific addresses is (Listing 8.8).

Listing 8.8 Assigning global variables to specific addresses

#pragma DATA_SEG [__SHORT_SEG] <segment_name>
setting the PLACEMENT section in the linker parameter file. An older method of accomplishing this is shown in Listing 8.9.

Listing 8.9 Another means of assigning global variables to specific addresses

<segment_name> INTO READ_ONLY <Address> ;
Listing 8.10 is a correct and incorrect example of using the global variable address modifier and Listing 8.11 is a possible PRM file that corresponds with example Listing.

Listing 8.10 Using the global variable address modifier
//看這意思,就是把int型變量glob地址從0x0500開始,並把值10初始化時放在0x0500
int glob @0x0500 = 10; // OK, global variable "glob" is
// at 0x0500, initialized with 10
void g() @0x40c0; // error (the object is a function)

void f() {
int i @0x40cc; // error (the object is a local variable)
}

 

全局變量地址修飾符(@address)
您可以使用全局變量地址修飾符將全局變量分配給特定地址。這些變量稱為“絕對變量”。它們對於訪問內存映射的I / O端口很有用,並具有以下語法:

聲明= <TypeSpec> <聲明符> [@ <地址> | @“ <部分>”]
[= <Initializer>];
<TypeSpec>是類型說明符,例如int,char

<Declarator>是全局對象的標識符,例如i,glob

<Address>是對象的絕對地址,例如0xff04、0x00 + 8

<Initializer>是全局變量初始化到的值。

將為每個用絕對地址指定的全局對象創建一個段。該地址不得在鏈接參數文件的SECTIONS條目中的任何地址范圍內。否則,將出現鏈接器錯誤(重疊段)。如果指定的地址的大小大於用於尋址默認數據頁的大小,則指向此全局變量的指針必須為“ __far”。將全局變量分配給特定地址的另一種方法是(清單8.8)。

清單8.8將全局變量分配給特定地址

#pragma DATA_SEG [__SHORT_SEG] <段名稱>
在鏈接器參數文件中設置PLACEMENT部分。清單8.9顯示了完成此操作的較舊方法。

清單8.9將全局變量分配給特定地址的另一種方法

<段名稱> INTO READ_ONLY <地址>;
清單8.10是使用全局變量地址修飾符的正確和不正確的示例,清單8.11是與示例清單相對應的可能的PRM文件。

清單8.10使用全局變量地址修飾符
//看這意味着,就是把int型變量glob地址從0x0500開始,並把值10初始化時放在0x0500
int glob @ 0x0500 = 10; //確定,全局變量“ glob”為
//在0x0500處,以10初始化
無效g()@ 0x40c0; //錯誤(對象是一個函數)

無效f(){
int我@ 0x40cc; //錯誤(對象是局部變量)
}

主要在嵌入式內應用多,將某一變量名稱指向寄存器的地址處,之后對此地址處寄存器的操作(賦值)只需要對此變量名操作即可

以pic16F877A中pic16F877.h頭文件對寄存器地址的命名舉例

static volatile unsigned char INDF @0x00;

static volatile unsigned char TMR0 @0x01;

這里將0x00地址處賦予INDF,而INDF對應多少位呢,unsigned char限定INDF表示8位,這樣就對0x00物理地址下的8位寄存器命名了一個變量,之后操作此地址下寄存器只需要操作此變量即可,不需要在記憶寄存器的地址是什么,只需要記住它對應的變量名即可,畢竟記名字要比一系列數字要好的多;

還可以使用指針符號來對某一地址下寄存器進行命名舉例說明

以上面情況舉例

#define INDF (static volatile unsigned char *)0x00;

將0x00強制類型轉換為unsigned char 的指針類型 並對它賦予另外一個名字INDF


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM