Endianness

HistoryEdit

Muchos procesadores históricos y existentes utilizan una representación de memoria big-endian, ya sea exclusivamente o como una opción de diseño. La representación de memoria big-endian se conoce comúnmente como orden de red, como se utiliza en el conjunto de protocolos de Internet. Otros tipos de procesadores utilizan la representación de memoria little-endian; otros utilizan otro esquema llamado «middle-endian», «mixed-endian» o «PDP-11-endian».

El IBM System/360 utiliza el orden de bytes big-endian, al igual que sus sucesores System/370, ESA/390 y z/Architecture. El PDP-10 también utiliza el direccionamiento big-endian para las instrucciones orientadas a bytes. El minicomputador IBM Series/1 también utiliza el orden de bytes big-endian.

Tratar con datos de diferente endianidad se denomina a veces el problema NUXI. Esta terminología alude a los conflictos de orden de bytes que se produjeron al adaptar UNIX, que se ejecutaba en el PDP-11 de endianos mixtos, a un ordenador IBM Series/1 de endianos grandes. Unix fue uno de los primeros sistemas en permitir la compilación del mismo código para plataformas con diferentes representaciones internas. Uno de los primeros programas convertidos debía imprimir Unix, pero en el Series/1 imprimía nUxi en su lugar.

El Datapoint 2200 utiliza una simple lógica bit-serial con little-endian para facilitar la propagación del carry. Cuando Intel desarrolló el microprocesador 8008 para Datapoint, utilizó little-endian por compatibilidad. Sin embargo, como Intel no pudo entregar el 8008 a tiempo, Datapoint utilizó un equivalente de integración de escala media, pero el little-endian se mantuvo en la mayoría de los diseños de Intel, incluyendo el MCS-48 y el 8086 y sus sucesores x86. El DEC Alpha, el Atmel AVR, el VAX, la familia MOS Technology 6502 (incluyendo el Western Design Center 65802 y el 65C816), el Zilog Z80 (incluyendo el Z180 y el eZ80), el Altera Nios II, y muchos otros procesadores y familias de procesadores son también little-endian.

El Motorola 6800 / 6801, el 6809 y la serie 68000 de procesadores utilizaban el formato big-endian.

El Intel 8051, al contrario que otros procesadores de Intel, espera direcciones de 16 bits para LJMP y LCALL en formato big-endian; sin embargo, las instrucciones xCALL almacenan la dirección de retorno en la pila en formato little-endian.

SPARC utilizó históricamente big-endian hasta la versión 9, que es bi-endian; de forma similar, los primeros procesadores IBM POWER eran big-endian, pero los descendientes PowerPC y Power ISA son ahora bi-endian. La arquitectura ARM era little-endian antes de la versión 3, cuando se convirtió en bi-endian.

Arquitecturas actualesEditar

Las series de procesadores Intel x86 y AMD64 / x86-64 utilizan el formato little-endian. Otras arquitecturas de conjuntos de instrucciones que siguen esta convención, permitiendo sólo el modo little-endian, incluyen Nios II, Andes Technology NDS32, y Qualcomm Hexagon.

Algunas arquitecturas de conjuntos de instrucciones permiten ejecutar software de cualquier endianness en una arquitectura bi-endian. Esto incluye ARM AArch64, C-Sky, Power ISA y RISC-V.

Las arquitecturas únicamente big-endianas incluyen la arquitectura IBM z/Architecture, Freescale ColdFire (que está basada en la serie Motorola 68000), Atmel AVR32 y OpenRISC. Los sistemas operativos IBM AIX y Oracle Solaris en Power ISA y SPARC bi-endian funcionan en modo big-endian; algunas distribuciones de Linux en Power han pasado a modo little-endian.

Bi-endiannessEdit

Algunas arquitecturas (incluyendo las versiones 3 y superiores de ARM, PowerPC, Alpha, SPARC V9, MIPS, PA-RISC, SuperH SH-4 y IA-64) cuentan con una configuración que permite cambiar el endianamiento en las búsquedas y almacenes de datos, en las búsquedas de instrucciones, o en ambas. Esta característica puede mejorar el rendimiento o simplificar la lógica de los dispositivos de red y el software. La palabra bi-endian, cuando se dice del hardware, denota la capacidad de la máquina para computar o pasar datos en cualquier formato endian.

Muchas de estas arquitecturas pueden ser cambiadas por software para que se ajusten por defecto a un formato endian específico (normalmente se hace cuando el ordenador arranca); sin embargo, en algunos sistemas el endianamiento por defecto se selecciona por hardware en la placa base y no puede cambiarse por software (por ejemplo, el Alpha, que ejecuta la instrucción en la placa base).Por ejemplo, el Alpha, que sólo funciona en modo big-endian en el Cray T3E).

Nótese que el término bi-endian se refiere principalmente a cómo un procesador trata los accesos de datos. Los accesos a las instrucciones (búsquedas de palabras de instrucción) en un determinado procesador pueden seguir asumiendo un endianamiento fijo, incluso si los accesos a los datos son totalmente biendianos, aunque no siempre es así, como en la CPU Itanium de Intel basada en IA-64, que permite ambos.

