gdb 查看内存

难记的大端小端

曾经被电面到一个题目,如何判断一个系统是大端还是小端, 方法其实很简单

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也是, 可以顺便说网络 字节序是 大端

原文地址:https://www.cnblogs.com/hustcpp/p/13061625.html