【问题标题】:What causes address error on 16 bit architecture?是什么导致 16 位架构上的地址错误?
【发布时间】:2012-12-14 04:35:04
【问题描述】:

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

struct foo{
    uint8_t thing1;
    uint16_t thing2;
};

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

【问题讨论】:

  • 您可能需要为问题添加更多细节。但是检查编译器中的对齐以确保它与 16 位对齐。通过对齐,上述结构将起作用。
  • 查看你的处理器手册,看看哪些地址是合法的。然后检查您的链接器命令文件。

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


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      取决于你如何实例化它:

      struct foo{
          uint8_t thing1;
          uint16_t thing2;
      };
      

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

      【讨论】:

        猜你喜欢
        • 2011-04-05
        • 2011-04-11
        • 1970-01-01
        • 2022-01-26
        • 2014-05-17
        • 1970-01-01
        • 1970-01-01
        • 2020-06-18
        • 1970-01-01
        相关资源
        最近更新 更多