2010-11-26 16 views

Respuesta

1

Piense en cómo convertiría endianness en un lenguaje de alto nivel como C, y luego cuando comprenda que puede traducirlo fácilmente al ensamblado de ARM, p.

uint16_t x = 0x0102; 
uint16_t y = (x << 8) | (x >> 8); // y = 0x0201 

Así que para el caso de 16 bits que tienen dos turnos (uno izquierdo y uno derecho) y un quirófano. Deberías poder hacer esto en 3 instrucciones.

17

¿Estás hablando de los modos endian de ARM, o leyendo algo escrito por otro procesador big endian, etc.?

Normalmente convierte a/desde big/little endian intercambia los bytes. Entonces 0xABCD es 0xCDAB cuando se ve como un número de 16 bits 0x12345678 es 0x78563412 cuando se ve como un número de 32 bits.

Los núcleos ARM armv5 y anteriores (ARM7, ARM9, etc.) tienen un modo endian conocido como BE-32, que significa invariante de palabra big endian. armv6 y más nuevos (mpcore, cortex-somehings) tienen BE-8, o invariante de byte big endian.

Así que si está utilizando un armv4 por ejemplo en modo big endian y modo endian nativo (pequeño) una lectura de palabra (ldr) del valor 0x12345678 sería 0x12345678 para una palabra de big endian leída en la misma dirección. Palabra invariante significa que la palabra lee da la misma respuesta. Una lectura de byte de la dirección cero en el modo little endian de la misma dirección sería 0x78 y la lectura de byte de big endian (ldrb) sería 0x12.

Así que tienes que ir más allá de simplemente decir si es grande o pequeño, pero qué instrucción se está usando.

Para un armv6 o posterior, si un ldr en alguna dirección da como resultado 0x12345678, entonces en modo big endian el ldr de la misma dirección daría como resultado 0x78563412. Tenga en cuenta que el modo endian grande o pequeño una búsqueda de instrucciones para esa dirección en un armv6 o más reciente obtendría 0x12345678. Un ldrb little endian mode armv6 same data misma dirección da como resultado 0x78, ldrb big endian armv6 o más nuevo también da como resultado 0x78. esto se debe a que el brazov6 y el último son invariantes en bytes, es decir, los accesos de byte al mismo resultado de dirección en el mismo valor, los accesos de media palabra, palabra y palabra doble se intercambian en estas arquitecturas cuando están en modo big endian. Debido a que las recuperaciones de instrucción no se intercambian, y dado que el bit endian está en el psr mientras se ejecuta un pequeño programa compilado endian, puede cambiar a big endian, hacer una serie de instrucciones y luego regresar al modo nativo y no afectará las lecturas de instrucción ni interrumpirá ocurrir.

 
setend be 
ldr r0,[r1] 
add r0,r0,#7 
str r0,[r1] 
setend le 

Algunas páginas web se menciona este intercambio de bytes de cuatro instrucciones, en caso de que desee ejecutar little endian nativo (una muy buena idea) y realizar el intercambio con ensamblador (no siempre es una buena idea, depende de lo que estás haciendo).

 
    eor r3,r1,r1, ror #16 
    bic r3,r3,#0x00FF0000 
    mov r0,r1,ror #8 
    eor r0,r0,r3, lsr #8 

siendo R1 la entrada de lo que parece y r0 es la salida

Para ARMv6 o más reciente de lo anterior se puede realizar con

 
    rev r0,r1 
2

A ver si hay un comando inversión de bytes es decir, (__REV(), __REV16(), __REVSH()). Estas son instrucciones de ensamblaje en línea que utilizan el hardware a diferencia del trabajo más lento pero portátil sobre las respuestas anteriores. (link1, link2)