Endianness

José Luis Prieto


Los formatos de datos. El endianness

Al igual que existen sistemas de escritura de izquierda a derecha y otros en sentido contrario, también en el mundo de las computadoras existen sistemas que almacenan los datos de más de un byte en un sentido u otro. En una máquina no hablamos de izquierda o derecha, pero sí hacemos referencia al sentido ascendente de las posiciones de memoria, y en el caso de las comunicaciones del orden de salida de los bytes de una línea de transmisión.

Hablaremos a partir de ahora del 'formato de almacenamiento', que solo afecta a los datos de varios bytes. En un único byte, los bits siempre se ordenan del mismo modo.

El orden de los bits dentro de un byte es siempre 7, 6, 5, 4, 3, 2, 1, 0.

Dependiendo de la arquitectura del ordenador, hay que considerar el orden de los bytes en los tipos de datos numéricos que utilizan varios bytes. Existen dos formatos diferentes, denominados "Little Endian" (LE) y "Big Endian" (BE).

Supongamos un Long Int almacenado en 4 bytes: Byte3, Byte2, Byte1, Byte0.

El byte de la izquierda es el byte más significativo (MSB) y el de la derecha es el byte menos significativo (LSB). La denominación viene del hecho que una alteración en el byte de la izquierda provoca cambios mucho más grandes que en el de la derecha.

En el formato BE el byte de mayor peso se almacena en la dirección más baja de memoria y el byte de menor peso en la dirección más alta. Así, tendríamos:

Memoria base + 0 + 1 + 2 + 3
Byte 3 2 1 0

En el formato LE el byte de menor peso se almacena en la dirección más baja de memoria y el byte de mayor peso en la más alta. El caso anterior sería ahora:

Memoria base + 0 + 1 + 2 + 3
Byte 0 1 2 3

El formato BE es el que nos puede parecer más natural, al almacenarse en el orden en que escribimos. Este sistema lo emplean los procesadores Motorola 680x0, Hewlett-Packard PA-RISC y Sun SuperSPARC. El LE es el utilizado por la mayoría de procesadores de Intel.

Existen arquitecturas que permiten escoger la "endianness" que se desee usar. En estos sistemas el cambio se puede hacer por software, al arrancar el equipo, o por hardware, mediante algún puente en la placa base. Los procesadores capaces de entender ambos sistemas reciben el nombre de "bi-endian”, entre ellos tenemos los IA64, MIPS y ARM.

Importancia del orden

Ambos sistemas tienen ventajas e inconvenientes. En el caso del formato LE, las instrucciones en ensamblador para tomar los bytes proceden incrementando el desplazamiento sobre la dirección inicial del almacenamiento, lo que hace que las rutinas matemáticas sean más sencillas de implementar.

En el formato BE al tener el byte de mayor peso el primero, se puede comprobar de forma directa si el número es positivo o negativo sólo comprobando el primer bit del primer byte, sin necesidad de conocer la longitud del número. Esta forma de representación coincide con el orden de escritura de los números, de modo que las rutinas de conversión entre sistemas de numeración son más eficientes.

Importancia de conocer el formato

Incluso trabajando solo en una plataforma puede que tengamos necesidad de conocer el formato de almacenamiento, ya que diferentes librerías pueden tratar los ficheros con diferentes formatos de almacenamiento.

El "Byte Order Mark” (BOM), Byte de Marca de Orden, es un carácter Unicode que se utiliza como una firma que define el orden de los bytes (endianness) y la forma de codificación en un fichero de texto. Su código es U+FEFF. Además de usarse para indicar el orden de los bytes en cada palabra, también se puede utilizar como marca para indicar qué codificación Unicode se está utilizando:

Formato Bit Order Mask
UTF-16 Big Endian 0xfe 0xff
UTF-16 Little Endian 0xff 0xfe
UTF-32 Big Endian 0x00 0x00 0xfe 0xff
UTF-32 Little Endian 0xff 0xfe 0x00 0x00
UTF-8 con BOM 0xef 0xbb 0xbf

En el formato UTF8 sin BOM, el fichero no contiene la marca de orden inicial.

Si trabajamos con varias plataformas si será necesario conocer el formato de almacenamiento de ficheros, al igual que en el caso de las comunicaciones.

En algunos protocolos de nivel superior, el uso de BOM puede ser obligatorio, en el flujo de datos Unicode de ese protocolo.

El protocolo TCP usa el formato BE, por lo que los sistemas que usan LE deben convertir los datos al crear los paquetes TCP/IP. Las direcciones IP, que son números de multiBytes (4 octetos), se construyen colocando primero el MSB. Este es el orden en que se transmiten los datos multibyte en las comunicaciones de Internet, el denominado "network-byte order". En caso de utilizar un equipo con hardware LE, será preciso recolocar los Bytes en el orden adecuado, tanto en los flujos de entrada como en los de salida, para que los datos puedan ser interpretados correctamente.

Cambio entre formatos

Para cambiar entre los dos formatos podemos construir una función que intercambie los bytes. Esta función nos sirve para pasar de LE a BE y viceversa, debido a la simetría entre ambos formatos:

void Intercambio(long int *a)
{
   *a=(((*a)&0x000000FF)<<24) |
      ((((*a)&0x0000FF00)>>8)<<16) |
      ((((*a)&0x00FF0000)>>16)<<8) |
      (((*a)&0xFF000000)>>24);
}

tugurium