很多人都知道big endian和little endian但是很少有人知道它们的实质,因为只要你在网上一google,出来的都是那个经典的典故,不可否认,那个典故很重要,但是那也仅仅是个故事而已,计算机也仅仅是利用了这个故事的名字罢了,说到它们的实质还要看存储式体系计算机刚开始的时候,那个时候人们纷纷将数据和指令存入内存,如今我们很坦然的说出一个字节八位,一个int型的数据32位,可是那个时候人们在设计这一切的时候却没有这么坦然,他们甚至都不把八位想的这么特殊,现在想想为什么一个字节是八位,为什么八位显得那么重要,其实这里并没有什么必然的东西,因为计算机是以二进制为基础的,八位一字节在硬件上最简单,最高效,当时的cpu的数据总线最多也就有8位,而且8位最大可以表示255,正好表示完所有的拉丁字符,可是随着软件硬件的进步,而且实际上我们必须表示一个大于255的数字而不是字符,那么八位的数据量太小了,因此必须用超过一个字节的内存存储更大的数据类型,这就涉及到如何安排这些多字节数据的字节顺序了,因为逻辑上虽然一个int就是一个整数,但是人们根本不会管它在物理上怎么被载入内存,应该是怎么简单怎么高效就怎么安排,就好像逻辑上一个进程有四个G的虚存空间,但是物理上怎么安排实际分给这个进程的内存就是操作系统的事情了,逻辑上连续物理上不一定连续在字节续上也有所体现,于是怎么安排多字节的数据就是个问题,像虚拟内存那样彻底分开然后建立一套映射机制显得没有必要,那么就有了big endian和little endian这样的排列方式,以字节为一个单位,然后安排这些字节的位置,不至于太分散但又不失灵活,这就是策略,于是big endian和little endian其实是根据不同的侧重点而最终采用的两种方式罢了,其实现在的计算机已经都是32位的了,8位的基本字节要改变了,但是即使改了也还要面对字节序的问题,毕竟数据类型的大小没有上限,对于big endian来说,自然数据的高位在内存的低位,按照cpu发出的访问指令据总线导致内存访问的顺序是从低地址到高地址的,也就是先访问到最高的数据位,按照二进制数据的编码,最高位是符号位,也就是说big endian的机器最先访问到符号位,这对于运算来说是很有优势的,现在看看little endian的情况,正好和big endian相反,数据总线最先访问到自然数据的最低位,但是想要的到符号不得不先看看数据占几个字节找到最高位,然后才能判定,很麻烦,但是先访问低位也有好处,比如位访问比较有效,cpu访问一个数据的第n位就需要简单的从该数的开始处移动n/8个位置即可,仅仅一个移位,很简单,这个特性可以很方便的进行类型转换,软件上类型转换比较频繁的用little endian比较有效,而不怎么需要类型转换的,数据类型比较固定的就用big endian比较好。
现在我们看一个重要的发现,就是CISC/RISC与big/little endian的关系,我们知道RISC拥有大量的寄存器,所有的计算都在寄存器进行,只有在load或者store的时候才访问内存,而这两个操作仅仅是加载或者存储一个数字,数字的符号以及大小等信息越容易得到越好,现在看看CISC,由于类型转换涉及到计算,涉及到一些cpu指令,比如将一个32位的寄存器放到一个16位的临时数据中,而32位数据的得到涉及到很多寻址方式,很可能数据就是从内存得到的,因此CISC中为了最快的类型转换需要最快的位访问,这就是说,对于CISC的cpu,用little endian比较好,而对于RISC的cpu,用big endian比较好。
计算机中的很多事情都没有绝对的为什么,很多都是因为历史原因,在当时的历史条件下必须那样,也许也不是必须那样,而是因为那样更简单,然后就确定了一些规则,计算机不仅仅是一门科学,它还是一个工业,工业就要兼顾经济利益,于是向下兼容就很重要了,其实很多概念都是为了兼容而遗留下来的,于是很多人就将它们当成教条,这很不应该。
本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1273951