本文介绍了GDB是否正确解释了内存地址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我正在使用GDB检查内存地址的内容,但不知道它是否正确显示。 (gdb)p(char *)0x8182f40 $ 4 = 0x8182f40XYZ(gdb) $ b $(gdb)x / 40x 0x8182f40-16 0x8182f30:0x00000000 0x00000000 0x000000a8 0x00000010 0x8182f40:0x005a5958 0x00000000 0x00000000 0x00000029 0x8182f50:0x00000000 0x00000000 0x00010000 0x082439d8 0x8182f60:0x08199100 0x00000000 0x08000000 0x00002f08 0x8182f70:0x00000002 0x000000b1 0x00000000 0x00000000 0x8182f80:0x00000000 0x00000000 0x00000000 0x00000000 0x8182f90:0x00000000 0x00000000 0x000000d4 0x00000002 0x8182fa0:0x000003f1 0x00007162 0x00000002 0x08178d00 0x8182fb0:0x00000000 0x080ef4b8 0x00000000 0x00000000 0x8182fc0:0x00000000 0x00000000 0x0000021d 0x00000000 上面的 0x8182f40 显示为 0x005a5958 ,但这看起来相反。这是正确的吗? 现在打印每个字节,我得到这个: (gdb)x / 40bx 0x8182f40-16 0x8182f30:0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x8182f38:0xa8 0x00 0x00 0x00 0x10 0x00 0x00 0x00 0x8182f40:0x58 0x59 0x5a 0x00 0x00 0x00 0x00 0x00 0x8182f48:0x00 0x00 0x00 0x00 0x29 0x00 0x00 0x00 0x8182f50:0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 这个更有意义: 0x8182f40:0x58 0x59 0x5a XYZ 我如何正确解释这些地址和内容? little endian 。 当存储多字节val在存储器中,有两种方式来存储它们: 。这被称为Little Endian或最低有效字节优先(LSB)。 较低地址上的较高字节。这被称为Big Endian或最高有效字节在先(MSB)。 从历史上看,一些CPU是小端的,有些是大端的大端序列可能更常见,但小端序列盛行。部分原因是最常见的ix86架构是小端。第二种最常见的架构ARM可以被配置为传统上很多操作系统都被用作大端(包括早期的Linux),最近每个人似乎都使用它作为小端。主要原因可能是为了避免检查从ix86移植的代码是否是endian-neutral。 原因看起来错误只是两个约定的冲突: / p> 数字从最左边到最右边的数字是先写入的 写入内存内容按地址递增的顺序从左到右。 但这只是一个约定。在计算机中,在给定 int 值 x 时,little endian可能稍微更合理,等于(char)x == *(char *)& x 成立,这在大端中是不正确的。当然,C规范非常小心,可以定义此实现(使用 char 它不违反严格的别名规则)。 I am examining the contents of a memory address using GDB, but don't know if it is being displayed correctly.(gdb) p (char *)0x8182f40 $4 = 0x8182f40 "XYZ"(gdb)(gdb) x/40x 0x8182f40-160x8182f30: 0x00000000 0x00000000 0x000000a8 0x000000100x8182f40: 0x005a5958 0x00000000 0x00000000 0x000000290x8182f50: 0x00000000 0x00000000 0x00010000 0x082439d80x8182f60: 0x08199100 0x00000000 0x08000000 0x00002f080x8182f70: 0x00000002 0x000000b1 0x00000000 0x000000000x8182f80: 0x00000000 0x00000000 0x00000000 0x000000000x8182f90: 0x00000000 0x00000000 0x000000d4 0x000000020x8182fa0: 0x000003f1 0x00007162 0x00000002 0x08178d000x8182fb0: 0x00000000 0x080ef4b8 0x00000000 0x000000000x8182fc0: 0x00000000 0x00000000 0x0000021d 0x00000000Content at 0x8182f40 above is shown as 0x005a5958, but this looks reversed. Is that correct?Now printing per byte, I get this:(gdb) x/40bx 0x8182f40-160x8182f30: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x000x8182f38: 0xa8 0x00 0x00 0x00 0x10 0x00 0x00 0x000x8182f40: 0x58 0x59 0x5a 0x00 0x00 0x00 0x00 0x000x8182f48: 0x00 0x00 0x00 0x00 0x29 0x00 0x00 0x000x8182f50: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00This one makes more sense: 0x8182f40: 0x58 0x59 0x5a X Y ZHow do I correctly interpret these addresses and contents? 解决方案 That's little endian.When storing multi-byte values in memory, there are two ways to store them:Lower bytes on lower addresses. This is called Little Endian or Least Significant Byte First (LSB).Higher bytes on lower addresses. This is called Big Endian or Most Significant Byte First (MSB).Historically some CPUs were little endian and some were big endian with big endian perhaps more common, but little endian prevailed. In part because the most common ix86 architecture is little endian. The second most common architecture, ARM, can be configured for either and while traditionally many operating systems used it as big endian (including early Linux), recently everybody seems to use it little endian. Main reason is probably to avoid having to check that code ported from ix86 is endian-neutral.The reason is looks "wrong" is just a conflict of two conventions:Numbers are written left-to-right with most significant digit firstContent of memory is written left-to-right in order of increasing addresses.But this is merely a convention. In computer, little endian might be slightly more logical in that given int value x, the equality (char)x == *(char *)&x holds, which is not true in big endian. Of course C specification is careful enough to leave this implementation defined (with char it does not violate strict aliasing rules).PDP-11 featured a third way, a special abomination called middle endian, where 16-bit values were little endian, but 32-bit values were composed of the two 16-bit units in big endian. 这篇关于GDB是否正确解释了内存地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-10 00:39