簡體   English   中英

這是如何取消引用的?

[英]How is this dereferenced?

我正在學習一個教程,他們想寫一個特定的值(0x0403)來注冊(地址為 0x04000000)

據我所知,這可以這樣做,

unsigned int 32 *ptr;
ptr = 0x04000000
*ptr = 0x403

但是,他們正在執行以下操作:

#define REG_DISP      *((volatile uint32*)(0x04000000))
#define VIDEOMODE_3                            0x0003
#define BGMODE_2                               0x0400

int main()
{
    REG_DISP = VIDEOMODE_3 | BGMODE_2;
    while(1){}
}

現在,我有以下問題:

  1. 我們可以在不聲明任何變量的情況下使用指針嗎?

  2. 為什么使用指向指針的指針? 是不是因為,我們不能做 ptr = 0x04000000?

只是一個評論。 所有這些只能由實現定義,因為語言本身沒有位於眾所周知的地址的寄存器的概念。

標准只是在 6.3.2.3 Pointers §5 中說(強調我的):

整數可以轉換為任何指針類型 除了前面指定的,結果是實現定義的,可能沒有正確對齊,可能不指向引用類型的實體,並且可能是陷阱表示。

這意味着這是有效的 C,只要實現允許它有意義:

unsigned int *ptr;
ptr = 0x04000000;
*ptr = 0x403;

它只是使用命名指針來訪問特定地址。 可以在不以這種方式命名指針的情況下完成:

* ((unsigned int *) 0x04000000) = 0x403;

讓我們看看它是如何工作的:

  • (unsigned int *) 0x04000000將 unsigned int 轉換為指向 unsigned int 的指針
  • * ((unsigned int *) 0x04000000)取消引用該指針
  • * ((unsigned int *) 0x04000000) = 0x403; 為指向的變量賦值

當您想訪問物理寄存器時,您需要要求編譯器立即寫入該值,而不是將其保存在內部寄存器中,這可以根據 if規則進行。 這就是volatile限定符的含義。 由於它專用於特定實現,因此它是完全合法的,前提是您可以確定unsigned int在該實現中具有 32 位,以編寫

volatile unsigned int *ptr;
ptr = 0x04000000;
*ptr = 0x403;

或者

* ((volatile unsigned int *) 0x04000000) = 0x403;

廣告。 1:C 允許將整數值轉換為指針,反之亦然。 您將(中間)轉換分配給變量的天氣與否無關緊要。 代碼部分(volatile uint32*)(0x04000000)實際上將整型文字0x0400000轉換為uint32*類型的指針; 請注意 volatile,它會關閉任何編譯器優化並讓代碼在取消引用時實際訪問相應的內存。

廣告2:沒有指向指針的指針; *((volatile uint32*)(0x04000000))只是取消引用指針(已在(1)中解釋)。

我猜這是關於 GameBoy Advance 的開發。

您可以在不聲明任何變量的情況下寫入內存地址,指針是一種表示內存地址的值,您可以對其進行寫入和讀取,而無需將其存儲在任何地方。

它不是指向指針的指針,它是一個硬編碼的地址,它被強制轉換為(volatile uint32*) ,並且宏在前面添加了*運算符只是為了避免您編寫它,這只是令人困惑。

最近我正在研究 GBA 開發的框架,也許您可​​以從中挑選一些信息或代碼,但請注意代碼是 C++14。

暫無
暫無

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

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