簡體   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