为什么0x100是256个字节、0x400是1KB、0x800是2KB、0x1000是4KB?
[TOC]
# 前言
在刚开始学习嵌入式时我们就遇到各种进制之间的换算,十六进制、十进制、八进制、二进制等等,一开始会经常在各种进制之间迷失自我;
在深入学习或者做项目或者工作时我们也经常要查看各种芯片的数据手册(datasheet),手册里面一般都是使用十六进制表示各种地址。
这时我们就会遇到类似这样的问题:
- 为什么 0x100 是 256Bytes([字节](https://baike.baidu.com/item/%E4%BD%8D%E3%80%81%E5%AD%97%E8%8A%82%E3%80%81%E5%AD%97/15650262?fr=aladdin)) 大小?
- 0x400 是 1KB 大小?
- 0x800是 2KB 大小?
下面我们就来解决这个疑惑!
# 数据单位标准
我们都知道数据单位有:bit、byte、word、KB、MB、GB、TB等等,他们之间的换算很简单,例如:
```bash
- 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,国际单位制)](https://en.wikipedia.org/wiki/International_System_of_Units)制定的标准,采用十进制换算。例如:
```bash
1 MB = 106 bytes = 1 000 000 bytes = 1000 kilobyte
1024 MB = 1 gigabyte (GB)
```
其中kilo、giga等称为十进制前缀,通常简写为KB、GB等。
另一种则为[IEC(International Electrotechnical Commission,国际电工委员会)](https://en.wikipedia.org/wiki/International_Electrotechnical_Commission)于[1998年2月](https://physics.nist.gov/cuu/Units/binary.html)制定的标准([IEC 60027-2](https://webstore.iec.ch/publication/93)),采用二进制换算。例如:
```bash
1 MiB = 2^20 bytes = 1 048 576 bytes = 1024 kibibytes
1024 MiB = 1 gibibyte (GiB)
```
其中kibi、gibi等称为二进制前缀,通常简写为KiB、GiB等。
下图是两种单位标准的[wiki](https://en.wikipedia.org/wiki/Byte)截图,摘自[wiki](https://en.wikipedia.org/wiki/Byte#Multiple-byte_units):

IEC制定的这个标准用于在一些更严格的场景下(希望使用二进制换算的情况)替换SI的标准,目前已为大多数组织所接受,像现在的许多Linux发行版也采用这种单位。
在本文中我们只关注我们常用到的 IEC 制定的标准,所有的讨论均是在 IEC 制定的 IEC 60027-2 标准基础上。
拓展阅读:
- [https://en.wikipedia.org/wiki/Byte](https://en.wikipedia.org/wiki/Byte)
- [https://simple.wikipedia.org/wiki/Mebibyte](https://simple.wikipedia.org/wiki/Mebibyte)
# 0x400为什么是1KB大小?
为了说这个问题,我们以 2440 的芯片手册为例,下面的图是 NAND闪存映射:
> 下面图引用自 S3C2440A_UserManual_Rev13.pdf :p222

我们重点看 ``0x4000 0000 - 0x4000 0FFF`` 这段内存空间。图中说明这个4kb的空间是分配给BootSRAM,这个 ``4KB`` 结果的换算过程:
```bash
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`` 位的,所以表示的范围是:
```bash
从
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 |
为什么0x100是256个字节、0x400是1KB、0x800是2KB、0x1000是4KB?的更多相关文章
- ASP.NET输出流至少要有256个字节的数据后Response.Flush方法才会生效
很多时候我们写的asp.net程序会因为做很多操作,所以会花上一分钟甚至几分钟时间.为了使软件使用者能够耐心的等待程序的执行,我们经常会希望有一个进度条来表示程序执行的状态.或者最起码要显示一个类似: ...
- sql2000-text类型数据只能看到256个字节
工具只能看到256个字节,其实数据是完整的,可以自己写个程序取数据试一试
- Python 实现隐藏文件夹、文件操作
Python通过win32api 可以实现操作文件夹文件操作,获取属性,修改属性 1.获取属性 通过win32api.GetFileAttributes 方法可以获取属性值 import win32c ...
- python 判断 windows 隐藏文件/系统文件
linux 下隐藏文件是以句号 “.” 开头的文件,根据文件名即可判断是否为隐藏文件. win 下是以文件隐藏属性确定的,所以,只能通过微软的 API 获取隐藏属性来判断是否为隐藏文件. 1. win ...
- 移植 libuv 至 Visual C++ 6.0 并支持 Windows XP 编译系统
移植版本 libuv:https://github.com/liigo/libuv-vc6 (支持VC6和XP.作者Liigo). 我从一年前(大概2013年6,7月份)開始在业余时间做这项移植工作, ...
- C# 自定义特性(Attribute)详解
什么是特性 特性的定义:公共语言运行时允许添加类似关键字的描述声明,叫做attribute,它对程序中的元素进行标注,如类型.字段.方法.和属性等.attribute和.NetFramework文件的 ...
- Android 12(S) 图形显示系统 - createSurface的流程(五)
题外话 刚刚开始着笔写作这篇文章时,正好看电视在采访一位92岁的考古学家,在他的日记中有这样一句话,写在这里与君共勉"不要等待幸运的降临,要去努力的掌握知识".如此朴实的一句话,此 ...
- Linux Netlink学习笔记
参考链接:https://www.systutorials.com/docs/linux/man/7-netlink/ 1. 监听Netlink消息类型示例 Netlink是用户程序与内核通信的soc ...
- String[255]在高版本Delphi里还是被解释成Byte,总体长度256,使用StrPCopy可以给Array String拷贝字符串(内含许多实验测试)
学了好多不了解的知识: procedure TForm1.Button1Click(Sender: TObject); var s1 : String; s2 : String[]; begin s1 ...
随机推荐
- Step By Step(Lua数据结构)
Step By Step(Lua数据结构) Lua中的table不是一种简单的数据结构,它可以作为其它数据结构的基础.如数组.记录.线性表.队列和集合等,在Lua中都可以通过table来表示. ...
- Go语言协程并发---select多路复用应用
package main import ( "fmt" "time" ) /* ·循环从一写两读三条管道中随机选择一条能走的路 ·等所有路都走不通了就退出循环 ...
- sql批量插入缓慢
1.有一个普通的表t_asset,只有2个字段id,ip 没有索引 2.当用insert into t_asset(id,ip) values(?,?),(?,?) 1200多条记录时,发现竟然用了3 ...
- 华为4D成像雷达、智能驾驶平台MDC 810
华为4D成像雷达.智能驾驶平台MDC 810 2020年10月底,华为发布了HI品牌,在今年2021年上海国际车展前夕,华为以 "专新致智" 为主题,举办HI新品发布会,发布了包括 ...
- MindSpore 高阶优化器
MindSpore 高阶优化器 MindSpore自研优化器THOR(Trace-based Hardware-driven layer-ORiented Natural Gradient Desce ...
- RCNN系列、Fast-RCNN、Faster-RCNN、R-FCN检测模型对比
RCNN系列.Fast-RCNN.Faster-RCNN.R-FCN检测模型对比 一.RCNN 问题一:速度 经典的目标检测算法使用滑动窗法依次判断所有可能的区域.本文则预先提取一系列较可能是物体的候 ...
- 行人检测与重识别!SOTA算法
行人检测与重识别!SOTA算法 A Simple Baseline for Multi-Object Tracking, Yifu Zhang, Chunyu Wang, Xinggang Wang, ...
- Docker Buildx插件
Docker Buildx插件 Overview Docker Buildx是一个CLI插件,它扩展了Docker命令,完全支持Moby BuildKit builder toolkit提供的功能.它 ...
- 性能工具之stress工具使用教程(带源码说明)
stress是一个在linux下的压力测试小工具. 我看到有些人用这个工具来描述一些资源耗尽的场景,也有人用它来做混沌测试中.请使用者要注意,这个工具并不是模拟业务问题的,是模拟系统级问题的.所以 ...
- 【C++】Vector排序
1.普通类型(由大到小排序) int main() { sort(v.begin(),v.end()); } 2.普通类型(由小到大排序) bool comp(const int &a,con ...