c - 为什么硬件寄存器访问是通过无符号数据类型

标签 c embedded

我正在浏览一些示例,并且在所有示例中都使用了 unsigned。如果使用得当,使用 int 类型是否安全?就像下面的示例一样,无论 ptr 被定义为有符号还是无符号,0x12345678 地址都将写入 0xFFFFFFFF。

volatile unsigned int* ptr = (volatile unsigned int* ) 0x12345678; 

*ptr = 0xFFFFFFFF;

为什么使用无符号而不是有符号的寄存器访问是安全的?

最佳答案

我认为无符号 C 算法更接近机器寄存器算法。这是因为 C 语言定义说,如果有符号整数算术运算结果为不符合给定类型的数字(溢出),则运算的实际结果是未定义的。所以它可以是任何东西。在无符号算术中:

A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.

这与机器寄存器中发生的情况相同。

你的例子是另一种情况,行:

*ptr = 0xFFFFFFFF;

创建unsigned long int 类型的常量0xFFFFFFFF。类型是 unsigned 而不是 int 因为该值大于最大整数值。如果变量 ptrint* 类型,那么编译器需要在任务。这将导致溢出并且该赋值的结果将是未定义的。虽然我不知道编译器在从 unsigned 转换为 int 时会生成任何算术运算。

如果 ptr 被定义为 int*,并且您希望是正确的,那么您的行应该是:

*ptr = -1;

关于c - 为什么硬件寄存器访问是通过无符号数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27206381/

相关文章:

c - C 语言中字符串输出时就变成了符号

c - 在循环中使用 fscanf() 的问题

c - 检查目录时出现指针问题

c++ - 调整大小和清除数组

c - 如何知道编译器正在编译的函数的位置

c - 由于看门狗 (IAR/MSP430),我的嵌入式应用程序从未完成初始化以进入 main()

linux - 每个版本都会下载 Yocto zip

c - 包含 .c 文件的副作用

c - 生成 RTE_Components.h

chmod 无法授予所有权限