数据的字节序及对硬件的影响

一、字节序

我们知道,计算机处理数据和存储数据的基本单元是一个字节。如果我们的数据超过一个字节,数据要怎么存储和处理。比如一个简单整形数据数0x12345678,这是一个四字节的十六进制数据,按照我们在数的进制里讲的,这个数从左到右排列,是按照由高位到低位排列的,不同的位的位权不一样,这个进制里的位其实也就是数的排列顺序。在计算机里是以十六进制(二进制)来表示数据的,那么其实也就是字节的排列顺序,称为字节序。我们常见的是从左到右依次排列,也是我们人类习惯书写顺序。

在一个顺序排列的进制数里,在不同的位由于位权不一样,对这个数的影响不一样,按高低位,高位影响越大,低位影响越小。比如(12345)10,万位上1肯定影响最大,个位上的5影响最小。针对这种情况,我们有两个相对专业的词:

  • MSB(Most Significant Bit)
    最高有效位
  • LSB(Least Significant Bit)
    最低有效位

如果一个进制数中,某个位在MSB的话对数的影响就大,在LSB的话就小。

二、大小端模式

大端模式和小端模式是我们现在计算机世界里存在的两种最常用的数据字节序。我们知道在计算机里,CPU访问处理的数据要么在寄存器、主存或者其他设备里。据的存储是放在不同的地址,一个字节对应一个地址,CPU访问数据又是根据数据的地址来访问的,所以,数据在计算机里的表示跟地址直接相关,我们可以说,纯数学上的进制数的位就对应了计算机里的数据存储地址,从这个概念出发,人么设计了大端和小端这两种计算机数据的字节序模式。

  • Big Endian
    是指数据的高位字节保存在内存的低地址中,而数据的低位字节保存在内存的高地址中,这样的存储模有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。也就是MSB在低地址,LSB在高地址。
  • Little-Endian
    是指数据的高位字节保存在内存的高地址中,而数据的低位字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。也就是MSB在高地址,LSB在低地址。

比如整数0X12345678按大小端分别存储如下:

采用大小模式对数据进行存放的主要区别在于在存放的字节顺序,大端方式将高位存放在低地址,小端方式将低位存放在高地址。采用大端方式进行数据存放符合人类的正常思维,而采用小端方式进行数据存放利于计算机处理。到目前为止,采用大端或者小端进行数据存放,其孰优孰劣也没有定论。

三、字节序对硬件设计的影响

有的处理器系统采用了小端方式进行数据存放,如Intel的X86。有的处理器系统采用了大端方式进行数据存放,如IBM半导体和Freescale的PowerPC处理器。不仅对于处理器,一些外设的设计中也存在着使用大端或者小端进行数据存放的选择。

因此在一个处理器系统中,有可能存在大端和小端模式同时存在的现象。这一现象为系统的软硬件设计带来了不小的麻烦,这要求系统设计工程师,必须深入理解大端和小端模式的差别。大端与小端模式的差别体现在一个处理器的寄存器,指令集,系统总线等各个层次中。

软件上对不同端模式编程上的差异,处理器在硬件上也由于端模式问题在设计中有所不同。从系统的角度上看,端模式问题对软件和硬件的设计带来了不同的影响,当一个处理器系统中大小端模式同时存在时,必须要对这些不同端模式的访问进行特殊的处理。

小端外设是指这种外设中的寄存器以小端方式进行存储,如PCI设备的配置空间,NOR FLASH中的寄存器等等。

对于有些设备,如DDR颗粒,没有以小端方式存储的寄存器,因此从逻辑上讲并不需要对端模式进行转换。在设计中,只需要将双方数据总线进行一一对应的互连,而不需要进行数据总线的转换。

如果从实际应用的角度说,采用小端模式的处理器需要在软件中处理端模式的转换,因为采用小端模式的处理器在与小端外设互连时,不需要任何转换。

而采用大端模式的处理器需要在硬件设计时处理端模式的转换。大端模式处理器需要在寄存器,指令集,数据总线及数据总线与小端外设的连接等等多个方面进行处理,以解决与小端外设连接时的端模式转换问题。

