¿Voltear endianness en gdb?
En gdbSoy un bix perplejo de por qué a veces imprime bytes de izquierda a derecha y, a veces, de derecha a izquierda. Aquí hay un ejemplo en el que no se ha ejecutado ninguna instrucción en el medio:
>>> x/4b $rbp-4 0x7fffffffe43c: 0x04 0x00 0x03 0x16 >>> x/2h $rbp-4
0x7fffffffe43c: 0x0004 0x1603
¿Por qué se hace esto en gdb? Creo que siempre los imprimiría como:
04 00 03 16
Respuestas
GDB usa los endiannes nativos de la máquina de destino (por defecto 1 ) para interpretar fragmentos del tamaño que solicitó como enteros, con direcciones que aumentan de izquierda a derecha entre fragmentos. x86 es little-endian.
Dentro de un fragmento, 04 00interpretado como un entero little-endian de 16 bits es 0x0004 . Esto hace que GDB descargue una matriz de shortla forma esperada, por ejemplo. Le pidió a GDB fragmentos de números enteros de 16 bits, por lo que hace lo que le dijo, mostrando el valor entero utilizando la notación de valor posicional estándar con el dígito más a la izquierda el más significativo. No está tratando de imprimir los bytes por separado porque solicitó medias palabras.
Si desea bytes en orden de memoria, utilice b. Para eso es.
Nota al pie 1 :
Puede cambiar la configuración de endianidad de GDB; show endianmuestra la configuración actual. Sin embargo, set endian bigcausa problemas y corrompe los valores de los registros. por ejemplo, cuando se detiene en _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
Los registros no tienen endianidad y cambiarlos al expandir su valor como dirección para otro comando está totalmente roto.
Duplicados no exactos relacionados:
- ¿GDB está interpretando correctamente la dirección de memoria?
- ¿Por qué se invierten los datos almacenados en la memoria?
- Big Endian y Little Endian little confusion
Peter tiene la respuesta correcta y aceptada, pero también pondré aquí una explicación muy breve que me ha ayudado a comprender.
Digamos que queremos almacenar el número 22( 0x16en hexadecimal) como un valor de dos bytes en la memoria.
Debido a que x86 es little-endian (almacena el byte más significativo en la dirección de memoria más alta), lo almacenaríamos así:
0xAA1: 0x16 (LSB)
0xAA2: 0x00 (MSB)
Ahora, si lo imprimimos byte a byte en orden creciente de dirección de memoria, obviamente se ve así:
0xAA1: 0x16 0x00 (2 bytes, byte by byte in increasing memory address)
Pero luego, si queremos el valor original de 22back, necesitamos interpretar el valor de dos bytes como little-endian para que devuelva el valor correcto:
0xAA1: 0x0016 # 22 in decimal (bytes flipped back to interpret it properly in program