Endians是什么意思?它是数据在内存中的排列顺序。在微处理器中,象long/DWORD(32 bits) 0x12345678 这样的数据总是按照高位优先(BIG ENDIAN)方式存放的。但在内存中,数据存放顺序则因微处理器厂商的不同而不同。
Byte:一个字节,标记为byte 0
Word:二个字节,从byte 0到byte 1
Long : 四个字节,从byte 0到byte 3
每个byte由8个位(bit)组成,从bit 7 到 bit 0 (从左往右)。
每个word由16个 bit 组成,从bit 15 到 bit 0 (从左往右)。
每个long由32个 bit 组成,从bit 31 到 bit 0 (从左往右)。
byte 0 是LSB (Less Significant Byte,最低有效字节),byte 3 是MSB (Most Significant Byte,最高有效字节)。因此如果有:
Byte : 3 2 1 0
Number : $12 $34 $56 $78
则值等于:$12*256^3 + $34*256^2 + $56*256^1 + $78*256^0
word类型也一样。word 0 是LSW (Less Significant Word,最低有效字),word 1 是MSW (Most Significant Word,最高有效字):
Word : 1 0
Number : $1234 $5678
值等于:$1234*65536^1 + $5678*65536^0.
BIG ENDIAN : 最低地址存放高位字节,可称为高位优先。内存从最低地址开始,顺序存放:
Byte : Byte 3 ($12) (正好是MSB)
Word : Byte 3 到 Byte 2,即word 1 ($1234) (按照从MSB 到 LSB 顺序存放)
Long : Byte 3 到 Byte 0,即word 1 到 word 0 ($12345678) (按照从MSB 到 LSB 顺序存放)
BIG ENDIAN 存放方式正是我们的书写方式,大数先写(比如,总是按照千、百、十、个位来书写数字)。而且所有的处理器都是按照这个顺序存放数据的。
在内存中,根据地址 n (+ 位移量),存放的数据分别是:
n+0 : Byte 3 ($12) (MSB 优先: BIG Endian)
n+1 : Byte 2 ($34)
n+2 : Byte 1 ($56)
n+3 : Byte 0 ($78) (LSB)
Byte 0 的位置是:'n+3' (在 'n+3', byte 0 等于 $78)
Word 0 的位置是:'n+2' ('n+2' 到 'n+3', byte 1 到 byte 0, word 0 等于 $5678)
Long 0 的位置是:'n+0' ('n+0' 到 'n+3', byte 3 到 byte 0, long 0 等于 $12345678)
高位优先方式对于嵌入式系统和调试内存映象都很有用。在寄存器中读到的数据就是内存里的数据。但是如果要在word 0 的地址 'n+2' 处提取低位字(Low Word),就要用附加的内存,通过移位后才能得到,所以会稍慢些。
例如在寄存器中有:$12345678
从地址 'n+0' 开始: $12 $34 $56 $78 (按字节从MSB 到 LSB,即byte 3 到 byte 0)
从地址'n+0' 开始: $1234 $5678 (按字从MSB 到 LSB, 即word 1 到 word 0)
BIG ENDIAN 排列顺序还广泛运用在TCP/IP协议上!主要使用BIG Endian 排列结构的是摩托罗拉的 Motorola 6800 系列,68000 系列和ColdFire 系列。PowerPC 是用低位优先(Little Endian)顺序,它是从IBM Power 处理器系列派生而来的。
LITTLE ENDIAN : 最低地址存放低位字节,可称为低位优先。内存从最低地址开始,顺序存放:
Byte : Byte 0 ($78) (正好是 LSB)
Word : Byte 0 到 Byte 1,即 word 0 ($7856) (按照从LSB 到MSB 顺序存放)
Long : Byte 0 到 Byte 3,即 word 0 到 word 1 ($78563412) (按照从LSB 到MSB 顺序存放)
LITTLE ENDIAN 处理器是通过硬件将内存中的LITTLE ENDIAN 排列顺序转换到寄存器的BIG ENDIAN排列顺序的,没有数据加载/存储的开销,不用担心。
在内存中,根据地址 n (+ 位移量),存放的数据分别是:
n+0 : Byte 0 ($78) (LSB 优先:Little Endian)
n+1 : Byte 1 ($56)
n+2 : Byte 2 ($34)
n+3 : Byte 3 ($12) (MSB)
Byte 0 的位置是:'n+3' (在 'n+3', byte 0 等于 $78)
Word 0 的位置是:'n+2' ('n+2' 到 'n+3', byte 1 到 byte 0, word 0 等于 $5678)
Long 0 的位置是:'n+0' ('n+0' 到 'n+3', byte 3 到 byte 0, long 0 等于 $12345678)
Byte 0 的位置是:'n+0' (在 'n+0', byte 0 等于 $78)
Word 0 的位置是:'n+0' ('n+0' 到 'n+1', byte 0 到to byte 1, word 0 等于 $5678,按照 LITTLE ENDIAN 顺序)
Long 0 的位置是:'n+0' ('n+0' 到 'n+3', byte 0 to byte 3, long 0 等于 $12345678,按照 LITTLE ENDIAN 顺序)
低位优先顺序对于要取得诸如LSB或LSW这样的低位数据是很有用的。只要在起始位置上直接提取即可。不过在内存调试时可有些“古怪”。
例如在寄存器中有:$12345678
从地址 'n+0' 开始:$78 $56 $34 $12 (按字节从LSB 到 MSB)
从地址 'n+0' 开始:$7856 $3412 (按字从LSB to MSB)
注意:少数一些处理器是按照LITTLE ENDIAN 排列顺序来进行位运算的,就是说,一个从bit 31 到bit 0 表达的long类型数值按照从bit 0到bit 31的顺序来存放!
寄存器有: $12345678 (%10010001101000101011001111000)
在地址'n+0':$01CD4589 (%0001110011010100010110001001) (老天,真蠢!)
附件:本文提及的数据格式:
公司: Motorola Toshiba Intel
十进制(Decimal) : 123 123 123 (缺省)
八进制(Octal) : @173 o173 173o
十六进制(Hexa) : $7B h7B 7Bh
二进制(Binary) : %1111011 b1111011 1111011b