2010-12-21 10 views
5

Necesito ayuda para entender el endianness dentro de los registros de la CPU de los procesadores x86. Escribí este pequeño programa conjunto:Endianidad dentro de los registros de la CPU

section .data 
section .bss 

section .text 
    global _start 
_start: 
    nop 
    mov eax, 0x78FF5ABC 
    mov ebx,'WXYZ' 
    nop ; GDB breakpoint here. 
    mov eax, 1 
    mov ebx, 0 
    int 0x80 

me encontré con este programa en GDB con un punto de interrupción en la línea número 10 (comentado en la fuente más arriba). En este punto de interrupción, info registers muestra el valor de eax=0x78ff5abc y ebx=0x5a595857.

Dado que los códigos ASCII para W, X, Y, Z son 57, 58, 59, 5A respectivamente; e intel es little endian, 0x5a595857 parece ser el orden correcto de bytes (el byte menos significativo primero). ¿Por qué entonces no es la salida para eax register 0xbc5aff78 (byte menos significativo del número 0x78ff5abc primero) en lugar de 0x78ff5abc?

Respuesta

5

Endianness sólo tiene sentido para la memoria, donde cada byte tiene un numérica dirección. Cuando MSByte de un valor se coloca en una dirección de memoria mayor que LSByte, se llama Littte endian, y esta es la endianidad de cualquier procesador x86.

Mientras que para la distinción entre números enteros y LSByte MSByte es clara:

0x12345678 
MSB---^^ ^^---LSB 

No está definido para los literales de cadena!No es obvio qué parte de la WXYZ debe ser considerado LSB o MSB:

1) La forma más obvia,

'WXYZ' -> 0x5758595A 

llevaría a fin de memoria ZYXW.

2) El camino no no es tan obvio, cuando la orden de memoria debe coincidir con el orden de literales:

'WXYZ' -> 0x5A595857 

El ensamblador tienen que elegir uno de ellos, y al parecer se opta por la segunda.

14

Endianidad dentro de un registro no tiene sentido ya que endianness describe si el orden de bytes es de baja a alta dirección de memoria o de alta a baja memoria. Los registros no son direccionables por bytes, por lo que no hay una dirección baja o alta dentro de un registro. Lo que está viendo es cómo su depurador imprime los datos.

+0

Gracias por la respuesta. Aparentemente, 'WXYZ' está almacenado en orden inverso en el registro ebx. De acuerdo con el depurador, el registro BL contiene 87 (valor decimal de 0x57); seguramente, hay una noción de orden de bytes aquí? ¿Por qué no se almacenó 'W' en los 8 bits más altos de ebx? – wrxyz

+3

En realidad, los registros * son * parcialmente byte direccionables. Puede acceder a los dos bytes inferiores de EAX con AL y AH. –

+2

Eso es byte accesible, no byte "direccionable". Puede acceder a ese byte inferior pero aún no puede responder a la pregunta: "es ese byte inferior ubicado en una dirección de memoria más alta o más baja que el byte más alto". (Bueno, puede argumentar que el código de operación, si se interpreta como un número entero, es más grande o más pequeño que el otro, pero eso es muy arbitrario) – slebetman

9

El ensamblador maneja las dos constantes de forma diferente. Internamente, un valor en el registro EAX se almacena en formato big-endian. Se puede ver que al escribir:

mov eax, 1 

Si inspecciona el registro, verá que su valor es 0x00000001.

Cuando le dice al ensamblador que desea el valor constante 0x78ff5abc, eso es exactamente lo que se almacena en el registro. Los 8 bits altos de EAX contendrán 0x78, y el registro AL contiene 0xbc.

Ahora, si fuera a almacenar el valor de EAX en la memoria, se distribuiría en la memoria en el orden inverso. Es decir, si tuviera que escribir:

mov [addr],eax 

Y luego inspeccionados memoria en [DIRECCIÓN], que se vería 0xBC, 0x5a, 0xff, 0x78.

En el caso de 'WXYZ', el ensamblador supone que desea cargar el valor de forma que si lo escribiera en la memoria, se establecería como 0x57, 0x58, 0x59, 0x5a.

Eche un vistazo a los bytes de código que genera el ensamblador y verá la diferencia. En el caso de mov eax,0x78ff5abc, verá:

<opcodes for mov eax>, 0xbc, 0x5a, 0xff, 0x78 

en el caso de mov eax,WXYZ, verá:

<opcodes for mov eax>, 0x57, 0x58, 0x59, 0x5a 
+1

Entonces, cuando decimos que una CPU es little-endian, ¿estamos diciendo que la CPU leerá múltiples bytes de la memoria siguiendo las reglas de "little-endian"? Y los valores en el registro se llevarán a cabo en Big Endian siempre? –

+2

@KorayTugay: Que yo sepa, eso es cierto para los procesadores modernos. No sé sobre procesadores antiguos, pero sospecho que es cierto. "Endianess" solo se refiere a cómo la CPU espera que los valores se almacenen en la memoria. –

+0

Muchas gracias por la información. –

Cuestiones relacionadas