寄存器地址的指针

时间:2014-03-03 18:59:19

标签: c++ pointers

当涉及到引用程序中的另一个变量时,我通常对指针有一个很好的理解,但是引用/写入寄存器呢。 这两个代码版本是否会执行相同的操作?

#define REGISTER 0x0001 
volatile unsigned int* baseAddress = (unsigned int*) 0x60000000;
baseAddress[REGISTER] = 0x10101010;


volatile unsigned int* realRegister = (unsigned int*) 0x60000004;
realRegister = 0x10101010;

3 个答案:

答案 0 :(得分:2)

您不能拥有指向寄存器的指针或引用。寄存器不构成计算机主存的一部分,并且不能使用存储器地址寻址。

尽管使用名为#define的{​​{1}},您的代码片段与寄存器完全无关。他们试图写入正常的可寻址内存。在某些操作系统体系结构上,特定的内存地址可以直接映射到硬件端口(包括某些设备上的寄存器)。但是,大多数现代操作系统都不支持这一点。他们使用virtual memory的概念,而指针不直接映射到硬件位置。

关于您发布的代码,这两部分相同。第二个将无法编译,因为您正在尝试为指针分配一个整数。您可以通过在赋值(REGISTER)之前取消引用指针来进行编译,但这两段代码仍然不相同:

第一段代码将其值写入地址

*realRegister = 0x10101010;

相比之下,第二段代码将其值写入地址

reinterpret_cast<char*>(0x60000000) + sizeof(unsigned int)

- 这两段代码仅在reinterpret_cast<char*>(0x60000000) + 4

的机器上相同

答案 1 :(得分:1)

对于您的问题,术语寄存器有两个概念含义:处理器内部保存值的位置和硬件可寻址设备保存值的位置。

让我们跳过关于处理器寄存器的部分,因为它们没有外部世界可以访问的地址。 (有些处理器会这样做。)

让我们使用例如UART,它是将并行数据转换为串行数据的设备,通常用于来自嵌入式系统的输出数据。

仅考虑发送部分,有一个状态寄存器和一个数据寄存器。状态寄存器具有位,表示何时完成发送字符。数据寄存器保存要传输的字符。

假设它们是32位宽的顺序寄存器,它们从0x1000的基址开始。

您可以将模具设置为:

uint32_t * UART_BASE = (uint32-t *) 0x1000;

状态寄存器可以引用为UART_BASE[0],数据寄存器可以引用为UART_BASE[1]

还有其他方式来表示硬件设备,例如使用结构和每个寄存器作为结构中的字段;或者每个寄存器都有一个单独的指针。

答案 2 :(得分:0)

那应该是(*realRegister) = 0x10101010;,否则,是的,那些似乎是相同的。