Inverser l'endianness dans gdb?
Dans gdbJe suis un bix perplexe quant à savoir pourquoi parfois il imprime des octets de gauche à droite et parfois de droite à gauche. Voici un exemple où aucune instruction n'a été exécutée entre les deux:
>>> x/4b $rbp-4 0x7fffffffe43c: 0x04 0x00 0x03 0x16 >>> x/2h $rbp-4
0x7fffffffe43c: 0x0004 0x1603
Pourquoi est-ce fait dans gdb? Je pense qu'il les imprimerait toujours comme:
04 00 03 16
Réponses
GDB utilise les endiannes natifs de la machine cible (par défaut 1 ) pour interpréter les morceaux de la taille que vous avez demandée comme des entiers, les adresses augmentant de gauche à droite entre les morceaux. x86 est petit-boutiste.
Dans un bloc, 04 00interprété comme un entier petit-boutiste de 16 bits est 0x0004 . Cela rend GDB dump un tableau de shortla façon dont vous vous attendez, par exemple. Vous avez demandé à GDB des blocs d'entiers de 16 bits, il fait donc ce que vous lui avez dit, en affichant la valeur entière en utilisant la notation de valeur de position standard avec le chiffre le plus à gauche le plus significatif. Il n'essaie pas d'imprimer les octets séparément parce que vous avez demandé des demi-mots.
Si vous voulez des octets dans l'ordre de la mémoire, utilisez b. C'est pour ça que c'est.
Note de bas de page 1 :
Vous pouvez modifier le paramètre d'endianité de GDB; show endianaffiche le réglage actuel. Cependant, cela set endian bigcause des problèmes, corrompant les valeurs de registre. par exemple à l'arrêt à _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
Les registres n'ont pas d'endianité, et les retourner lors de l'extension de leur valeur en tant qu'adresse pour une autre commande est tout simplement totalement cassé.
Doublons associés non exacts:
- GDB interprète-t-il correctement l'adresse mémoire?
- Pourquoi les données stockées en mémoire sont-elles inversées?
- Petite confusion entre Big Endian et Little Endian
Peter a la réponse correcte et acceptée, mais je vais également mettre ici une très brève explication qui m'a aidé à comprendre.
Disons que nous voulons stocker le nombre 22( 0x16en hexadécimal) sous forme de valeur à deux octets en mémoire.
Parce que x86 est petit-boutiste (stocker l'octet le plus significatif à l'adresse mémoire la plus élevée), nous le stockerions comme ceci:
0xAA1: 0x16 (LSB)
0xAA2: 0x00 (MSB)
Maintenant, si nous l'imprimons octet par octet dans un ordre croissant d'adresse mémoire, cela ressemble évidemment à ceci:
0xAA1: 0x16 0x00 (2 bytes, byte by byte in increasing memory address)
Mais ensuite, si nous voulons la valeur d'origine de 22back, nous devons interpréter la valeur à deux octets comme étant little-endian afin qu'elle renvoie la valeur correcte:
0xAA1: 0x0016 # 22 in decimal (bytes flipped back to interpret it properly in program