首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有可寻址GPR文件的CPU、寄存器变量的地址以及内存和寄存器之间的混叠。

具有可寻址GPR文件的CPU、寄存器变量的地址以及内存和寄存器之间的混叠。
EN

Stack Overflow用户
提问于 2014-11-13 18:17:25
回答 1查看 213关注 0票数 0

背景

一些CPU(如Atmel AVR )具有一个通用寄存器文件,该文件也可作为主内存的一部分寻址--参见7.4节中的图7-2和图后面的段落。

WG14是怎么想的?

既然如此,为什么C委员会选择

代码语言:javascript
复制
register int ri;
int* pi = &ri;

根据N1124第6.7.1节的脚注101,普遍存在畸形吗?考虑到上面的代码至少在一个处理器上是有意义的,而C向后弯曲以适应更陌生的(而且更少),那么未定义或实现定义的行为就不会更有意义了。比AVR更重要的目标?

101)实现可以将任何register声明简单地视为auto声明。但是,无论是否实际使用可寻址存储,都不能显式地(使用6.5.3.2中讨论的一元&运算符)或隐式(通过将数组名称转换为6.3.2.1中讨论的指针)计算用存储类说明符register声明的对象的任何部分的地址。因此,唯一可以应用于用存储类说明符register声明的数组的操作符是sizeof

我只是通过指针改变了CPU寄存器。哇?!

此外,使用GCC显式寄存器变量扩展,可以指导编译器将变量放置到特定的寄存器中。在这种情况下,您可以得到一个带有寄存器变量别名的指针,如下所示:

代码语言:javascript
复制
register int ri asm("r15") = 0;
int* pi = (int*)0x15;
/* pi now aliases ri */
*pi = 42;
/* ri is 42 now */
assert(ri == 42);

GCC如何处理这样的案件?我觉得这真的很奇怪,像这样的东西并没有considered...or,对吗?

EN

回答 1

Stack Overflow用户

发布于 2014-11-13 19:18:57

C是一种抽象语言,定义时不了解最终实现它的机器。C的定义并不认为底层机器甚至会有常规形式的寄存器(或者堆栈、连续内存,或者在实际机器上存在的与这个问题无关的许多其他事情)。

要点是,register并不意味着应该为变量分配一个机器寄存器。关键字的含义是,变量不能被占用其地址;然后,理论上编译器能够对其执行更好的优化,因为它减少了变量可能被修改的路径数。在C中获取register变量的地址是没有意义的,无论它在哪个处理器上运行,因为register一个非常糟糕的关键字 (以它所支持的最明显的优化命名),这意味着不应该使用该地址。这就是所有的意义。

无论如何,AVR的智能编译器应该能够在不需要您提示的情况下进行优化(实际上,关键字是无用的,因为任何半体面的编译器都可以检测到它何时适用,因为基本上没有明确定义的方法来引用auto对象而不显式地获取其地址)。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26915731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档