También hay que tener en cuenta que algunas CPUs nominalmente biendianas requieren la ayuda de la placa base para cambiar completamente el endianamiento. Por ejemplo, los procesadores PowerPC de 32 bits orientados al escritorio en modo little-endian actúan como little-endian desde el punto de vista de los programas que se ejecutan, pero requieren que la placa base realice un intercambio de 64 bits en todos los carriles de 8 bytes para garantizar que la visión little-endian de las cosas se aplique a los dispositivos de E/S. En ausencia de este hardware inusual de la placa base, el software del controlador del dispositivo debe escribir en diferentes direcciones para deshacer la transformación incompleta y también debe realizar un intercambio normal de bytes.

Algunas CPUs, como muchos procesadores PowerPC destinados a uso embebido y casi todos los procesadores SPARC, permiten la elección de endianidad por página.

Los procesadores SPARC desde finales de la década de 1990 (procesadores compatibles con SPARC v9) permiten elegir el modo de datos con cada instrucción individual que carga o almacena en la memoria.

La arquitectura ARM soporta dos modos big-endian, llamados BE-8 y BE-32. Las CPUs hasta ARMv5 sólo soportan el modo BE-32 o invariante de palabra. Aquí cualquier acceso naturalmente alineado de 32 bits funciona como en el modo little-endian, pero el acceso a un byte o palabra de 16 bits se redirige a la dirección correspondiente y no se permite el acceso no alineado. ARMv6 introduce el modo BE-8 o byte-invariante, donde el acceso a un solo byte funciona como en el modo little-endian, pero el acceso a una palabra de 16, 32 o (a partir de ARMv8) 64 bits resulta en un intercambio de bytes de los datos. Esto simplifica el acceso a la memoria no alineada, así como el acceso mapeado en memoria a los registros que no sean de 32 bits.

Muchos procesadores tienen instrucciones para convertir una palabra en un registro a la endogamia opuesta, es decir, intercambian el orden de los bytes en una palabra de 16, 32 o 64 bits. Sin embargo, no se invierten todos los bits individuales.

Las CPUs de arquitectura Intel x86 y x86-64 recientes tienen una instrucción MOVBE (Intel Core desde la generación 4, después de Atom), que obtiene una palabra en formato big-endian de la memoria o escribe una palabra en la memoria en formato big-endian. Por lo demás, estos procesadores son completamente little-endian. Además, ya contaban con una serie de instrucciones de intercambio para invertir el orden de los bytes del contenido de los registros, por ejemplo, cuando las palabras ya han sido obtenidas de ubicaciones de memoria en las que estaban en el formato «incorrecto».

Punto flotanteEditar

Aunque los omnipresentes procesadores x86 de hoy en día utilizan el almacenamiento little-endian para todos los tipos de datos (enteros, punto flotante), hay una serie de arquitecturas de hardware donde los números de punto flotante se representan en forma big-endian mientras que los enteros se representan en forma little-endian. Hay procesadores ARM que tienen una representación de punto flotante mitad little-endian, mitad big-endian para números de doble precisión: ambas palabras de 32 bits se almacenan en little-endian como los registros de enteros, pero la más significativa primero. Dado que ha habido muchos formatos de punto flotante sin una representación estándar «de red» para ellos, el estándar XDR utiliza como representación el IEEE 754 big-endian. Por lo tanto, puede parecer extraño que el extendido estándar de punto flotante IEEE 754 no especifique el endianamiento. En teoría, esto significa que incluso los datos de punto flotante IEEE estándar escritos por una máquina podrían no ser legibles por otra. Sin embargo, en los ordenadores estándar modernos (es decir, que implementan la norma IEEE 754), en la práctica se puede asumir con seguridad que el formato es el mismo para los números de punto flotante que para los enteros, lo que hace que la conversión sea sencilla independientemente del tipo de datos. (Sin embargo, los pequeños sistemas embebidos que utilizan formatos especiales de punto flotante pueden ser otro asunto.)

Datos de longitud variableEditar

La mayoría de las instrucciones consideradas hasta ahora contienen el tamaño (longitudes) de sus operandos dentro del código de operación. Las longitudes de operandos disponibles con frecuencia son de 1, 2, 4, 8 o 16 bytes.Pero también hay arquitecturas en las que la longitud de un operando puede mantenerse en un campo separado de la instrucción o con el propio operando, por ejemplo, mediante una marca de palabra. Los tipos de datos de estos operandos son cadenas de caracteres o BCD.

Las máquinas que pueden manipular este tipo de datos con una instrucción (por ejemplo, comparar o sumar) son, por ejemplo, las siguientes IBM 1401, 1410, 1620, System/3×0, ESA/390, y z/Architecture, todos ellos de tipo big-endian.

OptimizationEdit

