如何在不违反严格的混叠规则的情况下访问内存映射的多字节寄存器
How can memory mapped multi-byte registers be accessed without violating the strict aliasing rule?
我正在使用Xilinx Zynq (ARM)平台的嵌入式linux项目上工作,该项目需要将一些物理FPGA地址映射到虚拟地址空间中,以便我可以访问一些32位寄存器。是否有一种方法可以让我调用mmap(),然后在映射地址上覆盖一个32位数组,以便对这些寄存器进行单操作访问?
我目前使用memcpy()来遵守严格的混叠规则,但这显示为对FPGA的4次单独访问(每字节1次)。编译时指定-fno-strict-aliasing是我唯一安全的选择吗?
你误解了严格的混叠规则
关于类型的规则不是,只有。这也和语义学有关。只要是适当类型的对象,通过void *
转换到其他指针类型的混叠是完全可以的。(否则void *
将不会有用。)
E。g。
uint32_t reg = 1337;
void *ptr = ®
*(uint32_t *)ptr = 42;
是可以的,因为ptr
不包含 uint32_t
对象的地址;只是它有不同的类型。
那么,下面这段代码:
uint32_t *regs = mmap(0xf00ba12, ...);
regs[0] = 0xffffffff;
可能违反也可能不违反严格混叠规则,这取决于地址0xf00ba12
的寄存器是否是uint32_t
类型。因此,在您的情况下,这是有效的。
严格混叠规则涉及那些试图通过绕过类型系统并通过不同类型的左值访问对象来作弊的程序员。这当然涉及到转换指针,但这并不是转换和解引用指针的行为违反了严格混叠,而是在引用地址处没有给定类型的对象这一事实。<<p> <子>,请做strong>不是使用-fno-strict-aliasing
! 子>
这里解释了严格混叠本身,相关的标准引号是C99/C11 6.5 p.7。简而言之,它说您不能通过与其有效类型不同类型的左值访问对象(有一些例外,请参阅链接)。
C99/C11 6.5 p.6
*)如果一个值通过一个非字符类型的左值被存储到一个没有声明类型的对象中,那么该左值的类型将成为该访问和后续不修改该存储值的访问的有效类型。如果使用memcpy或memmove将值复制到没有声明类型的对象中,或者将值复制为字符类型的数组,那么对于该访问和后续不修改该值的访问,修改后的对象的有效类型是复制该值的对象的有效类型(如果有)。对于对没有声明类型的对象的所有其他访问,对象的有效类型只是用于访问的左值的类型。*)已分配对象没有声明类型。
换句话说,你对该内存的第一次写访问决定了它的有效类型,直到下一次写访问,例如
void *foo = mmap(...);
*(int32_t *)foo = 1; // legal, the type of the mmaped object is now int32_t
*(float *)foo = 1.0; // legal, now the effective type is float
int32_t tmp = *(int32_t *)foo; // illegal, not compatible with the effective type
只要你访问你的映射寄存器只作为int32_t
,你是安全的(你可以做更多)。
- c++, 在子类中,如何在没有对象的情况下访问父类的方法?
- 模板方法访问正向声明的类仅在没有此指针的情况下无法编译
- 在无法访问向量的情况下查找迭代器的末尾
- 我是否访问了已释放的内存,或者在这种情况下DrMemory报告不正确?
- 是否可以在不复制的情况下访问undered_map中的元素
- 为什么不能指向指针,在没有强制转换的情况下访问结构成员?
- 为什么可以在没有实例变量的情况下访问静态回调方法中的静态成员变量?
- 在链接的程序集文件中,我想从 c++ 调用代码访问变量.是否可以在不触发访问冲突的情况下执行此操作?
- 如何在不设置完整路径的情况下访问 c++ 中的资源
- 当 95% 情况下的值为 0 或 1 时,对非常大的数组进行随机访问的任何优化
- OpenCL 矢量类型:在启用 C++11 的情况下无法访问联合组件 x,y,z
- 视觉 在C++中,我试图在没有递归的情况下循环访问许多对象
- 如何在 getter 的父类中初始化变量的情况下访问子类中的变量
- 如何在不需要 root 访问权限的情况下为应用程序中的线程设置相对线程优先级
- 我可以在不循环访问数组/向量的情况下检查数组/向量中的单词吗?
- 对象无法访问其私人数据.错误:在这种情况下私有
- 为什么我们可以访问交换机其他情况下标签内的变量
- 在不违反严格的别名规则的情况下访问进程间共享内存中的对象
- C++ 在不打开文件的情况下访问IMAGE_OPTIONAL_HEADER64?
- 在没有显式作用域的情况下无法访问模板基类的静态成员