探求为什么x86架构的一个字节(byte)是8位(bit)

原文链接:Some possible reasons for 8-bit bytes

About author

I’m a software developer. I live in Montreal. I sometimes give talks. Most of my income comes from my programming zines business Wizard Zines.

I have one main opinion about programming, which is that deeply understanding the underlying systems you use (the browser, the kernel, the operating system, the network layers, your database, HTTP, whatever you’re running on top of) is essential if you want to do technically innovative work and be able to solve hard problems.

I spent the fall of 2013 at the Recurse Center, which houses my favourite programming community. I wrote down what I did every day while there, if you want to know what it’s like.

我(本文中的“我”皆指原文作者,非译者!)一直在研究核算机如何用二进制表明事物的有关问题,其间有个问题被问了好几次——为什么 x86 架构运用8位字节?为什么不用其他巨细呢?

关于这个问题,我以为有两种存在或许的答案:

  • 一是前史偶尔,其他巨细(比如4、6、16位)相同适用,不过偶尔运用了8位;

  • 二是8 bit是最佳挑选,即便前史开展到现在,咱们仍然会运用8位作为一个字节(即原文的8-bit bytes,下文同);

  • 或者以上二者皆有。

我对核算机前史不是很了解(他更喜爱运用核算机而不是阅读相关资料),但我总是猎奇为什么核算机中的这些东西现在的方法是这样的,是什么原因导致的?或者是否首要就仅仅前史偶尔罢了。所以咱们来谈谈一些有关核算机的前史。

举个前史偶尔的比如:DNS 有一个class字段,它有5个或许的值(“internet”、“chaos”、“hesiod”、“none”和“any”)。我以为这是一个十分明显的前史偶尔比如——假如咱们今日从头规划 DNS 而不需求考虑兼容性,我不敢相信咱们还会以相同的方法界说 class 字段。我也不确认咱们是否彻底不会运用 class 字段!

这篇文章并没有给出终究答案,但我在 Mastodon 上提出了这个问题,以下是我找到的一些或许的原因,我以为终究答案是其间一些原因的组合。

byte和word的区别是什么?

首先你得知道本文中会说到的“byte”和“word”有何不同?我的理解是:

  • 字节数( byte size)是能够寻址的最小单位。例如,在我的核算机上运转某个程序时,0x20aa87c68 或许是某个字节的地址,周围的 0x20aa87c69 便是下一个字节的地址。

  • 字巨细(word size)是字节巨细的某个倍数。我对这个东西困惑了许多年,而维基百科对这个概念的界说十分模糊(“ 在核算机范畴, 关于某种特定的核算机规划而言,字是用于表明其天然的数据单位的术语:a word is the natural unit of data used by a particular processor design”)。最初我以为字巨细(word size)与寄存器巨细(register size)相同(寄存器巨细在 x86-64 上为 64 位)。可是依据 Intel 架构手册(Intel architecture manual)的第 4.1 节(“根本数据类型:Fundamental Data Types”),在 x86 上,一个字(word)是 16 位,寄存器(registers)是 64 位。所以我很困惑——在 x86 上,字到底是 16 位还是 64 位?它的意义能够依据运用场景而改变吗?这是什么情况?

现在来谈一谈咱们运用 8-bit bytes 的或许原因!

原因1️⃣:为了把一个英文字母放进一个字节里

下面这段维基百科中的内容称,IBM System/360 在1964年引入了8-bit bytes。

这儿有一段 Fred Brooks 关于此事的视频采访(他负责管理该项目)。以下是我转录的一部分内容:

……six bit bytes实际上更适合科学核算,而8-bit byte在商业核算(commercial computing)中表现更好,而每一种都可用于另一个范畴。所以挑选哪一种其实是一种取决于领导的决议计划(executive decision),我挑选了 Jerry 的 8-bit byte 提案。

[…]

我在 IBM 的作业生涯中最重要的技能决议计划便是挑选了 8-bit byte 用于IBM System/360。我相信字符处理(character processing)会变得更加重要,而不是十进制数字处理。

选用 8-bit byte 关于文本处理来说是十分合适的:2^6是64,因而6位不足以表明一切小写字母、大写字母和符号。

为了选用 8-bit byte ,System/360 还引入了 EBCDIC 编码,这是一种8位的字符编码。

8-bit byte 开展前史上影响深远的另一款设备是 Intel 8008,它被用于电脑终端(Datapoint 2200)。电脑终端需求能够表明字母以及终端操控代码(terminal control codes),所以运用 8-bit byte 也是有道理的。一同,Computer History Museum 上的这份 Datapoint 2200 手册在第7页上说明,Datapoint 2200 支撑 ASCII(7位)和 EBCDIC(8位)。

为什么 6-bit byte 更适合科学核算?

我对这个谈论很猎奇,即为什么 6-bit byte 更适合科学核算。以下是 Gene Amdahl 承受某个采访时的一段摘抄:

