为什么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 ...
随机推荐
- Camera Calibration 相机标定
Camera Calibration 相机标定 一.相机标定方法 在opencv中提供了一组函数用于实现相机的标定,标定返回的值包括:相机内参矩阵(fx fy xc yc).相机外参矩阵(R t)以及 ...
- 语义分割:基于openCV和深度学习(一)
语义分割:基于openCV和深度学习(一) Semantic segmentation with OpenCV and deep learning 介绍如何使用OpenCV.深度学习和ENet架构执行 ...
- MindSpore网络模型类
MindSpore网络模型类 Q:使用MindSpore进行模型训练时,CTCLoss的输入参数有四个:inputs, labels_indices, labels_values, sequence_ ...
- Docker_Swarm集群系统
Docker_Swarm集群系统 一.Docker Swarm 介绍 实践中会发现,生产环境中使用单个 Docker 节点是远远不够的,搭建 Docker 集群势在必行.然而,面对 Kubernete ...
- 毫米波RADAR与LIDAR探秘
毫米波RADAR与LIDAR探秘 说起激光雷达和毫米波雷达,相信业内人士并不陌生,激光雷达是以发射激光束探测目标的位置.速度等特征量的雷达系统.而毫米波雷达是指工作在毫米波波段探测的雷达.毫米波实质上 ...
- TVM源码框架安装方法
TVM源码框架安装方法 本文提供如何在各种系统上从零构建和安装TVM包的说明.它包括两个步骤: 首先从C++代码中构建共享库(linux的libtvm.so,macOS的libtvm.dylib和wi ...
- 【模板】Linux下输出文件的对比
命令格式: diff+[参数]+[文件1或目录1]+[文件2或目录2] 命令参数: 指定要显示多少行的文本.此参数必须与-c或-u参数一并使用. -a或--text diff预设只会逐行比较文本文件. ...
- mybatis入“坑”第一步
一.导入坐标 要想通过maven创建一个简单的mybatis项目,首先需要的是要导入相关的坐标.需要导入的坐标如下: <dependencies> <!--mysql驱动坐标--&g ...
- Sublime Text 4 破解笔记
Sublime Text 4 破解笔记 偶然看到Sublime已经更新到版本4了,多了许多很nice的新特性,例如: 船新 UI 感知上下文的自动补全 支持 TypeScript, JSX 和 TSX ...
- Binding(三):资源和ValueConverter
这节讲资源和值转换器(ValueConverter). 资源 在XAML中,我们想要使用外部的数据或者类,需要引入其命名空间,然后将其定义为XAML页面的资源,供给控件使用,或者我们需要封装一个共用的 ...