为什么计算机采用 8 位字节
为什么 x86 架构使用 8 位字节？为什么不能是其他大小呢？
字节 架构
211.83.126.210
Great!
来自四川成都四川大学的 Firefox 31.0|GNU/Linux 用户
2023-05-30T19:31:14.000
219.217.246.58
Great!
来自黑龙江哈尔滨哈尔滨工业大学的 Firefox 114.0|GNU/Linux 用户
2023-06-01T16:48:46.000
为什么 x86 架构使用 8 位字节？为什么不能是其他大小呢？
![](/data/attachment/album/202305/30/115011gak5kqzsx3gfi2ud.jpg)


我正在制作一份有关计算机以二进制表示事物的小册子，有人问我一个问题 - 为什么 x86 架构使用 8 位字节？为什么不能是其他大小呢？


对于类似这样的问题，我认为有两种可能性：


* 这是历史原因造成的，其他尺寸（如 4、6 或 16 位）同样有效。
* 8 位是客观上的最佳选择，即使历史发展不同，我们仍然会使用 8 位字节。
* 一些混合 1 和 2 的因素。


我对计算机历史并不是非常着迷（与阅读计算机文献相比，我更喜欢使用计算机），但我总是很好奇计算机事物今天的方式是否存在本质原因，或者它们大多是历史偶然的结果。因此，我们将谈论一些计算机历史。


作为历史偶然性的一个例子：DNS 有一个 `class` 字段，它有 5 种可能的值（`internet`、`chaos`、`hesiod`、`none` 和 `any`）。 对我来说，这是一个明显的历史意外的例子 - 如果我们今天重新设计 DNS 而不必担心向后兼容性，我无法想象我们会以相同的方式定义类字段。我不确定我们是否会使用 `class` 字段！