我之所以挑选运用24-bit word和48-bit word而不是32-bit word和64-bit word,由于这样会发生一个更合理的浮点数系统。在浮点运算中,关于32位字(32-bit word),有必要将指数坚持在8 bits以表明指数符号,要使其有更合理的数字规模,就有必要通过每4 bits进行调整而不是单个bit。因而这样会比进行二进制移位运算(binary shifting)更快地丢失信息。

我彻底不理解这条谈论——假如运用32位字长,为什么指数有必要为8位?为什么不能运用9位或10位?但这是我找到的全部内容,假如你能回答,期望在谈论区告诉我。

为什么大型机(mainframes)要运用36位字长?

与 6-bit byte 有关的另一个问题:为什么许多大型机运用36位字长?有人告诉我在维基百科上有一段关于36-bit computing的解说十分不错:

在核算机呈现之前,要求极端精细的科学核算和工程核算是运用支撑10位数的电动或机械核算器……这些核算器中每一位都有一列按键,操作员在输入数字时要运用一切手指,因而虽然一些专业核算器具有更多列(译者注:也便是支撑不止10位数的运算),但十列的确现已根本到了极限。

因而,前期针对同一范畴(译者注:指科学核算和工程核算)的二进制核算机一般运用36位字长。这足以表明正负整数的小数位达到十位(最少应为35 bits)。

因而,这个字长运用36 bit的事情好像基于这样一个现实:log2(20000000000)为34.2。

我猜想原因是这样的。在50年代核算机十分贵重,因而,假如想让核算机支撑十个十进制数字,就需求规划核算机恰好具有足够的位数,而不再多了。

现在的核算机更快、更廉价,因而,假如咱们想表明十个十进制数字,能够运用64 bits——糟蹋一点空间现在不是什么大问题。

还有人说到,一些具有36位字长的机器能够答应用户挑选字节巨细——依据运用场景能够挑选5、6、7或8位一个字节。

原因2️⃣:8-bit bytes与二进制编码的十进制数一同作业效果更佳

在60年代,有一种流行的整数编码方法叫做binary-coded decimal(简称BCD),它将每个十进制数字编码为4位。

举个比如,假如你想用BCD来编码数字1234,那么就会是这样的:

0001 0010 0011 0100

因而,假如你想要能够轻松地处理二进制编码的十进制数,字节巨细应该是4 bits的倍数,比如8 bits!

为什么BCD会流行呢?

我个人以为这种整数表明办法好像十分古怪,为什么不直接运用更高效的二进制来存储整数呢?毕竟在前期的核算机中,效率十分重要!

我的猜想是,前期的核算机没有像现在这样的显示器,所以每个字节的内容都会直接映射到了“lights”的开关上。

这是一张 IBM 650 的图片,能够看到它有一些“lights”,该图来自维基百科,(CC BY-SA 3.0):

探究为什么x86架构的一个字节(byte)是8位(bit)

因而,假如你能够让人们较简略地从二进制表明的数字中换算成十进制数,这就更有意义了。我以为今日BCD现已过期了,由于咱们有了显示器,咱们的核算机能够将用二进制表明的数字转换为十进制,并将其显示出来。

此外,我想知道“nibble”一词是否来自BCD——在BCD的时代,经常会引用半个字节(由于每个数字都是4 bits)。因而,有一个单词来表明“4 bits”,人们称为“nibble”。现在,“nibble”对我来说感觉有点陈旧了——除了作为一个趣闻之外,我肯定从来没有运用过它(这是一个十分风趣的词!)。维基百科上关于nibble的一句话支撑了这个我的这个猜想:

nibble用于描述在IBM大型核算机中以压缩的十进制格局(BCD)存储数字的内存量。

The nibble is used to describe the amount of memory used to store a digit of a number stored in packed decimal format (BCD) within an IBM mainframe.

有人说到BCD的另一个原因是财务核算(financial calculations)。现在,假如你想要存储一个美元金额,一般只需求运用美分做单位存储,假如想要美元部分,就除以100。这没有什么大不了的,进行除法运算速度很快。可是显然,在70年代那时候,将用二进制表明的整数除以100十分慢,因而值得从头规划如何表明整数来避免除以100的效率问题。

好了,关于BCD的内容就说这么多。

原因3️⃣:8是2的幂?

许多人说将CPU的字节巨细规划成2的幂是很重要的一件事。我无法确认这是否是正确的,而且“核算机运用二进制所以将字节规划成2的幂很好”这种解说并不能令我满足。这好像十分合理,但我想深化探求。前史上的确有许多运用非2的幂巨细的字节的机器,例如(来自retro computing stack exchange thread):

  • Cyber 180大型机运用6-bit bytes

  • Univac 1100/2200系列选用36位字长(36-bit word size)

  • PDP-8是一台 12-bit 机器

