众所周知,目前市面上pc,手机等基本都是小端模式,而有部分机器是大端模式,对于网络传输规定为大端模式。目前我们搜索到的大部分介绍都只有小端模式指的是高字节存在地址高位,低字节在地址低位。对于这句话,其实大部分学习者完全感受不到,原因是大部分的教材资料不是16位就是32位cpu,汇编容易指明XH,XL使得高低字节是明确的。
那么什么时候最容易理解呢?答案是使用c语言整形指针去访问字符数组或者使用字符指针访问整形数据并尝试进行运算和赋值。
对于char str[5]="1234"
如果尝试使用int *intp=(int*)&str
那么读取的整数将会是"4321"字符数据的排列。原因是整形指针尝试将str解释为整形时,会从str[0]开始读入数据,由于是小端,那么先读入的字节将会读为低字节,也就是整数的低端,书写体的右边字节,依次以一字节读入时翻译成人能理解的方式就是"4321"。
与直觉相符合的是intp指向的确实是1的地址,不是4,地址确实是从1往4读而不是从4往1读。但整形的实际内容确实是"4321"而不是"1234"的猜测。如果你是这样猜测,使用intp去进行按位与的加密或者与整数加减,那么结果将令你失望,原因是你不经意间算反了,你认为的"1234"+xxx实际会变成"4321"+xxx。
这个问题在实际上是有意义的。比如你可能需要使用字符指针去访问整形数组,你期待的是改变你所看见的整形部分字节内容。如果你只带着人的习惯去操作,那么你很容易操作到错误的字节。char* charp=(char*)&a对于整形的内存字节排列,高字节将是当前charp+3,以人常识顺序将从charp+3往前访问至charp才是真正的整形数据。
对于这个问题,在大端模式下获得的内容也将与之相反,它将符合人的常见猜想。由于不同架构上的不统一,所以这是一个UB行为。但虽然是UB行为,但却有实际需求。如加密算法就容易出现这种拼接字节内容组成新数据。所以小端架构的加密算法在大端下就容易出问题,需要针对性实现。除非不进行UB行为的操作,否则必定会造成差异,需要每一步实际检查才能考虑移植。
当然,这种UB行为还有其他需求并且很常见,所以小伙伴们使用时需要多加注意。