C 特定内存地址上的内容与gdb中预期的内容不同

C 特定内存地址上的内容与gdb中预期的内容不同,c,memory,binary,gdb,memory-address,C,Memory,Binary,Gdb,Memory Address,我有int类型的变量I,它的值是129。我在gdb中使用了这个变量的各种表示形式 # Decimal format of i (gdb) p/d i $18 = 129 # Binary format of i (gdb) p/t i $19 = 10000001 # Address of variable i (gdb) p &i $20 = (int *) 0xbffff320 # Binary format displayed at one byte (gdb) x /

我有int类型的变量I,它的值是129。我在gdb中使用了这个变量的各种表示形式

# Decimal format of i
(gdb) p/d i
$18 = 129


# Binary format of i
(gdb) p/t i
$19 = 10000001


# Address of variable i
(gdb) p &i
$20 = (int *) 0xbffff320


# Binary format displayed at one byte
(gdb) x /tb &i
0xbffff320:     10000001


# Decimal format displayed at four bytes (one word)
(gdb) x /dw &i
0xbffff320:     129


# Decimal format displayed at one byte
(gdb) x /db &i
0xbffff320:     -127
上面的输出可能是因为
10000001
两次补码相当于
-127
,如果我错了,请纠正我

据此:

# Size of int in bytes:
(gdb) p sizeof(int)
$22 = 4
我知道int在计算机内存中消耗4个字节。所以,若我的理解是正确的,那个么这个数字驻留在内存中的某个地址上,消耗4个字节(或32位,或1个字或1/2个巨字)。然后该数字的表示形式如下所示:

AAAAAAAA: XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
在哪里

所以,当我访问整数时,我需要知道它的地址以及它消耗了多少位。所以int消耗32位,可以使用
&
运算符获得地址。这是我在内存中的实际int表示形式(顺便问一下,为什么这两种表示形式不同?它与系统上的endian设置有关还是什么?)

现在我们来学习一点基础数学:

0xbffff320:     00000000 00000000 00000000 10000001
AAAAAAAA:       XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
AAAAAAAA:       8bits    8bits    8bits    8bits

8*3=24
(24)DEC == (0x18)HEX
0xbffff320 + 0x18 = 0xBFFFF338
0xBFFFF338应该是我最后一个八位组的地址。那么为什么这给了我
11001100
,而不是
1000001

(gdb) x/tb 0xBFFFF338
0xbffff338:     11001100
我正在打印一个字节。如果我打印整个int,它消耗4个字节(我不认为这在我的情况下是可能的,因为我没有对应于这个内存的变量名,但你明白了)这可能是一些奇怪的数字,因为我在声明变量之后访问内存,可能有一些垃圾,而且我的10000001将驻留在最重要的八位字节中,但为什么现在呢

编辑: 根据建议,我添加了3个字节,而不是以前的24个字节,但结果仍然是错误的:

(3)DEC == (3)HEX
0xbffff320 + 0x3 = 0xbffff323

(gdb) x/tb 0xbffff323
0xbffff323:     00000000

仍然不返回
10000001
这里有什么问题?

保持简单。表达式向地址添加了24个字节,而不是24位。

看来您自己已经解决了这个问题:

(gdb) x /tb &i
0xbffff320:     10000001  #### Look at the address of this byte ####

# Binary format displayed as four bytes
(gdb) x/4tb &i
0xbffff320:     10000001        00000000        00000000        00000000
#                +0              +1             +2               +3
存储整数时,先存储最低有效字节。另外3个字节保存00000000

所以想必

(gdb) x/tb 0xbffff320
0xbffff320:     10000001

(gdb) x/tb 0xbffff321
0xbffff321:     00000000

(gdb) x/tb 0xbffff322
0xbffff322:     00000000

(gdb) x/tb 0xbffff323
0xbffff323:     00000000

地址是按字节,而不是按位;为什么您要尝试向起始地址添加24个字节?我也使用了3个字节,但给出了错误的结果,请参阅编辑的问题。请参阅我编辑的问题。我也试过用3个字节。啊,现在我明白了。让我困惑的是:
x/4tb&i vs x/1tw&i
我想知道为什么两种输出都不同,以及为什么设置endian会破坏gdb。谢谢如果您正在检查字节,那么不管字节的大小,都会按照地址的顺序得到它们。如果您正在检查一个整数,您将以人类可读的形式得到它(即从左到右的大端)。我不知道你说“设置endian broke gdb”是什么意思。很抱歉,我把我的问题弄糊涂了。我在这里的另一个问题中提到了这一点:重点是,当我使用
set endian big
将endian设置为big时,我不再能够访问变量地址
&I
(gdb) x /tb &i
0xbffff320:     10000001  #### Look at the address of this byte ####

# Binary format displayed as four bytes
(gdb) x/4tb &i
0xbffff320:     10000001        00000000        00000000        00000000
#                +0              +1             +2               +3
(gdb) x/tb 0xbffff320
0xbffff320:     10000001

(gdb) x/tb 0xbffff321
0xbffff321:     00000000

(gdb) x/tb 0xbffff322
0xbffff322:     00000000

(gdb) x/tb 0xbffff323
0xbffff323:     00000000