2017-02-15 108 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