El sistema little-endian tiene la propiedad de que el mismo valor puede ser leído de la memoria en diferentes longitudes sin utilizar diferentes direcciones (incluso cuando se imponen restricciones de alineación). Por ejemplo, una posición de memoria de 32 bits con contenido 4A 00 00 puede ser leída en la misma dirección como de 8 bits (valor = 4A), de 16 bits (004A), de 24 bits (00004A), o de 32 bits (0000004A), conservando todas ellas el mismo valor numérico. Aunque esta propiedad little-endian rara vez es utilizada directamente por los programadores de alto nivel, a menudo es empleada por los optimizadores de código, así como por los programadores de lenguaje ensamblador.

En términos más concretos, tales optimizaciones son el equivalente del siguiente código C que devuelve true en la mayoría de los sistemas little-endian:

union { uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64;} u = { .u64 = 0x4A };puts(u.u8 == u.u16 && u.u8 == u.u32 && u.u8 == u.u64 ? "true" : "false");

Aunque no está permitido por C++, tal código de puntaje de tipo está permitido como «definido por la implementación» por el estándar C11 y comúnmente utilizado en el código que interactúa con el hardware.

Por otro lado, en algunas situaciones puede ser útil obtener una aproximación de un valor multibyte o multipalabra leyendo sólo su porción más significativa en lugar de la representación completa; un procesador big-endian puede leer dicha aproximación utilizando la misma dirección base que se utilizaría para el valor completo.

Las optimizaciones de este tipo no son portables a través de los sistemas de diferentes endianeces.

Orden de cálculoEditar

Algunas operaciones en los sistemas numéricos posicionales tienen un orden natural o preferido en el que se deben ejecutar los pasos elementales.Este orden puede afectar a su rendimiento en procesadores y microcontroladores direccionables por bytes a pequeña escala.

Sin embargo, los procesadores de alto rendimiento suelen obtener los operandos típicos de varios bytes de la memoria en la misma cantidad de tiempo que habrían obtenido un solo byte, por lo que la complejidad del hardware no se ve afectada por el orden de los bytes.

Las operaciones que comienzan en el dígito menos significativoEditar

La suma, la resta y la multiplicación comienzan en la posición del dígito menos significativo y propagan el acarreo a la posición subsiguiente más significativa.Cuando este primer byte contiene el dígito menos significativo, lo que equivale a un endoso pequeño, la implementación de estas operaciones es marginalmente más sencilla.

Las operaciones que comienzan en el dígito más significativoEditar

La comparación y la división comienzan en el dígito más significativo y propagan un posible acarreo a los siguientes dígitos menos significativos. Para los valores numéricos de longitud fija (típicamente de longitud 1,2,4,8,16), la implementación de estas operaciones es marginalmente más simple en las máquinas big-endianas.

Operandos de longitud variableEditar

Muchos procesadores big-endianos contienen instrucciones de hardware para comparar lexicográficamente cadenas de caracteres de longitud variable (p. ej. el IBM System/360 y sus sucesores).

Operaciones sin impactoEditar

El transporte normal de datos por parte de una sentencia de asignación es, en principio, independiente de la endianidad del procesador.

Middle-endianEditar

Son posibles otras numerosas ordenaciones, llamadas genéricamente middle-endian o mixed-endian. Un ejemplo fuera de la informática es el formato de fecha estándar americano de mes/día/año.

PDP-endianEdit

El PDP-11 es en principio un sistema little-endian de 16 bits. Las instrucciones para convertir entre valores de punto flotante y enteros en el procesador opcional de punto flotante del PDP-11/45, PDP-11/70, y en algunos procesadores posteriores, almacenaban valores «enteros largos de doble precisión» de 32 bits con las mitades de 16 bits intercambiadas del orden little-endian esperado. El compilador de UNIX C utilizaba el mismo formato para los enteros largos de 32 bits. Este ordenamiento se conoce como PDP-endian.

Una forma de interpretar este endianamiento es que almacena un entero de 32 bits como dos palabras de 16 bits en big-endian, pero las palabras mismas son little-endian (E.g. «jag cog sin» sería «gaj goc nis»):

Almacenamiento de un entero de 32 bits, 0x0A0B0C0D, en un PDP-11
direcciones crecientes →
0Bh 0Ah 0Dh 0Ch
0A0Bh 0C0Dh

Los valores de 16 bits aquí se refieren a sus valores numéricos, no a su disposición real.

Honeywell Serie 16Editar

Los ordenadores de 16 bits de la Serie 16 de Honeywell, incluyendo el Honeywell 316, son lo opuesto al PDP-11 en el almacenamiento de palabras de 32 bits en C. Almacena cada palabra de 16 bits en orden big-endian, pero las une en little-endian:

almacenamiento de un entero de 32 bits, 0x0A0B0C0D, en un Honeywell 316
direcciones crecientes →
0Ch 0Dh 0Ah 0Bh
0C0Dh 0A0Bh

Descriptores de segmento Intel IA-32Editar

Los descriptores de segmento de IA-32 y procesadores compatibles mantienen una dirección base de 32 bits del segmento almacenada en orden little-endian, pero en cuatro bytes no consecutivos, en las posiciones relativas 2, 3, 4 y 7 del inicio del descriptor.