难记的大端小端
曾经被电面到一个题目,如何判断一个系统是大端还是小端, 方法其实很简单
int main(){
int i = 0x12345678; // 注意必须是16进制,否则难以判断
return *(char*)&i;
}
在linux 的执行结果
gcc test.c
$./a.out
$echo $?
120
120 即 0x78, 证明低位放在了低地址,所以是小端系统(little endian )。
这样说可能不够直观,而且内存中怎么分布本来就比较抽象,所以这里演示打印内存并画个图来表示
用gdb 打印内存地址
使用disassemble命令反汇编后,可见我们的i在 -0xc(%rbp) 位置,也就是 %rbp-0xc
│ >0x555555555150 <main+23> movl $0x12345678,-0xc(%rbp)
打印4个字节的内存,用到x命令,方法是 x/fmt,若记不住,只需要在gdb内使用help x
(gdb) x/4xb $rbp - 0xc
0x7fffffffe7c4: 0x78 0x56 0x34 0x12
(gdb)
4 表示重复4次,x表示显示为16进制,b表示每次打印的长度为1字节
下面值打印逐步打印一个字节,更清楚
(gdb) x/1xb $rbp - 0xc
0x7fffffffe7c4: 0x78
(gdb) x/1xb $rbp - 0xb
0x7fffffffe7c5: 0x56
(gdb) x/1xb $rbp - 0xa
0x7fffffffe7c6: 0x34
(gdb) x/1xb $rbp - 0x9
0x7fffffffe7c7: 0x12
(gdb)
画个图
c7 | c6 | c5 | c4 |
---|---|---|---|
0x12 | 0x34 | 0x56 | 0x78 |
而我们的i指针地址指的是 c4, 所以c4是端, lsb
处在端位置,所以是小端系统, little endian
(gdb) p $rbp - 0xc
$2 = (void *) 0x7fffffffe7c4
也可以看出,系统通过一个地址取值是从低地址取到高地址。 c4 c5 c6 c7
区分endian
搞清楚了端
,就很好判断endian, 给两个图理解什么是big endian
文章的第一个字母都是比较大, 这叫big endian
总结
Linux 是一个小端系统, windows也是, 可以顺便说网络 字节序是 大端