大小端字节序
说到字节序,它描述的是:一个多字节数值,在内存里存放时,高位字节和低位字节的排列顺序。其有大小端之分。
大端:低内存地址放高位字节,高内存地址放低位字节。
小端:低内存地址放低位字节,高内存地址放高位字节。
对于一个数,比如说 int 类型 的 1,我们截取它的第四位bit,为:00 01。左边的 0 是高位字节,右边的 1 为低位字节。
我们又知道,栈的使用是由高地址向低地址的,数值大的为高地址,比如:0xFFF0与0xFFF5相比,0xFFF5 是高地址。(对于这个,我发现了一个 vs 2022 的一个特性,详细请看本文后面的补充内容)。
由此可得,如果按照大端存储,那么应该是如下情况:
大小端字节序属于存储数据的组织方式,不是 CPU 硬件电路本身的 “硬件特性”,但受硬件架构决定,有些CPU甚至支持切换大小端。
所以,我们是不能自主选择大小端的,不过,在网络传输的时候,规定统一使用大端序,也叫网络字节序。
补充:vs 2022的 “奇怪” 现象
局部变量是存放在内存中的,如果我们创建的变量有先后关系,那么根据栈的增长方向可知,先创建的变量的地址是比后创建的变量的地址要更高的,但是在vs 2022 中,发现:
可以看到,这里 a 先被创建,并被赋值 1,b 后创建,赋值为 2。
&a:0x00000001f87aff7c4
&b:0x00000001f87aff7e4
b 的地址比 a 的更大,也就是 b 处于更高的地址。很显然,这不对,但为什么呢?
经过一番研究,原来在 vs 2022 的 x64 Debug下,编译器会把该栈帧所需空间一次性开好,然后对于变量的安排,便不再严格遵守 “先定义的变量地址更高” 这个简单结论。
如果换成 x86,我们发现结果就和预期相符了: