[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):
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210421224309102.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1MTgxMjM2,size_16,color_FFFFFF,t_70)

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

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210419185113659.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1MTgxMjM2,size_16,color_FFFFFF,t_70)
我们重点看 ``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 `
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210510145740134.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1MTgxMjM2,size_16,color_FFFFFF,t_70)

> 上面的案例基于 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?的更多相关文章

  1. ASP.NET输出流至少要有256个字节的数据后Response.Flush方法才会生效

    很多时候我们写的asp.net程序会因为做很多操作,所以会花上一分钟甚至几分钟时间.为了使软件使用者能够耐心的等待程序的执行,我们经常会希望有一个进度条来表示程序执行的状态.或者最起码要显示一个类似: ...

  2. sql2000-text类型数据只能看到256个字节

    工具只能看到256个字节,其实数据是完整的,可以自己写个程序取数据试一试

  3. Python 实现隐藏文件夹、文件操作

    Python通过win32api 可以实现操作文件夹文件操作,获取属性,修改属性 1.获取属性 通过win32api.GetFileAttributes 方法可以获取属性值 import win32c ...

  4. python 判断 windows 隐藏文件/系统文件

    linux 下隐藏文件是以句号 “.” 开头的文件,根据文件名即可判断是否为隐藏文件. win 下是以文件隐藏属性确定的,所以,只能通过微软的 API 获取隐藏属性来判断是否为隐藏文件. 1. win ...

  5. 移植 libuv 至 Visual C++ 6.0 并支持 Windows XP 编译系统

    移植版本 libuv:https://github.com/liigo/libuv-vc6 (支持VC6和XP.作者Liigo). 我从一年前(大概2013年6,7月份)開始在业余时间做这项移植工作, ...

  6. C# 自定义特性(Attribute)详解

    什么是特性 特性的定义:公共语言运行时允许添加类似关键字的描述声明,叫做attribute,它对程序中的元素进行标注,如类型.字段.方法.和属性等.attribute和.NetFramework文件的 ...

  7. Android 12(S) 图形显示系统 - createSurface的流程(五)

    题外话 刚刚开始着笔写作这篇文章时,正好看电视在采访一位92岁的考古学家,在他的日记中有这样一句话,写在这里与君共勉"不要等待幸运的降临,要去努力的掌握知识".如此朴实的一句话,此 ...

  8. Linux Netlink学习笔记

    参考链接:https://www.systutorials.com/docs/linux/man/7-netlink/ 1. 监听Netlink消息类型示例 Netlink是用户程序与内核通信的soc ...

  9. String[255]在高版本Delphi里还是被解释成Byte,总体长度256,使用StrPCopy可以给Array String拷贝字符串(内含许多实验测试)

    学了好多不了解的知识: procedure TForm1.Button1Click(Sender: TObject); var s1 : String; s2 : String[]; begin s1 ...

随机推荐

  1. 小程序webview涉及的支付能力、选用绑定多商户支付

    小程序webview涉及的支付能力.选用绑定多商户支付 webview承接页面涉及的支付能力: 仅支持小程序本身支付能力,不支持承接页面内的原支付功能(譬如,webview中嵌入了h5官方商城,经过配 ...

  2. Go以及调试工具dlv安装及使用

    安装go wget https://studygolang.com/dl/golang/go1.14.1.linux-amd64.tar.gz tar -C /usr/local -zxvf go1. ...

  3. vue相关面试知识点总结

    vue v-for循环中为什么要用key?为什么index不能作为key? key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes.如 ...

  4. [leetcode] 46. 全排列(Java)

    46. 全排列 这题我们可以借用31. 下一个排列写的nextPermutation函数来做,稍微改造一下即可 注意要先给nums排个序 class Solution { // 当没有下一个排列时re ...

  5. Oracle数据库使用pfile启动还是spfile启动---oracle

    查看数据库使用pfile启动还是spfile启动 9i版本以后,一般是使用spfile启动,但前提是有这个spfile文件,如果同时存在spfile和pfile文件,会优先选择spfile模式启动数据 ...

  6. Docker Context基本原理

    Docker Context基本原理 介绍 本指南介绍了上下文如何使单个Docker CLI轻松管理多个Swarm集群.多个Kubernetes集群和多个单独的Docker节点. 单个Docker C ...

  7. 使用NDepend衡量代码的SOLID程度

    SOLID是面向对象的软件开发中的5条准则,也是开发人员可以提升自己代码质量的准则.那么如何衡量自己的代码是否符合SOLID准则呢?NDepend这款工具也许可以帮得上忙.本文将介绍一些NDepend ...

  8. 机器人路径规划其一 Dijkstra Algorithm【附动态图源码】

    首先要说明的是,机器人路径规划与轨迹规划属于两个不同的概念,一般而言,轨迹规划针对的对象为机器人末端坐标系或者某个关节的位置速度加速度在时域的规划,常用的方法为多项式样条插值,梯形轨迹等等,而路径规划 ...

  9. 再试Hibernate框架

    几个月前因为学习需要第一次接触了Hibernate(之前一直在用MyBatis),后来觉得有点难,也急着找工作,所以就没继续学下去了.但是找工作的时候发现Hibernate的需求更高,使用率更高,所以 ...

  10. Springboot集成Spring Security实现JWT认证

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 Spring Security作为成熟且强大的安全框架,得到许多大厂的青睐.而作为前后端分离的SSO方案,JWT ...