0

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

struct foo{
    uint8_t thing1;
    uint16_t thing2;
};

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

4

3 回答 3

0

取决于您如何实例化它:

struct foo{
    uint8_t thing1;
    uint16_t thing2;
};

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

于 2012-12-14T13:15:51.120 回答
0

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

于 2012-12-14T12:58:24.907 回答
0

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

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

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

于 2012-12-14T07:05:32.910 回答