4

我一直在阅读有关访问外围设备的内存映射寄存器的信息,看来您可以采取多种方式。例如:

方法一:

#define MyReg 0x30610000

volatile int *ptrMyReg;
ptrMyReg = (volatile int *) MyReg;
*ptrMyReg = 0x7FFFFFFF; /* Turn  ON all bits */

方法二:

#define MyReg 0x30610000

volatile unsigned char *ptrMyReg;
ptrMyReg = (volatile unsigned char *) MyReg;
*ptrMyReg = 0x7FFFFFFF; /* Turn  ON all bits */

问题:是否有任何具体原因说明为什么要选择一个而不是另一个?

假设:架构上的 int 大小为 4 个字节。

4

4 回答 4

5

*ptrMyReg = 0x7FFFFFFF;

在第二种情况下,*ptrMyRegis 类型unsigned charso0x7FFFFFFF将在赋值之前转换为unsigned char(即转换后的值将是0xFF),并且只写入一个字节。如果您最初打算写 4 个字节,我认为这不是您想要的。

于 2013-04-21T17:20:29.830 回答
2

好吧,第二个示例不是有效代码,因为您的类型转换不匹配。如果您将其修复为:

ptrMyReg = (volatile unsigned char *)MyReg;

那么,是的,它们是不同的。在第二种情况下,该常量会被截断,并且您将仅写入0xFFat 字的最高或最低有效字节0x30610000,具体取决于字节序。无论如何,0x30610000将写入的是单个字节,而不是其他字节。

于 2013-04-21T17:14:22.367 回答
1

CPU 体系结构可能要求对外围寄存器的所有访问为例如 32 位宽。如果是这样,进行字节访问可能会导致 CPU 异常或静默错误执行。许多 ARM SoC 就是这种情况。

于 2013-04-21T19:50:22.663 回答
0

In method 2, you aren't going to access the entire int by dereferencing a pointer to char (unless, of course, sizeof(int)=1 on your platform).

Other than that, you should look at your hardware. It may behave differently when accessed using memory operands of different sizes.

于 2013-04-22T06:49:10.507 回答