gdbのエンディアンを反転しますか?

Aug 23 2020

gdb、私は時々 、それはバイトが左から右、時には右から左に表示します理由として困惑BIXです。間に命令が実行されていない例を次に示します。

>>> x/4b $rbp-4 0x7fffffffe43c: 0x04 0x00 0x03 0x16 >>> x/2h $rbp-4
0x7fffffffe43c: 0x0004  0x1603

なぜこれがgdbで行われるのですか?私はそれが常にそれらを次のように印刷すると思います:

04 00 03 16

回答

1 PeterCordes Aug 23 2020 at 22:19

GDBは、ターゲットマシンのネイティブエンディアン(デフォルトでは1)を使用して、要求したサイズのチャンクを整数として解釈します。アドレスはチャンク間で左から右に増加します。x86はリトルエンディアンです。

チャンク内に、04 0016ビットリトルエンディアン整数として解釈です 0x0004。これにより、GDBshortは、たとえば、期待どおりの配列をダンプします。GDBに16ビット整数チャンクを要求したので、GDBは指示どおりに動作し、左端の桁が最も重要な標準の場所と値の表記を使用して整数を表示します。ハーフワードを要求したため、バイトを個別に出力しようとはしていません。

メモリ順にバイトが必要な場合は、を使用しますb。それが目的です。


脚注1

GDBのエンディアン設定を変更できます。show endian現在の設定を表示します。ただし、set endian big問題が発生し、レジスタ値が破損します。例_start:で停止した場合:

(gdb) p /x $rsp $1 = 0x7fffffffe6d0       # this is normal for x86-64
(gdb) set endian big
The target is assumed to be big endian
(gdb) x /16xw $rsp 0xd0e6ffffff7f0000: Cannot access memory at address 0xd0e6ffffff7f0000 (gdb) p /x $rsp
$2 = 0xd0e6ffffff7f0000   # this is obviously broken, byte-reversed

レジスタにはエンディアンがなく、別のコマンドのアドレスとして値を展開するときにレジスタを反転すると、完全に壊れます。


関連する正確ではない重複:

  • GDBはメモリアドレスを正しく解釈していますか?
  • メモリに保存されているデータが逆になるのはなぜですか?
  • ビッグエンディアンとリトルエンディアンの小さな混乱
samuelbrody1249 Aug 23 2020 at 23:30

ピーターは正解で受け入れられた答えを持っていますが、ここでも非常に簡単な説明をします。これは私の理解に役立ちました。


したがって、数値220x1616進数)を2バイトの値としてメモリに格納するとします。

x86はリトルエンディアン(最上位バイトを最上位メモリアドレスに格納)であるため、次のように格納します。

0xAA1: 0x16                       (LSB)
0xAA2: 0x00                       (MSB)

ここで、メモリアドレスの昇順でバイトごとに出力すると、明らかに次のようになります。

0xAA1:  0x16 0x00                (2 bytes, byte by byte in increasing memory address)

ただし、22backの元の値が必要な場合は、2バイトの値をリトルエンディアンとして解釈して、正しい値を返すようにする必要があります。

0xAA1:  0x0016 # 22 in decimal  (bytes flipped back to interpret it properly in program