我还听到的一些关于运用2的幂作为字节巨细是很好的理由,可是我还没有彻底理解:

  • 每个 word 中的每个 bit 都需求一个总线,用户期望总线的数量是2的幂次方(为什么?)

  • 许多电路逻辑易受分而治之(divide-and-conquer)技能理念的影响(我以为我需求一个示例来理解这一点)

对我而言更有道理的原因:

  • 它使得规划能够测量“在这条线上发送了8位”的时钟分频器(clock dividers)更简略,,这些分频器的作业原理是折半(halving)——能够将3个折半(halving)的时钟分频器串联起来。 Graham Sutherland告诉我这个原因,并制作了这种时钟分频器模拟器,展现了这些时钟分频器的姿态。该网站(Falstad)还有许多其他的示例电路,好像这是一种十分酷的制作电路模拟器办法。
  • 假如您有一条指令来清除某个字节中的特定位,那么假如您的字节巨细为8(2 ^ 3),则只需求运用3位指令来指示是哪个 bit 。x86好像没有这么做,但Z80的位测验指令能够这样做。
  • 还有人说到,有些处理器运用 Carry-lookahead adders,它们以4 bit 为一组作业。从一些谷歌搜索成果来看,好像有各种各样的加法器电路。
  • bitmaps:核算机的内存被组织成页(pages)(一般是2 ^ n的巨细)。需求跟踪每页(page))是否闲暇。操作系统运用 bitmap 进行此操作,其间每个bit对应于一个页面,而且依据也是否闲暇表明为0或1。假如运用9-bit byte,则需求除以9才能在 bitmap 中找到所需的页面。除以9比除以2的幂次方慢,由于除以2的幂次方总是最快的方法。 我或许很糟糕地解说了一些理由。I’m pretty far out of my comfort zone here。让咱们持续。

原因4️⃣:较小的字节巨细是好事

你或许会想:假如8-bit bytes比4-bit bytes更好,那么为什么不持续添加byte size呢?能够运用16-bit bytes呀!

坚持 byte size 较小的一些原因:

  • 这是很糟蹋空间的——字节是能够寻址的最小单位,假如核算机存储了大量ASCII文本(一个字符仅需求7位),那么每个字符 12 位或 16 位是十分糟蹋的,而能够运用8位。
  • 跟着字节变大,CPU需求规划得更杂乱。例如,每个位都需求一条总线线路。

所以我以为越简略越好。 我对CPU架构的理解十分不牢固,所以我就点到为止。但“这样会糟蹋空间”的原因对我来说感觉适当有说服力的。

原因5️⃣:兼容性考虑

Intel 8008(1972年)是8080(1974年)的前身,而8080是8086(1976年)的前身——第一个x86处理器。好像8080和8086十分受欢迎,这便是咱们现代x86核算机梦开端的地方。

我以为这儿存在一个“假如它没坏,就不要修理”的问题——由于8-bit byte作业得很好,因而英特尔以为没有更改规划的必要性。假如坚持相同的 8-bit byte,那么就能够重用更多的指令集。

此外,在80年代左右,咱们开端运用TCP之类的网络协议,这些协议运用8-bit byte(一般称为“octets”),假如要完成网络协议,则或许要运用8-bit byte。

总结

在我看来,运用 8-bit byte 的首要原因如下:

  1. 许多前期核算机公司都是美国公司,美国最常用的语言是英语。
  2. 这些人期望核算机能够很好地处理文本。
  3. 遍及来说,较小的字节巨细更好。
  4. 7位是能够将一切英文字母+标点符号都放入其间的最小巨细。
  5. 8比7更好(由于它是2的幂次方)。
  6. 一旦呈现流行的 8-bit 核算机而且它们运作杰出,咱们就期望坚持相同的规划以完成兼容性。

有人指出,这本1962年的书第65页谈到IBM挑选 8-bit byte 的原因根本上也是相同的。

  1. Its full capacity of 256 characters was considered to be sufficient for the great majority of applications.
  2. Within the limits of this capacity, a single character is represented by a single byte, so that the length of any particular record is not dependent on the coincidence of characters in that record.
  3. 8-bit bytes are reasonably economical of storage space
  4. For purely numerical work, a decimal digit can be represented by only 4 bits, and two such 4-bit bytes can be packed in an 8-bit byte. Although such packing of numerical data is not essential, it is a common practice in order to increase speed and storage efficiency. Strictly speaking, 4-bit bytes belong to a different code, but the simplicity of the 4-and-8-bit scheme, as compared with a combination 4-and-6-bit scheme, for example, leads to simpler machine design and cleaner addressing logic.
  5. Byte sizes of 4 and 8 bits, being powers of 2, permit the computer designer to take advantage of powerful features of binary addressing and indexing to the bit level (see Chaps. 4 and 5 ) .

总的来说,这让我觉得假如在运用英语的国家规划一台二进制核算机,8位字节是一个天然而然的挑选。

本文正在参加「金石计划」