2017-02-15 94 views
0

我知道这可能是一个明显的问题,但我决定学习一些低级别的编程。我从c和gdb开始。GDB检查命令与地址混淆

第一个问题:

`(gdb) x/10xb $rip 
0x4005a5 <main+4>: 0xb9 0x04 0x00 0x00 0x00 0xba 0x03 0x00 
0x4005ad <main+12>: 0x00 0x00 
(gdb) x/10xh $rip 
0x4005a5 <main+4>: 0x04b9 0x0000 0xba00 0x0003 0x0000 0x02be 0x0000 0xbf00 
0x4005b5 <main+20>: 0x0001 0x0000 
(gdb) x/10xw $rip 
0x4005a5 <main+4>: 0x000004b9 0x0003ba00 0x02be0000 0xbf000000 
0x4005b5 <main+20>: 0x00000001 0xffff9fe8 0x0000b8ff 0xc35d0000 
` 

问:为什么当我使用单元尺寸b的下一个地址0x4005ad但是当我使用H或W以下地址0x4005b5?

问题二:

`(gdb) x/4xw $rip + 0 
0x4005a5 <main+4>: 0x000004b9 0x0003ba00 0x02be0000 0xbf000000 
(gdb) x/4xw $rip + 1 
0x4005a6 <main+5>: 0x00000004 0x000003ba 0x0002be00 0x01bf0000 
(gdb) x/4xw $rip + 2 
0x4005a7 <main+6>: 0xBA000000 0x00000003 0x000002be 0x0001bf00 
(gdb) x/4xw $rip + 3 
0x4005a8 <main+7>: 0x03BA0000 0xbe000000 0x00000002 0x000001bf 
(gdb) x/4xw $rip + 4 
0x4005a9 <main+8>: 0x0003BA00 0x02be0000 0xbf000000 0x00000001 
(gdb) x/4xw $rip + 5 
0x4005aa <main+9>: 0x000003BA 0x0002be00 0x01bf0000 0xe8000000 
(gdb) x/4xw $rip + 6 
0x4005ab <main+10>: 0x00000003 0x000002be 0x0001bf00 0x9fe80000 
(gdb) x/4xw $rip + 7 
0x4005ac <main+11>: 0xBE000000 0x00000002 0x000001bf 0xff9fe800 
(gdb) x/4xw $rip + 8 
0x4005ad <main+12>: 0x02BE0000 0xbf000000 0x00000001 0xffff9fe8` 

问:为什么相同的值重复(大写字母),例如:在第一列,但移动到右边,就像从$翻录+ 2 $撕裂+ 5 BA在哪里开始,然后在中间,最后在最后?

回答

0

当你要求任何底层调试器显示从给定地址开始的内存值时,它将从连续位置获得一定数量的字节并显示它们。 (每个地址指的是内存中的一个特定字节)

在第一个问题中,您要求它显示十个字节,并将每个字节显示为两位十六进制值,每行八个字节,从0x4005a5到(0x4005a55 + 8)或0x4005ad

然后,您要求显示十个半字,每行八个半字,并且因为每个半字都是两个字节,地址从0x4005a5到(0x4005b5 + 16)或0x4005b5

你的第二个问题有点复杂。请记住,当你要求它显示从一个位置开始的内存内容时,它只会提取你在该位置开始的四个单词。当你选择一个更高的地址时,你将获得相同的内存值,只是移动一个。

那么为什么单词中的值似乎在错误的方向转移?这与你要求单词和x86 CPU以不直观的顺序(从最低有效字节到最多)获取单词有关。

这应该有所帮助: https://en.wikipedia.org/wiki/Endianness