c - 写入 double 浮点时处理ecos中未对齐的写入

标签 c exception mips memory-address ecos

我正在用 C 语言为 mipsisa32 架构编写程序,该架构可与 ECOS 操作系统配合使用。这是我第一次使用 ecos 和 mips,我遇到了一个奇怪的问题。 我使用动态分配的内存块并向其中写入一些数据。 但是当我尝试将 double 值写入未对齐到 8 字节的地址时,我得到异常编号 5,它在 hal_intr.h 中声明为 CYGNUM_HAL_VECTOR_STORE_ADDRESS,后来被重新定义为 CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE。

如果我获取指向目标和源的指针并将它们转换为 long long*,并且它们将值从一个赋值给另一个,那么我不会得到异常。

从未对齐的地址读取 double 时会发生同样的事情,但仅限于 double ,而不是 long long。这确实有道理,因为汇编代码确实使用了不同的指令。我不知道 mips 程序集,但根据我所看到的,我得出结论,当存储/读取 long long 时,它会分两 block 4 字节执行,但对于 double,它会一步完成。

那么你有什么建议呢? 这是正常行为吗?

我最后的办法是自己确保地址对齐,这会增加额外的开销,因为我要写入许多动态分配的缓冲区。

最佳答案

IIRC MIPS 不支持未对齐的内存访问。你可能违反了 requirement用于 malloc 返回针对任何数据类型正确对齐的 block 。

double 作为单个 64 位字获取。所以它需要对齐8个字节(这里:8位)。 对于 long long:在 32 位(字)架构上,使用具有 32 位内存访问的两个寄存器进行模拟(ARM 上的加载双字指令,如 LDRD 基本上是两个字加载指令)。所以 4 个字节是足够的(但可能不是最佳的)对齐方式。

我假设您目前正在对齐单词边界。你应该对齐 max_align_t (C11) 或类似的 (pre-C11) 为了安全起见。

关于c - 写入 double 浮点时处理ecos中未对齐的写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31878750/

相关文章:

MIPS 汇编语言

c - 嵌套 for 循环改进

c - 添加历史命令到多客户端服务器程序

c# - 在 try catch 中抛出自定义异常

c++ - 如何将有关最顶层调用/上下文的信息添加到异常

java - android中的空指针异常错误

linux - Mips 和 mipsel 工具链为同一可执行文件提供不同的堆栈信息

c - 有没有办法使用 gcc 将 C 转换为 MIPS?

c - 我们如何知道用 exec() 启动的程序所需的最小堆栈大小?

c - 使用 getc 读取文件并跳过以分号开头的行