总的来说,大小端的战争来源于人类的阅读顺序。

人类可视的数据表现形式为: 0x0810

  • 计算机的世界: 内存里排列,按照低地址到高地址为:0x10, 0x08。在内存的排列里,程序去读的时候

    • 小端的计算机世界: 读取是从低地址开始。
    • 大端的计算机世界: 读取也是从低地址开始。:)
    • 机器根本不认识大小端,他只是按照顺序从低地址向高地址读字节。

假设ptr指向的值为0x20150801。当我们从某个地址强转为一个结构体时: int a = (int)ptr;
在大端的机器里,它读取的顺序是 0x20 0x15 0x08 0x01 , 按照地址从低到高。 这是写的顺序,机器帮我们做了。
在小端的机器里,它读取的顺序是 0x01 0x08 0x15 0x20 , 按照地址从低到高。 这是写的顺序,机器帮我们做了。

真正要区分大小端是在读的过程中:
那么如果要将ptr翻译为一个short。 short b = (int)ptr;

  • 则在大端的机器里,b = 0x2015. 解释为:0x20 << 8 + 0x15 . 高位数据在低地址,我们就得按照这个规则还原数字。
  • 在小端的机器里, b = 0x0801, 解释为: 0x08 << 8 + 0x01. 低位数据在高地址,我们按照规则还原。

也就是说第一个区别,同一行代码在不同机器上得到的会是不同的结果。

人类的世界: 人类的世界阅读是 0x20, 0x15, 0x08, 0x10。这是合乎我们直觉的大端模式。所以网路中的http报文总是按照大端传输自己的数据,比如一个端口号 0x8088,传到小端机器上会被解释为 0x88 << 8 + 0x80 。数值反转过来。传到大端机器上则是 0x80 << 8 + 0x88

总结为两点:

  1. 如果在内存里 x address 观察指针地址,大小端会有差异。
  2. 大小端的差异存在对表现层的text进行解析的时刻。序列化阶段要还原成原来字段的意义。

这篇文章很好的解释了这个问题。

我们可以在Qemu上模拟大端系统行为。这里有一个PPC的大端QEMU镜像。

qemu-system-ppcw -hda debian_wheezy_powerpc_standard.qcow2 -L bios -m 1G -g 1024x768x8

后发现一个很有意思的CPU EMULATOR,基于QEMU。名字叫Unicore

标签: none

添加新评论