什么原因导致16位架构的地址错误?

时间:2012-12-14 04:35:05

标签: c memory-management memory-alignment 16-bit

我正在为16位微控制器开发一些C代码。当我在目标上调试应用程序时,我最终遇到了AddressError ISR。我读了数据表,它说如果你试图读取或写入一个在奇数存储器地址对齐的16位值,就会发生这种情况。我想我明白这意味着什么,但它似乎并不正确。如果我要制作这样的结构,那并不意味着:

struct foo{
    uint8_t thing1;
    uint16_t thing2;
};

我永远无法在没有错误的情况下读取或写入thing2?如果不是,这是否意味着编译器会在事物1和事物2之间自动填充8位,以便事物2在偶数地址上正确对齐?如果是这种情况,那么地址错误将如何发生?

3 个答案:

答案 0 :(得分:0)

大多数小尺寸处理器仅允许有限的一组存储器操作,因为未对准的存储器读取必须在两个或更多个周期内完成,并且会增加处理器的整体复杂性。

这通常不会在c代码中显示,因为堆栈变量和struct成员都与该类型的本机宽度对齐(或4或8字节,以最小者为准)。这可以使用属性 packed 覆盖,也可以将指向结构的指针重新分配给未对齐的地址。因此,人们可以很容易地熟悉地址错位异常。

虽然例如。英特尔8086支持非对齐地址的16位读取,在尝试访问跨越段边界的字时(偏移量为0xffff),仍然可以选择地址生成异常。

答案 1 :(得分:0)

可能您需要更改默认结构对齐方式。您可以在代码或编译器选项中使用pragma。在gcc的情况下,它是-fpack-struct [= n]

答案 2 :(得分:0)

根据您实例化的方式:

struct foo{
    uint8_t thing1;
    uint16_t thing2;
};

可以在偶数地址对齐,但如果编译器不够聪明,则在thing2之间不会添加填充,这需要将thing2设置为奇数地址,因此会出错。更改成员顺序或搜索编译器文档(可能是一些编译指示预处理程序指令),这将允许编译器帮助您为您调整数据。