GCC编译EEPROM地址顺序相反

3
我有一个使用C语言编写、使用GCC编译器编译的ATmega代码。 需要将一些数据存储在EEPROM中,因此我添加了以下声明:

enter image description here

在读取EEPROM后,我发现数据以某种奇怪的方式存放。经过一些调查,我在 .map 文件(由工具链生成的众多文件之一)中找到了这段文本:

enter image description here

如您所见,编译器将数据以相反的顺序放置。当然,我可以颠倒声明并继续编码,但这是意料之外的事情,因此在我不理解编译器为什么这样做之前,我害怕面对任何其他意外行为。有什么想法吗?

1
编译器/链接器可以自由地将变量放置在任何位置。问题在于你为什么期望一定的顺序,或者这个顺序是否对你的程序有影响? - Lundin
1
这对我来说很有意义,因为我之后要读取EEPROM并对数据进行分析。所以顺序对我至关重要 :( - Vlada Katlinskaya
如果顺序很重要(例如,如果您希望通过某些外部工具读取/编程EEPROM),那么您真的需要手动指定每个变量分配在哪个地址。 应该有一些特定于系统的方法来做到这一点:在您的系统上可能称为某些 #pragma 或 "__declspec" 或其他名称。 - Lundin
@Lundin 我对这种行为感到生气 :((((((( 现在我知道编译器可以自由地定位变量。然而,在这种特定情况下,我看不出混淆数据的任何理由 :( 如果应用了一些填充,我能理解,但这种意外的反向就像一个恶作剧。 通常指定直接地址并不是最好的方法,因为我需要亲自处理重叠(以及其他问题),这在我的情况下很容易,但在更大的项目中可能会很棘手和不可靠。谢谢您的 #pragma 想法(我会尝试找到语法)。 - Vlada Katlinskaya
1
我记得在 avr-gcc 4.6 左右,avr-gcc 反转了 EEMEM 对象在内存中的顺序与它们在声明中出现的顺序。正如其他人所说,您不能假设任何顺序。 - ouah
1个回答

2
正如@Lundin所述,全局变量不需要连续分配。
您可以使用struct的特性,其成员总是按照指定顺序分配
从C11标准,§6.7.2.1.15:

在结构对象内,非位字段成员和位字段所在的单元具有按照它们声明的顺序增加的地址

但要注意填充

2
请引用6.7.2.1/15。 - Lundin
谢谢大家的帮助! - Vlada Katlinskaya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接