微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

可变宽度访问的类型转换数组

如何解决可变宽度访问的类型转换数组

抱歉,我不确定我是否准确地写了标题

但首先,这里是我的约束:

  1. Array[],用作寄存器映射,声明为无符号 8 位数组 (uint8_t), 这样索引(偏移量)是按字节进行的。
  2. 要读取/写入阵列的数据具有不同的宽度(8 位、16 位、32 位和 64 位)。
  3. 必须非常有限的内存和速度。

执行以下操作有哪些注意事项

uint8_t some_function(uint16_t offset_addr) //16bit address
{
  uint8_t Array[0x100];
  uint8_t data_byte = 0xAA;
  uint16_t data_word;
  uint32_t data_double = 0xBEEFFACE;

\\ A. Storing wider-data into the array
*((uint32_t *) &Array[offset_addr]) = data_double;

\\ B. Reading multiple-bytes from the array
data_word = *((uint16_t *) &Array[offset_addr]);
 
  return 0;
}

我知道我可以尝试按字节写入数据,但由于位移,这会很慢。

这种用法会有重大问题吗? 我已经在我的硬件上运行了它,到目前为止还没有发现任何问题,但我想注意这个实现可能导致的潜在问题。

解决方法

这种用法会有重大问题吗?

它会产生未定义的行为。因此,即使在实践中表现出您对当前 C 实现、硬件、程序和数据的预期,您也可能会发现当某些(任何)发生变化时它会意外中断。

即使编译器以明显的方式实现了强制转换和取消引用(它没有义务这样做,因为 UB),由您的方法导致的未对齐访问至少会减慢许多 CPU,并且会在某些 CPU 上产生陷阱。

>

做你想做的符合标准的方法是这样的:

uint8_t some_function(uint16_t offset_addr) {
  uint8_t Array[0x100];
  uint8_t data_byte = 0xAA;
  uint16_t data_word;
  uint32_t data_double = 0xBEEFFACE;

\\ A. Storing wider-data into the array
  memcpy(Array + offset_addr,&data_double,sizeof data_double);

\\ B. Reading multiple-bytes from the array
  memcpy(&data_word,Array + offset_addr,sizeof data_word);
 
  return 0;
}

这不一定比您的版本慢,并且只要您不超出数组边界,它就会定义行为。

,

这可能没问题。很多人都做过这样的事情。 C 在这种事情上表现得很好。

注意两点:

  1. 缓冲区溢出。你知道像永恒之蓝这样的零日和像 WannaCry 这样的黑客吗?他们中的许多人利用了像您这样的代码中的错误。恶意输入导致代码将过多内容写入您的 uint8_t Array[0x100] 等数据结构中。当心。避免在堆栈上分配缓冲区(作为函数局部变量),因为破坏堆栈是可利用的。让它们足够大。检查您没有超出它们。

  2. 机器字节顺序与网络字节顺序,又名endianness。如果这些数据结构通过网络从一台机器转移到另一台机器,您可能会遇到麻烦。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。