前言
在剛開始學習嵌入式時我們就遇到各種進制之間的換算,十六進制、十進制、八進制、二進制等等,一開始會經常在各種進制之間迷失自我;
在深入學習或者做項目或者工作時我們也經常要查看各種芯片的數據手冊(datasheet),手冊里面一般都是使用十六進制表示各種地址。
這時我們就會遇到類似這樣的問題:
- 為什么 0x100 是 256Bytes(字節) 大小?
- 0x400 是 1KB 大小?
- 0x800是 2KB 大小?
下面我們就來解決這個疑惑!
數據單位標准
我們都知道數據單位有:bit、byte、word、KB、MB、GB、TB等等,他們之間的換算很簡單,例如:
- 1TB=1024GB
- 1GB=1024MB
- 1MB=1024KB
- 1KB=1024B(Byte)
- 1B=8bit
從上面的換算我們可以不難理解下面的兩個基本約定:
- bit(比特):bit是數據的最小單位,通常簡寫為b。在計算機中通常用1和0來表示。
- Byte(字節):數據存儲的基本單位,通常簡寫為B。通常:1Byte=8bit。
但是這些都是誰規定的呢?我們得先要解決這個疑惑。
兩種標准
目前,有兩種比較流行的單位:一種為SI(International System of Units,國際單位制)制定的標准,采用十進制換算。例如:
1 MB = 106 bytes = 1 000 000 bytes = 1000 kilobyte
1024 MB = 1 gigabyte (GB)
其中kilo、giga等稱為十進制前綴,通常簡寫為KB、GB等。
另一種則為IEC(International Electrotechnical Commission,國際電工委員會)於1998年2月制定的標准(IEC 60027-2),采用二進制換算。例如:
1 MiB = 2^20 bytes = 1 048 576 bytes = 1024 kibibytes
1024 MiB = 1 gibibyte (GiB)
其中kibi、gibi等稱為二進制前綴,通常簡寫為KiB、GiB等。
IEC制定的這個標准用於在一些更嚴格的場景下(希望使用二進制換算的情況)替換SI的標准,目前已為大多數組織所接受,像現在的許多Linux發行版也采用這種單位。
在本文中我們只關注我們常用到的 IEC 制定的標准,所有的討論均是在 IEC 制定的 IEC 60027-2 標准基礎上。
拓展閱讀:
0x400為什么是1KB大小?
為了說這個問題,我們以 2440 的芯片手冊為例,下面的圖是 NAND閃存映射:
下面圖引用自 S3C2440A_UserManual_Rev13.pdf :p222
我們重點看 0x4000 0000 - 0x4000 0FFF
這段內存空間。圖中說明這個4kb的空間是分配給BootSRAM,這個 4KB
結果的換算過程:
1. 0x4000 0FFF - 0x4000 0000 = 0x0000 0FFF
2. 0x0000 0FFF 的十進制是 4095 (Bytes)
3. (4095+1) / 1024 = 4 (KB)
為什么 0x0000 0FFF 的十進制是 4095 ,而且這就是代表 (4095+1) 個字節(也就是4KB)呢?下面我們一起來解開這個疑惑:
下圖是2440的內存布局圖 (0x0000 0000 - 0xFFFF FFFF)
。
2440的CPU是32bit的,地址總線一共有 32(2^5)
根,可以索引的地址范圍是 0 - 2^32 (0x0000 0000 - 0xFFFF FFFF)
,也就是 4GB
的空間。
那么這個 4GB 是怎么得來的呢?
下面的圖已經給出了很直觀的答案了,2440的CPU是 32
位的,所以表示的范圍是:
從
0000 0000 0000 0000 0000 0000 0000 0000 (0x0000 0000)
到
1111 1111 1111 1111 1111 1111 1111 1111 (0xFFFF FFFF)
一個字節有8位,從下面的圖可知,一共有 0xFFFF FFFF
個字節,也就是 4,294,967,295
個字節( 0xFFFF FFFF
轉換后的十進制),所以大小為:4,294,967,295 Bytes = 4,194,305KB = 4095MB
但是這里為什么不是 4096
呢?因為我們計算的范圍是 0x0000 0000 - 0xFFFF FFFF
) ,並沒有算第1個字節(Byte),所以上面的應該是一共有 0xFFFF FFFF+1
個字節,也就是:4,294,967,296 Bytes = 4,194,306KB = 4096MB = 4GB
上面的案例基於 2400,其他芯片也是一樣的思路分析即可。不管他是8位、16位、32位還是64位,我們只要知道他們的能表示的最大范圍即可
回到開始的問題
到這里我們就能理解為什么在 2440的芯片手冊中,分配給BootSRAM的 0x4000 0000 - 0x4000 0FFF 是 4KB
大小了 。
那么我們來解決一開始提出的問題: 為什么0x400是1KB大小?
0x400轉換的十進制為:1024
,也就是有 1024 個字節(Byte),
1KB的換算過程:1024(Byte)/1024=1kb
。
用這種思路我們就可以理解為什么, 0x100 是 256 個字節(Bytes)、0x800是 4096 個字節(Bytes)也就是 4KB。
附錄1:存儲單位之間的換算
1 Byte(B) | 8 bit |
1 Kilo Byte(KB) | 1024B |
1 Mega Byte(MB) | 1024 KB |
1 Giga Byte (GB) | 1024 MB |
1 Tera Byte(TB) | 1024 GB |
1 Peta Byte(PB) | 1024 TB |
1 Exa Byte(EB) | 1024 PB |
1 Zetta Byte(ZB) | 1024 EB |
1Yotta Byte(YB) | 1024 ZB |
1 Bronto Byte(BB) | 1024 YB |
1Nona Byte(NB) | 1024 BB |
1 Dogga Byte(DB) | 1024 NB |
1 Corydon Byte(CB) | 1024DB |
1 Xero Byte (XB) | 1024CB |
附錄2:常見的16進制地址及其對應容量
十六進制 | 大小 |
---|---|
0x100 | 256B |
0x200 | 512B |
0x400 | 1KB |
0x800 | 2KB |
0xC00 | 3KB |
0x1000 | 4KB |
0x2000 | 8KB |
0xF000 | 60KB |
0x1 0000 | 64KB |
0x2 0000 | 128KB |
0xF 0000 | 960KB |
0x10 0000 | 1MB |
0x20 0000 | 2MB |
0xF0 0000 | 15MB |
0x0100 0000 | 16MB |
0x0200 0000 | 32MB |
0x0F00 0000 | 240MB |
0x1000 0000 | 256MB |