指向寄存器地址的指针
pointer to register address
当涉及到引用程序中的另一个变量时,我通常对指针有很好的理解,但引用/写入寄存器呢。这两个代码版本会执行相同的操作吗?
#define REGISTER 0x0001
volatile unsigned int* baseAddress = (unsigned int*) 0x60000000;
baseAddress[REGISTER] = 0x10101010;
volatile unsigned int* realRegister = (unsigned int*) 0x60000004;
realRegister = 0x10101010;
不能有指向寄存器的指针或引用。寄存器不构成计算机主内存的一部分,也不能使用内存地址进行寻址。
尽管使用了名为REGISTER
的#define
,但您的代码段与寄存器完全无关。它们试图写入正常的可寻址内存。在某些操作系统架构上,特定的内存地址可以直接映射到硬件端口(在某些设备上包括寄存器)。然而,大多数现代操作系统并不支持这一点。它们使用了虚拟内存的概念,指针不会直接映射到硬件位置。
关于您发布的代码,这两个部分不完全相同。第二个不会编译,因为您正试图为指针分配一个整数。您可以通过在赋值(*realRegister = 0x10101010;
)之前取消引用指针来编译它,但这两段代码仍然不完全相同:
第一段代码将其值写入地址
reinterpret_cast<char*>(0x60000000) + sizeof(unsigned int)
相比之下,第二段代码将其值写入地址
reinterpret_cast<char*>(0x60000000) + 4
–这两段代码仅在具有sizeof(unsigned int) == 4
的机器上相同。
对于您的问题,术语寄存器有两个概念含义:处理器内用于保存值的位置和硬件可寻址设备用于保存值。
让我们跳过关于处理器寄存器的部分,因为这些寄存器没有外部世界可以访问的地址。(有些处理器会这样做。)
例如,让我们使用UART,它是一种将并行数据转换为串行数据的设备,通常用于从嵌入式系统输出数据。
仅考虑发送部分,就有一个状态寄存器和一个数据寄存器。状态寄存器具有表示何时完成字符传输的位。数据寄存器保存要传输的字符。
假设这些是32位宽的顺序寄存器,它们从基址0x1000开始。
您可以将模具设置为:
uint32_t * UART_BASE = (uint32-t *) 0x1000;
状态寄存器可以被称为UART_BASE[0]
,数据寄存器可以被称作UART_BASE[1]
。
还有其他方式来表示硬件设备,例如使用结构和每个寄存器作为结构内的字段;或者每个寄存器具有单独的指针。
应该是(*realRegister) = 0x10101010;
,但除此之外,是的,它们看起来是一样的。
- CUDA:统一内存和指针地址的更改
- 是否可以仅通过将分配的指针地址存储在C++中来分析内存?
- 向指针地址添加 20 个字节偏移量
- 如何理解智能指针的底层指针地址?
- 初学者问题:C++指针/地址 - 和变量之后不是以前?
- 返回数组中值的指针地址
- C++向指针地址添加 4 个字节
- 指针地址的内存偶尔更改了函数前和后返回
- 如何根据指针地址获取指针内容
- C++ 将指针地址传递给函数
- 直接从指针/地址访问数组的元素
- 如何在没有作弊引擎的情况下从其他应用程序获取指针地址?
- 如何保存指针地址,以便另一个指针可以继续处理它
- 间接寻址运算符如何返回带有运算符重载的指针地址
- 使用已删除的指针地址.据我所知,
- 如何保护类外用户可以修改的指针地址?C++
- 多个调用构造函数将更改C 中的成员指针地址
- 类对象指针的向量:如何在指针地址获得价值?C 和SDL_RECT
- Visual Studio C 2K15-在指针地址上获取错误
- 指针地址和参考混乱