IEN 137 Danny Cohen USC/ISI 1980 年 4 月 1 日关于圣战和和平请求 介绍这是试图阻止战争。我希望现在还不算太晚,不知何故,也许奇迹般地,和平会再次占据上风。后来进入竞技场的人认为问题是:“消息中的正确字节顺序是什么?”。冲突的根源远不止于此。 .这是哪个位应该先行的问题,是单词小端的位,还是单词大端的位?前一种方法的追随者被称为小端,后者的追随者被称为大端。 Little-Endians 和 Big-Endians 之间的圣战细节记录在 [6] 中,并在附录中简要描述。我建议您此时阅读它。上述问题来自对消息执行的序列化过程,以便通过通信介质发送它们。如果通信单元是消息 - 这些问题没有意义。如果单元是计算机“词”,那么人们可能会问这些词是按什么顺序发送的,它们的大小是多少,但不会问这些词的元素是按什么顺序发送的,因为它们实际上是“一次”发送的。如果传输单位是一个 8 位字节,关于字节的类似问题是有意义的,但构成这些字节的基本粒子的顺序就没有意义了。如果通信单位是位,计算的“原子”(“夸克”?),那么唯一有意义的问题是发送比特的顺序。显然,这实际上是串行传输的情况。大多数现代通信基于单个信息流(“比特流”)。因此,比特,而不是字节或字,是实际通过通信信道(如电线和卫星连接)传输的信息单位。尽管在硬件和软件方面做了大量工作,致力于呈现字节或字通信,基本事实仍然是:比特是通信的。计算机内存可以被视为比特的线性序列,分为字节、字、页等。每个单元是下一级的子单元。显然,这是一个等级组织。 2如果顺序是一致的,那么这样一个序列可以成功地传达,同时双方保持他们将比特视为一组任意大小的组的自由。一方可能将一条消息视为一个“页面”,另一方将其视为如此多的“字”,或如此多的“字节”或如此多的位。如果使用一致的位序,则“chunk-size”没有影响。如果使用不一致的位序,则块大小必须得到各方的理解和同意。稍后我们将演示一些流行但不一致的顺序。在一致的顺序中,位序、字节序、字序、页序以及所有其他更高级别的顺序都是相同的。因此,在考虑串行比特流,例如,沿着通信线路,该流的发起者所考虑的“块”大小并不重要。有两种可能的一致顺序。一个是像 Little-Endians 那样从每个单词的低端(又名“LSB”)开始,或者像他们的竞争对手 Big-Endians 那样从宽端(又名“MSB”)开始。在这个音符中,我们通常使用以下示例编号:“字”是 32 位数量,由“W”指定,“字节”是 8 位数量,由“C”指定(对于“字符”,不要混淆用“B”表示“位)”。 MEMORY ORDER 内存中的第一个单词被两个政权指定为 W0。不幸的是,和谐没有进一步。Little-Endians 将 B0 分配给单词的 LSB,B31 是 MSB。Big-Endians 做相反的事情, B0 是 MSB,B31 是 LSB。顺便说一句,如果数学家按照他们的方式,每个序列都会从零开始编号,而不是像传统那样从一开始编号。如果是这样,第一项将被称为“第零”......由于大多数计算机不是由数学家建造的,难怪有些计算机指定从 B1 到 B32 的位,无论是小端还是大端' 命令。这些人可能想从 W1 开始编号他们的话,只是为了保持一致。回到主题。我们想用图形来说明层次一致的顺序,但首先我们必须决定计算机单词写在纸上的顺序。他们是从左到右,还是从右到左? 3英语与大多数现代语言一样,建议我们将这些计算机单词从左到右排列在纸上,如下所示:|---word0---|---word1---|---word2---| ....为了保持一致,B0 应该在 B31 的左边。如果一个字中的字节被指定为 C0 到 C3,那么 C0 也在 C3 的左边。因此我们得到: |---word0---|---word1---|---word2---|.... |C0,C1,C2,C3|C0,C1,C2,C3| C0,C1,C2,C3|..... |B0......B31|B0......B31|B0......B31|......如果我们也使用传统的惯例,正如我们的编号系统所介绍的那样,宽端在左侧,窄端在右侧。因此,以上是大端派所描绘的完全一致的世界观。重要性一致性随着项目编号(地址)的增加而降低。许多计算机与 Big-Endians 共享这种关于顺序的观点。在他们的许多图中,寄存器是这样连接的,当单词 W(n) 右移时,它的 LSB 移动到单词 W(n+1) 的 MSB。英文文本字符串以相同的顺序存储,第一个字符在 C0 W0 的,W0 的 C1 的下一个,依此类推。这个顺序与自己和英语非常一致。应该从每个单词的窄端开始,低地址的顺序低于高地址。因此,他们把单词写在纸上,就像用希伯来语写的一样,就像这样:...|---word2- --|---word1---|---word0---|当他们将位序和字节序相加时,他们得到:...|---word2---|---word1-- -|---word0---| ....|C3,C2,C1,C0|C3,C2,C1,C0|C3,C2,C1,C0| .....|B31......B0|B31......B0|B31......B0|在这种情况下,当词 W(n) 右移时,其 LSB 移动进入单词 W(n-1) 的 MSB。 4英文文本字符串的存储顺序是一样的,第一个字符在W0的C0,下一个在W0的C1,依此类推。这个顺序和自己非常一致,跟希伯来语,还有(更重要的)跟数学,因为重要性随着项目号(地址)的增加而增加。它的缺点是英文字符流似乎是倒写的;这只是一个审美问题,但不可否认,它看起来很有趣,尤其是对讲英语的人来说。为了避免收到关于这个命令的奇怪评论,小端人假装他们是中国人,写字节,不是从右到左而是从上-to-bottom, like: C0: "J" C1: "O" C2: "H" C3: "N" ..etc..注意,“左”和“右”的概念绝对没有任何具体意义"在计算机内存中按位顺序排列。例如,可以将其视为“上”和“下”,或者通过系统地交换所有“左”和“右”来镜像它。然而,这个概念源于计算机单词代表数字的概念,以及数字的宽端(又名 MSB)被称为“左”而数字的窄端被称为“右”的古老数学传统。数学约定是“左”和“右”概念的参考点。很容易确定任何给定的计算机系统是由 Little-Endians 设计的还是 Big-Endians 设计的。这是通过观察寄存器为“组合移位”操作和多精度算术(如整数乘积)连接的方式来完成的;还可以通过观察这些量是如何存储在内存中的;显然也是按照字节在字中的存储顺序。不要让B0-to-B31方向欺骗你!!大多数计算机是由 Big-Endians 设计的,他们在刑事起诉的威胁下假装自己是 Little-Endians,而不是在不来夫斯库寻求流放。他们通过使用 Little-Endians 的 B0-to-B31 约定来做到这一点,同时保留 Big-Endians 的字节和字约定。例如,PDP10 和 360 是由 Big-Endians 设计的:他们的位顺序,字节- order、word-order 和 page-order 是相同的。同样的顺序也适用于长(多字)字符串和多精度数字。 5接下来,让我们考虑新的M68000微处理器。其在16位字中存储32位数字xy、16位数字z和字符串“JOHN”的方式如下所示(S=符号位,M=MSB,L=LSB):SMxxxxxxx yyyyyyyyL SMzzzzzzL "J" "O" "H" "N" |--word0--|--word1--|--word2--|--word3--|--word4--|.... |- C0-|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-|..... |B15.... B0|B15....B0|B15....B0|B15....B0|B15....B0|......M68000 总是在左边(即,LOWER 字节-或字地址)它可能使用的任何不同大小的数字的宽端:4(BCD)、8、16 或 32 位。因此,M68000 是一致的大端,除了它的位指定,用来伪装其真实身份。请记住:Big-Endian 是不法分子。接下来让我们看看 PDP11 的顺序,因为这是第一台声称自己是 Little-Endian 的计算机。再来看看数据在内存中的存储方式: "N" "H" "O" "J" SMzzzzzzL SMyyyyyyL SMxxxxxxL ....|--word4--|--word3--|--word2--|- -word1--|--word0--| .....|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-| ......|B15....B0|B15....B0|B15....B0|B15....B0|B15....B0|PDP11 没有指令移动 32 位数字。它的乘积是仅在寄存器中创建的 32 位数量,并且可以以任何方式存储在内存中。因此,上图中没有显示 32 位数量 xy。因此,上面的顺序是 Little-Endians 的一致顺序。 PDP11 总是在左边(即更高的位或字节地址)存储它可能使用的任何大小的数字的宽端:8 或 16 位。然而,由于来自其他阵营的一些渗透,寄存器这个 Little-Endian 的奇迹以 Big-Endian 的方式处理:双长度操作数(32 位)放置在低地址寄存器中,其 MSB 放在高地址寄存器中。因此,当在纸上描绘时,寄存器必须从左到右放置,数字的宽端放在低地址寄存器中。这会影响整数乘法和除法、组合移位等。诚然,Blefuscu 在这一点上得分。后来,为 PDP11/45 引入了浮点硬件。浮点数由 32 位或 64 位数量表示,即 2 或 4 个 PDP11 字。宽端是带有符号位、指数和分数的 MSB 的那一端。窄端是分数的 LSB。根据数百年的数学惯例,这些格式在纸上清楚地显示为左宽右窄。在 PDP11/45 处理器手册 [3] 的第 12-3 6 页上,有一个可爱的图形演示该命令,单词“FRACTION”分割在所有 2 或用于存储它的 4 个单词上。但是,由于对于安全检查过程中的一些疏忽,Blefuscuians 再次接管了。他们一如既往地将宽端分配给内存中的低地址,将窄地址分配给高地址。让“xy”和“abcd”分别为 32 位和 64 位浮点数。让我们看看这些数字是如何存储在内存中的: ddddddddL ccccccccc bbbbbbbbb SMaaaaaaa yyyyyyyyL SMxxxxxxx ....|--word5--|--word4--|--word3--|--word2--|--word1-- |--word0--| .....|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-| -C0-| ......|B15....B0|B15....B0|B15....B0|B15....B0|B15....B0|B15....B0|好吧, 不来夫斯库为此得分很多。 [3] 中的上述参考文献甚至没有试图用任何中文符号来掩盖它。受到这一成功的鼓舞,尽管它是次要的,但布莱夫斯库人试图拉另一个快速的。这次是在VAX,所有小端崇拜的神圣机器。让我们看看VAX的顺序。再次,我们看看上面的数据(其中 xy 是一个 32 位整数)在内存中的存储方式: "N" "H" "O" "J" SMzzzzzzL SMxxxxxxx yyyyyyyyL ...ng2------ -|-------long1-------|-------long0-------| ....|--word4--|--word3--|--word2--|--word1--|--word0--| .....|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-| ......|B15....B0|B15....B0|B15....B0|B15....B0|B15....B0|多么漂亮一致的小尾数订单这是!那么,渗透者呢?他们是完全没有完成任务吗?由于整数算术受到严密保护,他们攻击了众所周知的容易被攻击的浮点数和双浮点数。 7让我们再看看上面数据的存储方式,除了现在 32 位量 xy 是一个浮点数:现在这个数据在内存中按照以下不来夫斯库式的方式组织:“N”“H”“O”“ J" SMzzzzzzL yyyyyyyyL SMxxxxxxx ...ng2-------|-------long1-------|-------long0-------| ....|--word4--|--word3--|--word2--|--word1--|--word0--| .....|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-|-C1-|-C0-| ......|B15....B0|B15....B0|B15....B0|B15....B0|B15....B0|Blefuscu 再次得分。 VAX 被判有罪,但解释说它试图与 PDP 兼容通过使用中国从上到下的符号,而不是令人尴尬的从左到右或从右到左的符号。这个页面是惊奇的。不得不佩服一些数量在8位宽,一些在16位,其他在32位列中的巧妙方式,所有这些都是为了避免脸上的鸡蛋问题......顺便说一句,一些工程类型的人抱怨“中文”(垂直)符号,因为通常图表的顶部(又名“上”)对应于“低”内存(低地址)。然而,任何由计算机科学家而不是植物学家抚养长大的人都知道,树是向下生长的,它们的根在页面顶部,叶子在页面下方。计算机科学家很少记得真正的“向上”方向(参见 [5] 中的 2.3,第 305-309 页)。在浮点部分获得如此轻松的分数后,Blefuscuians 转移到了新的领域:Packed-Decimal。 VAX 也可以使用 4-bit-chunk 十进制算术,类似于众所周知的 BCD 格式。Big-Endians 再次来袭,毫无阻力。十进制数 12345678 存储在这个 VAX 内存中顺序:7 8 5 6 3 4 1 2 ...|-------long0-------| ....|--word1--|--word0--| .....|-C1-|-C0-|-C1-|-C0-| ......|B15....B0|B15....B0|即使是标准的中国伎俩,也无法掩盖这种丑陋。 8 总结(内存顺序部分)据我所知,只有 Blefuscu 的 Big-Endians 构建了具有一致顺序的系统,可以跨块边界、寄存器、指令和内存工作。我没有找到完全一致的小端系统。传输顺序在任何一个一致的顺序中,第一个字 (W0) 的第一个字节 (C0) 的第一位 (B0) 首先被发送,然后是这个字节的其余位,然后(以相同的顺序)这个字的字节数等等。例如,这样一个8个32位字的序列,可以看成是4个长字、8个字、32个字节或256位。例如,有些人把ARPA-互联网数据报作为 16 位字序列,而其他人将它们视为 8 位字节流或 32 位字序列。这从来都不是混淆的根源,因为已经假定了 Big-Endians 的一致顺序。有很多方法可以设计不一致的顺序。两个最受欢迎的是以下及其镜像。在此顺序下,要发送的第一位是第一个字的最高有效字节 (C0) 的最低有效位 (B0),然后是该字节的其余位,然后是相同的从右到左的位顺序从左到右字节顺序。图 1 显示了上面讨论的 4 个命令的传输顺序,2 个一致的和 2 个不一致的。那些使用这种不一致顺序(或任何其他)的人,只有那些,必须关注著名的字节顺序问题。如果他们可以假装他们的通信媒介真的是一个面向字节的链接,那么这种不一致就可以安全地隐藏在地毯下。几年前,8 位微处理器出现并彻底改变了我们做生意的方式。几年后,出现了各种各样的 8 位通信硬件(例如 Z80-SIO 和 2652),所有这些硬件都按照 Little-Endians 的顺序运行。 9现在一波16位微处理器已经到来。很难想象 16 位通信硬件很快就会成为现实。由于 16 位通信设备将是由为我们带来 8 位通信设备的同一批人提供的,因此可以安全地期望这两种模式兼容每种模式其他。实现这一点的唯一方法是使用一致的 Little-Endiansorder,因为所有现有设备都已经是 Little-Endians 顺序。我们已经观察到 Little-Endians 没有一致的计算机内部组织的内存顺序。如果可以使 16 位通信链接以任何顺序运行,无论是否一致,这将使它看起来像一个面向字节的链接,那么 Big-Endians 可以推动(询问?希望?祈祷?)从左到右传输字节的顺序(即,宽端优先)并将其用作以更方便的大端格式传输所有数量(BCD除外)的基础,最重要的部分领先最不重要的,维护在 16 位和 32 位通信之间具有兼容性,等等。然而,这是一个很大的“IF”。如果我们能封装字节通信并忘记过去由 RS232 和 TELEX 引入的特性,那不是很好吗? ,首先发送窄端?我相信这会很好,但好的事情不一定会发生,尤其是如果有这么多芯片反对他们。因此,我们现在的选择是(1)Big-Endians 的计算机 -便利性和(2)未来不同块大小的通信设备之间的兼容性。我认为这是个问题,我们应该这样解决。短期便利性考虑有利于前者,长期考虑有利于后者既然Little-Endians和Big-Endians的战争一触即发,让我们数一数谁在谁的阵营。 Little-Endians党的创始人是RS232和TELEX,他们表示窄端先发送。 HDLC 和 SDLC 协议、Z80-SIO、Signetics-2652、Intel-8251、Motorola-6850 和所有其他现有通信设备也是如此。除了这些协议和芯片之外,PDP11 和 VAX 已经宣誓效忠于这个阵营,理应出现在这个名单上。 10HDLC 协议是该阵营的一个完整成员,因为它首先发送窄端的所有字段,如建议 X.25 的第 2.2.1 节表 1/X.25(帧格式)中的具体定义(见2])。仔细检查该表会发现传输的位顺序始终是 1 到 ......