大小端如何理解记忆

大小端

  • 大小端
    • 背景
    • 常规理解
    • 轻松记忆
    • 示例

背景

  在不同的计算机系统中,数据的存储和读取有所不同,计算机的通信和存储依赖于一致的规则。目前计算机通常采用的存储机制主要有两种:大端模式(Big-endian)和小端模式(Little-endian)

常规理解

  大端模式:数据的低位或低字节(对整个序列取值影响最小的那个bit/byte)保存在内存的高地址中,而数据的高位或高字节,存储时放在低地址,读取时放在流开始。这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放,存储顺序与我们所看到的数据顺序一致
  小端模式:数据的低位或低字节,存储时放在低地址,读取时放在流的末尾,而数据的高位或高字节保存在内存的高地址中。

轻松记忆

  在裘宗燕翻译的《程序设计实践》里,这对术语并没有翻译为“大端”和小端,而是“高尾端”“低尾端”,这就好理解了:如果把一个数看成一个字符串,比如11223344看成”11223344”,末尾是个’\0’,’11’到’44’个占用一个存储单元,那么它的尾端很显然是44,前面的高还是低就表示尾端放在高地址还是低地址。
  (数据看成字符串)大端——高尾端,小端——低尾端
  尤其需要注意:存储和传输(/读取)都遵循相同的机制,计算机才能正常通信。

示例

  下面这个例子,基于ubuntu14.04 Intel x86_64环境,目前Intel x86是小端模式。
  两个不同的4字节16进制数据x=0x12345678y=0x1,强转为char*型,打印每个字节的地址及值

#include   
#include   
main()  
{
    int x=0x12345678;
    unsigned char *p=(char *)&x;
    printf("x = %x\n", x);
    printf("%p %p %p %p\n",&p[0],&p[1],&p[2],&p[3]);
    printf("%0x %0x %0x %0x\n",p[0],p[1],p[2],p[3]);

    int y=0x1;  
    unsigned char *q=(char *)&y;
    printf("y = %x\n", y);
    printf("%p %p %p %p\n",&p[0],&p[1],&p[2],&p[3]);
    printf("%02x %02x %02x %02x\n",q[0],q[1],q[2],q[3]);
}

  运行结果如下,可以看出地址是递增的,并且尾端 x的78和y的01 都是存储在低地址,即低尾端,小端模式:

x = 12345678
0x7ffe25cb4478 0x7ffe25cb4479 0x7ffe25cb447a 0x7ffe25cb447b
78 56 34 12
y = 1
0x7ffe25cb4478 0x7ffe25cb4479 0x7ffe25cb447a 0x7ffe25cb447b
01 00 00 00

  Little-Endian主要用于PC的CPU中,如Intel x86系列,很多的ARM,DSP都为小端模式;Big-Endian则主要应用在目前的Mac机器中,目前TCP/IP网络及Java虚拟机的字节序都是Big-endian的。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

你可能感兴趣的:(Linux,ubuntu)