2012-03-27 18 views
5

Estoy tratando de leer ciertos valores de un registro en particular. El manual especifica que debo acceder primero al acceso LSB de 16 bits y luego al acceso MSB de 16 bits. ¿Acabo de leer en los 32 bits a la vez y luego enmascarar los 16 msb/lsb restantes, según sea necesario? O habría una manera de leer solo 16 bits puño.Lectura en 16 bits de un registro de 32 bits

Gracias, Neco

+0

Nos ayudaría si ha especificado qué procesador que está hablando. –

+0

¿En qué arquitectura estás trabajando? ¿Qué registro? –

+0

Este es un procesador ARM-le. – Falcata

Respuesta

8

Si el manual dice que el primer acceso de 16 bits LSB y luego el de 16 bits MSB, hacen como dice el manual.

Por ejemplo (little endian):

#define REG (*(volatile uint32_t *) 0x1234) 

uint16_t val_hi, val_lo; 

val_lo = *((volatile uint16_t *) &REG); 
val_hi = *((volatile uint16_t *) &REG + 1); 

Nota que los compiladores también a veces proporcionar identificadores HI y LO con el acceso LSB o MSB, como además de REG en el ejemplo:

#define REGL (*(volatile uint16_t *) 0x1234) 
#define REGH (*(volatile uint16_t *) 0x1236) 
+2

Sin embargo, esto no garantiza la "atomicidad" en el sentido de que el registro puede cambiar entre lectura lo y ho. –

+0

@OliCharlesworth el manual requiere que el acceso al registro de 32 bits no sea atómico: primero el LSB de 16 bits y luego el MSB de 16 bits. Este no es un requisito inusual. Lo que este código no garantiza es el acceso atómico de las dos lecturas de 16 bits. Los compiladores incorporados suelen ser bastante conservadores con respecto al acceso a objetos volátiles, pero si se puede utilizar cualquier código de ensamblaje de dudas. – ouah

+0

Al leer el 16 bit bajo, puede transferir los 16 bits altos a un registro. Tal vez el doctor lo dice o no ;-) –

2

No está claro qué idioma está utilizando para hacer esto. Asumiré que está utilizando ensamblado en línea en C.

Estoy muy familiarizado con NASM. Utilizando la sintaxis NASM para i386:

mov eax, 0x12345678 ; load whatever value 
mov bx, ax   ; put LSW in bx 
shr eax, 16   ; shift MSW to ax 
        ; now ax = MSW, bx = LSW 

supongo que el gas (C) código sería algo como esto:

movl $0x12345678, %eax # load whatever value 
movw %ax, %bx   # put LSW in bx 
shrl $16, %eax   # shift MSW to ax 
         # now ax = MSW, bx = LSW 
+0

Ya había una etiqueta ARM, no x86 –

Cuestiones relacionadas