在寄存器和数据总线的位序定义上,基于大小端模式的处理器有所不同。

一个采用大端模式的32位处理器,将其寄存器的最高位msb(most significant bit)定义为0,最低位lsb(lease significant bit)定义为31;而小端模式的32位处理器,将其寄存器的最高位定义为31,低位地址定义为0。

与此向对应,采用大端模式的32位处理器数据总线的最高位为0,最高位为31;采用小端模式的32位处理器的数据总线的最高位为31,最低位为0。

大小端模式处理器外部总线的位序也遵循着同样的规律,根据所采用的数据总线是32位,16位和8位,大小端处理器外部总线的位序有所不同。

大端模式下32位数据总线的msb是第0位,MSB是数据总线的第0~7的字段;而lsb是第31位,LSB是第24~31字段。小端模式下32位总线的msb是第31位,MSB是数据总线的第31~24位,lsb是第0位,LSB是7~0字段。

大端模式下16位数据总线的msb是第0位,MSB是数据总线的第0~7的字段;而lsb是第15位,LSB是第8~15字段。小端模式下16位总线的msb是第15位,MSB是数据总线的第15~7位,lsb是第0位,LSB是7~0字段。

大端模式下8位数据总线的msb是第0位,MSB是数据总线的第0~7的字段;而lsb是第7位,LSB是第0~7字段。小端模式下8位总线的msb是第7位,MSB是数据总线的第7~0位,lsb是第0位,LSB是7~0字段。

由上分析,我们可以得知对于8位,16位和32位宽度的数据总线,采用大端模式时数据总线的msb和MSB的位置都不会发生变化,而采用小端模式时数据总线的lsb和LSB位置也不会发生变化。

为此,大端模式的处理器对8位,16位和32位的内存访问(包括外设的访问)一般都包含第0~7字段,即MSB。小端模式的处理器对8位,16位和32位的内存访问都包含第7~0位,小端方式的第7~0字段,即LSB。

由于大小端处理器的数据总线其8位,16位和32位宽度的数据总线的定义不同,因此需要分别进行讨论在系统级别上如何处理端模式转换。

在一个大端处理器系统中,需要处理大端处理器对小端外设的访问。大端处理器采用32位总线与小端外设进行访问时,大端处理器的32位数据总线的第0~7位用来处理OP0,第8~15位用来处理OP1,第16~23位用来处理OP2,第24~31位用来处理OP3。而32位的小端设备使用数据总线的第31~24位用来处理OP0,第23~16位用来处理OP1,第15~8位用来处理OP2,第7~0位用来处理OP3。

大端处理器,如MPC8541,使用stw,sth,stb和lwz,lhz,lbz指令对32位的外部设备进行访问。在这些指令结束后,存放在外部设备的数据将被读入MPC8541的通用寄存器中。为保证软件的一致性,当访问结束后,存放在通用寄存器的字节序,即OP0,OP1,OP2和OP3必须要和存放在小端外设的字节序一致。此时在使用大端处理器的数据总线连接小端外设时必须要进行一定的处理,按照某种拓扑结构连接以保证软件的一致性。采用大端处理器访问小端设备时,将各自的OP0~OP3字段直接相连。在大端处理器的32位数据总线的最高位为0,最低位为31;而小端设备的最高位为31,最低位为0。因此硬件工程师在进行信号连接时需要将采用大端处理器的0~31位分别与小端设备的31~0位一一对应,进行互连。

大端处理器使用8位,16位数据总线对8位,16位的小端外设进行连接。对于32位处理器,用来连接外设的总线一般是32位。因此体系结构工程师在进行大端处理器总线设计时有两种选择,是采用32位总线的高端部分(第0~15字段)还是低端部分(第16~31字段)连接小端设备。PowerPC处理器使用32位总线的高端部分,即数据总线的第0~15位连接16位的小端设备,使用0~7位连接8位的小端设备。

posted on 2019-07-03 14:04  活着的虫子  阅读(798)  评论(0编辑  收藏  举报

导航