看了多篇关于bigendian和littleendian的解释文章,觉得都说的不够彻底。现记录几点说的不清楚的地方,以作备忘。
首先明确大小端是与cpu相关的,而非系统平台相关的。intelX86为小端。
其次大小端对位移操作没影响。不管大小端,左移都是消高位,右移都是消低位。因为位移操作汇编出来都只有一句:
SHL/SHR COUNT,其实现由cpu制造商自己去处理。来满足位移定义,不需要程序员操心。
看下面的测试大小端的程序用例:
int a=1;
char b=*((char*)&a);
若b为1,则为小端,否则大端。
在我的机器上结果为1,结论正确。
这里忽略了一个假设,那就是,假设程序可用存储空间从0x00ff43c0处开始,那么当分配了4个字节给a后,
&a取到得地址是0x00ff43c0还是0x00ff43c4?显然我们基于的假设是0x00ff43c0。那就是整数和数组一样,也是从低往高分配。
我们来看一下上面代码的汇编实现(基于80x86系列):
int a=1;
00412FE8 mov dword ptr [ebp-0Ch],1
char b=*((char*)&a);
00412FEF mov al,byte ptr [ebp-0Ch]
00412FF2 mov byte ptr [ebp-15h],al
上面的代码是x86系列的指令集,首先将1赋值给a,a可以理解为地址符,值为DS:[EBP-0CH],上面用到了类型说明,类似于强制类型转换,指明该地址指向的是双字类型。紧接着下面又将a解释为指向单字节的地址。然后将单字节内的数据送到AL,然后从AL送到b指向的地址。这里的2次类型说明无法确定上面的假设是哪一种。但我们可以从结论反推出内存的分配顺序:整数从低到高。我以前一直误以为是从高到低分配的。