繁体   English   中英

用于可变宽度访问的类型转换 Arrays

[英]Typecasting Arrays for Variable Width Access

对不起,我不确定我是否准确地写了标题。

但首先,这是我的限制:

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

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

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. 缓冲区溢出。 你知道那些像 Eternal Blue 这样的零日和像 WannaCry 这样的黑客吗? 他们中的许多人利用了像您这样的代码中的错误。 恶意输入导致代码将太多内容写入数据结构,如uint8_t Array[0x100] 当心。 避免像您所做的那样在堆栈上分配缓冲区(作为函数局部变量),因为破坏堆栈是可利用的。 让它们足够大。 检查你没有超越他们。

  2. 机器字节排序与网络字节排序,也就是字节序 如果这些数据结构通过网络在机器之间移动,您可能会遇到麻烦。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM