Borrar los 16 bits superiores en 1 instrucción ARM
-
08-07-2019 - |
Pregunta
En el ensamblaje ARM, los elementos inmediatos se codifican mediante un valor girado de 8 bits, lo que significa que solo podemos codificar
(0-256)^2n.
Ahora mi problema es que quiero borrar los 16 bits superiores de r0 y reemplazarlo con la media palabra almacenada r1. Pero debido al rango limitado de los inmediatos que tengo que hacer: -
bic r0, r0, #0xff000000
bic r0, r0, #0x00ff0000
add r0, r0, r1, LSL #16
¿Es posible reemplazar las 2 instrucciones bic con una sola instrucción? 0xffff0000 no se puede codificar. ¿Quizás debería estar usando otra operación lógica para borrar los 16 bits superiores?
Gracias
EDITAR: Lo siento, olvidé decir que los 16 bits superiores de r1 están vacíos y estoy usando un ARM7TDMI
Solución
¿Qué tal:
orr r0,r1,r0,lsl #16
mov r0,r0,ror #16
(Esto supone que la media palabra superior de r1 está vacía, como lo hizo su código de referencia). Dependiendo de las circunstancias, es posible que pueda omitir el movimiento final aquí fusionándolo con algún código posterior.
Otros consejos
Si tiene un núcleo ARM lo suficientemente nuevo, la pregunta es simple:
movt r0, #0
orr r0, r0, r1,lsl#16
Ver http://www.keil.com/support/man /docs/armasm/armasm_cjagdjbf.htm
Sin embargo, si tiene ARMv6 +, puede hacer todo el ejemplo citado de una vez:
pkhbt r0, r0, r1,lsl#16
Ver http://www.keil.com/support/man /docs/armasm/armasm_cihjedjg.htm
" reemplácelo con la media palabra almacenada r1 " ¿Significa esto que puede asumir que los 16 bits superiores de r1 son cero? Si es así,
add r0, r1, r0 lsl #16
mov r0, r0 ror #16
Piense en el mov como un marcador de posición, ya que con suerte puede mover el ror a lo que sea que tome r0 como entrada siguiente y realmente haga un trabajo útil en el mismo ciclo.
En ARMv6 (por ejemplo, MPCore), puede decir
uxth r1, r1
orr r0, r1, r0, asl #16
Si puede borrar todo el asunto, puede xor
hacerlo consigo mismo.
Si necesita retener la mitad inferior, ¿podría desplazar el registro a la izquierda 8 bits y retroceder? Sin embargo, esa puede ser la misma cantidad de instrucciones.
Para el código C
(a<<16)|((short)b)
gcc genera
mov r1, r1, asl #16
mov r1, r1, asr #16
orr r0, r1, r0, asl #16
que no utiliza ningún elemento inmediato; sin embargo, siguen siendo dos instrucciones.
Puede usar la instrucción BFC. Bit Field Clear. Esta instrucción borra n bits de m bit