这篇文章没有明确的答案，但我在 [Mastodon](https://social.jvns.ca/@b0rk/109976810279702728) 上提问，并找到了一些潜在的 8 位字节原因。我认为答案是这些原因的某种组合。


#### 字节和字有什么区别？


首先，本文中经常提到 “<ruby> 字节 <rt>  byte </rt></ruby>” 和 “<ruby> 字 <rt>  word </rt></ruby>”。它们有什么区别？我的理解是：


* **字节的大小** 是你可以寻址的最小单元。例如，在我的计算机上，程序中的 `0x20aa87c68` 可能是一个字节的地址，然后 `0x20aa87c69` 是下一个字节的地址。
* **字的大小** 是字节大小的某个倍数。我对此困惑了多年，维基百科的定义非常模糊（“字是特定处理器设计使用的自然数据单元”）。我最初认为字大小与寄存器大小相同（在 x86-64 上为 64 位）。但是根据 [英特尔架构手册](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html) 的第 4.1 节（“基本数据类型”），在 x86 上，虽然寄存器是 64 位的，但一个字是 16 位的。因此我困惑了 —— 在 x86 上，一个字是 16 位还是 64 位？它可以根据上下文而有不同的含义吗？这是怎么回事？


现在让我们来讨论一些使用 8 位字节的可能原因！


#### 原因 1：将英文字母适配到 1 字节中


[维基百科文章](https://en.wikipedia.org/wiki/IBM_System/360) 表示 IBM System/360 于 1964 年引入了 8 位字节。


在管理该项目的 Fred Brooks 的一段 [视频采访](https://www.youtube.com/watch?v=9oOCrAePJMs&t=140s) 中，他讲述了原因。以下是我转录的一些内容：



> 
> …… 6 位字节在科学计算中确实更好，而 8 位字节则更适合商业计算，每个字节都可以针对另一个字节进行调整，以使两种字节互相使用。
> 
> 
> 因此，这变成了一个高管决策，我决定根据 Jerry 的建议采用 8 位字节。
> 
> 
> ……
> 
> 
> 我在我的 IBM 职业生涯中做出的最重要的技术决策是为 360 选择 8 位字节。
> 
> 
> 我相信字符处理将变得重要，而不是十进制数字。
> 
> 
> 


使用 8 位字节处理文本很有道理：2<sup> 6</sup> 为 64，因此 6 位不足以表示小写字母、大写字母和符号。


为了使用 8 位字节，System/360 还引入了 [EBCDIC 编码](https://en.wikipedia.org/wiki/EBCDIC)，这是一种 8 位字符编码。


接下来在 8 位字节历史上重要的机器似乎是 [英特尔 8008](https://en.wikipedia.org/wiki/Intel_8008)，它设计用于计算机终端（Datapoint 2200）。终端需要能够表示字母以及终端控制代码，因此使用 8 位字节对其来说很有意义。[计算机历史博物馆上的 Datapoint 2200 手册](https://archive.computerhistory.org/resources/text/2009/102683240.05.02.acc.pdf) 在第 7 页上说 Datapoint 2200 支持 ASCII（7 位）和 EBCDIC（8 位）。


#### 为什么 6 位字节在科学计算中更好？


我对这条 “6 位字节在科学计算中更好” 的评论很好奇。以下是 [Gene Amdahl 的一段采访摘录](https://archive.computerhistory.org/resources/access/text/2013/05/102702492-05-01-acc.pdf)：



> 
> 我原本希望采用 24 和 48 而非 32 和 64，因为这将为我提供一个更合理的浮点系统。因为在浮点运算中，使用 32 位字大小时，你必须将指数保持在 8 位中用于指数符号，并且要使其在数字范围上合理，你必须每次调整 4 个位而不是单个位。因此，这将导致你比使用二进制移位更快地失去一些信息。
> 
> 
> 


我完全不理解这条评论 - 如果你使用 32 位字大小，为什么指数必须是 8 位？如果你想要，为什么不能使用 9 位或 10 位？但这是我在快速搜索中找到的全部内容。


#### 为什么大型机使用 36 位？


与 6 位字节相关的问题是：许多大型机使用 36 位字大小。为什么？在维基百科的 [36 位计算](https://en.wikipedia.org/wiki/36-bit_computing) 文章中有一个很好的解释：



> 
> 在计算机问世之前，即需要高精度科学和工程运算的领域，使用的是十位数码电动机械计算器……这些计算器每位数码均有一个专用按键，操作人员在输入数字时需要用到所有手指，因此，虽然有些专业计算器有更多位数码，但这种情况是个实际的限制。
> 
> 
> 因此，早期针对相同市场的二进制计算机通常使用 36 位字长度。这足以表示正负整数最高精度到十位数字（最小应为 35 位）。
> 
> 
> 


因此，这种 36 位大小似乎是基于


![](/data/attachment/album/202305/30/115207f4m55ct36z7knz4k.png)


的，它等于 34.2。嗯。


我猜这个原因是在 50 年代，计算机非常昂贵。因此，如果您想要你的计算机支持十位十进制数字，你将设计它恰好具有足够的位来执行此操作，而不会更多。


现在计算机更快更便宜，因此，如果您想要出于某种原因表示十位十进制数字，你只需使用 64 位即可 - 浪费一点空间通常并不会有太大问题。


还有人提到，一些具有 36 位字大小的计算机可以让你选择字节大小 - 根据上下文，你可以使用 5 或 6 或 7 或 8 位字节。


#### 原因 2：与二进制编码的十进制一起工作


20 世纪 60 年代，有一种流行的整数编码叫做 <ruby> 二进制编码的十进制 <rt>  binary-coded decimal </rt></ruby>（缩写为 [BCD](https://en.wikipedia.org/wiki/Binary-coded_decimal)），它将每个十进制数字编码为 4 位。


例如，如果你想要编码数字 `1234`，在 BCD 中，它会是这样的：



```
0001 0010 0011 0100

```

因此，如果你想要能够轻松地与二进制编码的十进制一起工作，你的字节大小应该是 4 位的倍数，比如 8 位！


#### 为什么 BCD 很流行？


这个整数表示方法对我来说真的很奇怪 —— 为什么不用更有效率的二进制来存储整数呢？在早期的计算机中，效率非常重要！


我最好的猜测是，早期的计算机没有像我们现在这样的显示器，所以一个字节的内容被直接映射到开关灯上。


这是来自维基百科一个带有一些亮灯的 IBM 650 显示器的图片（[CC BY-SA 3.0](http://creativecommons.org/licenses/by-sa/3.0/) 许可）：


![](/data/attachment/album/202305/30/115413n89sa99mit8krmqn.jpg)


因此，如果你想让人们能够相对容易地从二进制表示中读取十进制数，这样做就更有意义了。我认为，今天 BCD 已经过时了，因为我们拥有显示器，并且我们的计算机可以将用二进制表示的数字转换为十进制，并显示它们。


此外，我想知道，“<ruby> 四位 <rt>  nibble </rt></ruby>”（意为 “4 位”）这个词是不是来自 BCD 的。在 BCD 的上下文中，你经常会引用半个字节（因为每个十进制数字是 4 位）。所以有一个 “4 位” 的词语是有意义的，人们称 4 个位为 “<ruby> 四位 <rt>  nibble </rt></ruby>”。今天，“四位” 对我来说感觉像是一个古老的词汇，除了作为一个趣闻我肯定从未使用过它（它是一个很有趣的词！）。维基百科关于 “[四位](https://en.wikipedia.org/wiki/Nibble)” 的文章支持了这个理论：



> 
> “四位” 用来描述存储在 IBM 大型计算机中打包的十进制格式（BCD）中数字的位数。
> 
> 
> 


还有一个人提到 BCD 的另一个原因是 **金融计算**。今天，如果你想存储美元金额，你通常只需使用整数的分数，然后在需要美元部分时除以 100。这没什么大不了的，除法很快。但显然，在 70 年代，将一个用二进制表示的整数除以一个 100 是非常慢的，所以重新设计如何表示整数，以避免除以 100 是值得的。


好了，关于 BCD 就说这么多。


#### 原因 3：8 是 2 的幂？


许多人说，CPU 的字节大小是 2 的幂次方很重要。我无法确定这是真的还是假的，而且我对 “计算机使用二进制，所以 2 的幂次方很好” 这种解释感到不满意。这似乎非常合理，但我想深入探讨一下。而且从历史上看，肯定有很多使用字节大小不是 2 的幂次方的机器，例如（来自这个来自 Stack Exchange 上复古计算版块的 [帖子](https://retrocomputing.stackexchange.com/questions/7937/last-computer-not-to-use-octets-8-bit-bytes)）：


* Cyber 180 大型机使用 6 位字节
* Univac 1100/2200 系列使用 36 位字长
* PDP-8 是一台 12 位计算机


一些我听到的关于 2 的幂次方很好的原因我还没有理解：


* 一个单词中的每个位都需要一个总线，而你希望总线数量是 2 的幂次方（为什么？）
* 很多电路逻辑容易针对分而治之的技术（我需要一个例子来理解这个）


对我更有意义的原因是：


* 它使设计“时钟分频器”更容易，这些分频器可以测量“在这条线路上发送了 8 位”，分别基于减半进行操作 - 你可以将 3 个减半时钟分频器串联起来。[Graham Sutherland](https://poly.nomial.co.uk/) 告诉我这个，他制作了这个非常酷的 [分频器模拟器](https://www.falstad.com/circuit/circuitjs.html?ctz=CQAgjCAMB0l3BWcMBMcUHYMGZIA4UA2ATmIxAUgpABZsKBTAWjDACgwEknsUQ08tQQKgU2AdxA8+I6eAyEoEqb3mK8VMAqWSNakHsx9Iywxj6Ea-c0oBKUy-xpUWYGc-D9kcftCQo-URgEZRQERSMnKkiTSTDFLQjw62NlMBorRP5krNjwDP58fMztE04kdKsRFBQqoqoQyUcRVhl6tLdCwVaonXBO2s0Cwb6UPGEPXmiPPLHhIrne2Y9q8a6lcpAp9edo+r7tkW3c5WPtOj4TyQv9G5jlO5saMAibPOeIoppm9oAPEEU2C0-EBaFoThAAHoUGx-mA8FYgfNESgIFUrNDYVtCBBttg8LiUPR0VCYWhyD0Wp0slYACIASQAamTIORFqtuucQAzGTQ2OTaD9BN8Soo6Uy8PzWQ46oImI4aSB6QA5ZTy9EuVQjPLq3q6kQmAD21Beome0qQMHgkDIhHCYVEfCQ9BVbGNRHAiio5vIltg8Ft9stXg99B5MPdFK9tDAFqg-rggcIDui1i23KZfPd3WjPuoVoDCiDjv4gjDErYQA)，展示了这些分频器的工作原理。该网站（Falstad）还有很多其他示例电路，似乎是制作电路模拟器的一个非常酷的方式。
* 如果你有一个指令可以将字节中的特定位清零，则如果你的字节大小为 8（2 的 3 次方），你可以只使用 3 位指令来指示哪一位。x86 似乎没有这样做，但 [Z80 的位测试指令](http://www.chebucto.ns.ca/~af380/z-80-h.htm) 是这样做的。
* 有人提到一些处理器使用 [进位前瞻加法器](https://en.wikipedia.org/wiki/Carry-lookahead_adder)，它们按 4 位分组。经过一些快速的谷歌搜索，似乎有各种各样的加法器电路。
* **位图**：你计算机的内存被组织成页（通常大小为 2 的 n 次方）。它需要跟踪每一页是否空闲。操作系统使用位图来完成这项工作，其中每个位对应一页，并且根据页面是空闲还是占用，值为 0 或 1。如果你有一个 9 位的字节，你需要除以 9 来在位图中找到你要查找的页面。除以 9 的速度比除以 8 慢，因为除以 2 的幂次方总是最快的。


我可能很糟糕地扭曲了其中一些解释：在这里，我非常超出了自己的知识领域。我们继续前进吧。


#### 原因 4：小字节大小很好


你可能会想：好吧，如果 8 位字节比 4 位字节更好，为什么不继续增加字节大小呢？我们可以有 16 位字节啊！


有几个保持字节大小较小的理由：


* 它是一种空间浪费 —— 字节是你可以寻址的最小单位，如果你的计算机存储了大量的 ASCII 文本（只需要 7 位），那么每个字符分配 12 或 16 个位相当浪费，而你可以使用 8 个位代替。
* 随着字节变得越来越大，你的 CPU 需要变得更复杂。例如，你需要每个位线路一条总线线路。因此，我想简单总是更好。


我对 CPU 架构的理解非常薄弱，所以就说到这里吧。对我来说，“这是一种空间浪费” 的理由似乎相当有说服力。


#### 原因 5：兼容性


英特尔 8008（1972 年）是 8080（1974 年）的前身，8080 是第一款 x86 处理器 8086（1976 年）的前身。似乎 8080 和 8086 很受欢迎，这就是我们现代 x86 计算机的来源。


我认为这里有一个 “如果它好好的就不要动它” 的问题 - 我假设 8 位字节功能良好，因此英特尔看不到需要更改设计的必要性。如果你保持相同的 8 位字节，那么你可以重复使用更多指令集。


此外，80 年代左右我们开始出现像 TCP 这样的网络协议，它们使用 8 位字节（通常称为“<ruby> 八位组 <rt>  octet </rt></ruby>”），如果你要实现网络协议，你可能希望使用 8 位字节。


#### 就这些！


在我看来，8 位字节的主要原因是：


* 很多早期的电脑公司都是美国的，美国使用最广泛的语言是英语
* 这些人希望计算机擅长文本处理
* 较小的字节大小通常更好
* 7 位是你可以用来容纳所有英文字母和标点符号的最小尺寸
* 8 比 7 更好（因为它是 2 的幂次方）
* 一旦有得到成功应用的受欢迎的 8 位计算机，你希望保持相同的设计以实现兼容性。


有人指出 [这本 1962 年的书](https://web.archive.org/web/20170403014651/http://archive.computerhistory.org/resources/text/IBM/Stretch/pdfs/Buchholz_102636426.pdf) 第 65 页谈到了 IBM 选择 8 位字节的原因，基本上说了相同的内容：



> 
> 1. 其完整的 256 个字符的容量被认为足以满足绝大多数应用程序的需要。
> 2. 在该容量范围内，单个字符由单个字节表示，因此任何特定记录的长度并不因该记录中字符而异。
> 3. 8 位字节在存储空间上是相当经济的。
> 4. 对于纯数字工作，一个十进制数字只需要 4 个比特表示，两个这样的 4 位字节可以打包成一个 8 位字节。尽管这种数字数据包装不是必需的，但为了提高速度和存储效率，它是一种常见做法。严格来说，4 位字节属于不同的代码，但与 4 位及 8 位方案相比，它们的简单性导致了更简单的机器设计和更清晰的寻址逻辑。
> 5. 4 位和 8 位的字节大小，作为 2 的幂次方，允许计算机设计师利用二进制寻址和位级索引的强大功能（见第 4 章和第 5 章）。
> 
> 
> 


总的来说，如果你在英语国家设计二进制计算机，选择 8 位字节似乎是一个非常自然的选择。


*（题图：MJ/3526a0d5-bee5-4678-8637-e96e9843b53c）*




---


via: <https://jvns.ca/blog/2023/03/06/possible-reasons-8-bit-bytes/>


作者：[Julia Evans](https://jvns.ca/) 选题：[lkxed](https://github.com/lkxed/) 译者：ChatGPT 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出

