c - 在C中注册访问(读/写)

标签 c assembly binary cpu-registers

我对处理器寄存器的概念有些误解。有一个地址为 0x0345678 的寄存器。这个寄存器是 32 位宽/长(现在不重要,哪个字是正确的)。正如手册中所写,有某种表格/数组:

Position   Value
 0          111111...10b
 1          111111...11b
 2          7A
 .......................
 7          3F7C

I have to access the value with position 2. The first thing what I've done was:

#define REG 0x0345678

void somereadfunction()
{
   volatile unsigned int *pval = (volatile unsigned int *)REG;
   printf("%x", *(pval | 0x02));
}

正如您已经猜到的那样,这是错误的假设。

另一个尝试是这个:

    for(unsigned int i = 0; i < 3; i++)
    {
        printf("i: %d, res: 0x%08X", i, *((volatile unsigned int *)REG));
    } 

而且它有效。所以,我的问题是,为什么以及如何?处理器是否只是用其他开发人员编写的内部魔术算法切换寄存器值?我对此有点困惑。我知道如何使用一些简单的按位操作访问寄存器的第三位,但我不明白,如何通过调用三次寄存器来获得正确的值?

预先感谢您的回答。

添加:处理器是 ARM 7。使用 i2c 设备。

最佳答案

为什么

因为构建您的硬件设备(连接到您的 ARM 处理器)的人可能只声明了几个“属于”该设备的地址。然后,他们注意到硬件中的数据比寄存器多,更改手册已经来不及了,因此他们决定让一些寄存器保存多个值。

如何

硬件有一个内部计数器,用于计算从处理器读取的命令。每次处理器想要从寄存器读取时,硬件都会向它发送另一段数据,由不可见的内部计数器索引,并增加计数器。计数器是 3 位的,所以它计数 0, 1, ..., 7, 0, 1, ... 等等。

因此,如果要读取索引为 2 的数据,还必须读取所有其他数据元素(3、4、5、6 和 7)以重置不可见计数器。

关于c - 在C中注册访问(读/写),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11000806/

相关文章:

c getline 跳过空行

打印数组所有元素的汇编代码

c++ - 文件流实际上是如何工作的?

c - 如何阻止文件名/路径出现在已编译的 C 二进制文件中

c++ - 打印有符号整数的二进制表示

c - 关于C中的二进制文件

c++ - OpenGL 3 相当于 GLUTesselator?

c - 链表产生警告的函数

linux - 尽管使用 gcc 链接器,但获取对汇编代码的 "_printf"错误的 undefined reference

linux - 如何检查linux二进制文件是否有新添加的代码