【问题标题】:How is this dereferenced?这是如何取消引用的?
【发布时间】:2018-12-30 22:00:49
【问题描述】:

我正在关注一个教程,他们希望将特定值 (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?

【问题讨论】:

    标签: c pointers dereference


    【解决方案1】:

    只是一个评论。所有这些都只能由实现定义,因为语言本身没有位于众所周知地址的寄存器的概念。

    标准只是在 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; 为指向的变量赋值

    当你想访问一个物理寄存器时,你需要让编译器立即写入值,而不是把它保存在一个内部寄存器中,这可能是 as if 规则所允许的。这就是volatile 限定符的含义。因为它专门用于特定的实现,所以它是完全合法的,前提是您可以确定unsigned int 在该实现中具有 32 位,以编写

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

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

    【讨论】:

      【解决方案2】:

      广告。 1:C 允许将整数值转换为指针,反之亦然。是否将(中间)转换分配给变量的天气并不重要。代码部分(volatile uint32*)(0x04000000) 实际上将整型文字0x0400000 转换为uint32* 类型的指针;请注意 volatile,它会关闭任何编译器优化,并让代码在取消引用时实际访问相应的内存。

      广告2:没有指向指针的指针; *((volatile uint32*)(0x04000000)) 只是取消引用指针(已在(1)中解释。

      【讨论】:

        【解决方案3】:

        我猜这是关于 GameBoy Advance 开发的。

        您可以在不声明任何变量的情况下写入内存地址,指针是一种表示内存地址的值,您可以对其进行写入和读取,而无需将其存储在任何地方。

        它不是指向指针的指针,它是一个硬编码的地址,它被强制转换为(volatile uint32*),并且宏在前面添加了* 运算符,只是为了避免你编写它,这只是令人困惑。

        我最近正在为 GBA 开发框架工作,也许你可以从 there 中挑选一些信息或代码,但请注意代码是 C++14。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-05-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-15
          • 2014-05-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多