operando numeros numero negativos lenguaje instrucciones incrementar ensamblador ejemplo div data como and assembly arm

assembly - numeros - Cómo utilizar la instrucción MOV en ARM con un número inmediato como segundo operando



numeros negativos en ensamblador (6)

Acabo de comenzar a estudiar lenguaje ensamblador ARM y no tengo claro cómo usar MOV para transferir un número inmediato a un registro.

Tanto en el manual de referencia de ARM como en mi libro de texto, se dice que el rango del número inmediato que sigue a la instrucción MOV es 0-255. Pero cuando pruebo en mi propia PC en ADS 1.2 IDE, la instrucción

MOV R2, #0xFFFFFFFF

se desempeña bien ¿No está el número 0xFFFFFFFF fuera de rango según la especificación?

Espero que alguien me pueda dar una mano.

Saludos.


Es algo difícil determinar si las constantes dadas están dentro del rango válido.

Al igual que Matthew ya se mencionó, el ensamblador le da la mano al reemplazar las instrucciones dadas con negativas similares, como mov / mvn, cmp / cmn, tst / tne, etc.


Es posible que esté viendo artefactos de signo-extensión del valor original. Si las herramientas que está utilizando para ver el desensamblaje manejan el 0..255 como un byte con signo, entonces cuando lo cargue en un tipo int más grande (o registro) llenará todos los bits superiores con el bit de signo del original. valor. O para decirlo de otra manera, si 0xFF es un byte firmado, su valor decimal es -1. Ponga eso en un registro de 32 bits y el hex se verá como 0xFFFFFFFF, y su valor decimal sigue siendo -1.

Intente utilizar un valor sin el bit alto establecido, como 0x7F. Dado que el bit de signo no está establecido, supongo que llenará los bits superiores con cero cuando se cargue en un campo o registro de tipo int más grande.

También es posible que el compilador / ensamblador trunca cualquier valor que proporcione. Lo consideraría un error de código fuente, pero los ensambladores son bestias divertidas. Si le asigna 0x7FF, ¿se compila en 0x7FF (no truncado y más grande que 0..255) o en 0xFFFFFFFF (truncado en 0..255, byte firmado)?


La instrucción MOV puede aceptar un valor imm16 o un valor Operator2 (debido a que la longitud de la instrucción es opuesta a la alineación de la memoria), que debe cumplir cualquiera de las siguientes reglas (copiadas del manual del conjunto de instrucciones CortexM, X e Y es cualquier valor hexadecimal):

  • Cualquier constante que se pueda producir al cambiar un valor de 8 bits dejado por cualquier número de bits dentro de una palabra de 32 bits.
  • Cualquier constante de la forma 0x00XY00XY.
  • Cualquier constante de la forma 0xXY00XY00.
  • Cualquier constante de la forma 0xXYXYXYXY.

Por eso se acepta 0xFFFFFFFF (cumple la 4ta regla).

Si desea ensamblar su propia constante de 32 bits, puede usar la instrucción MOVT , que se escribe en la mitad superior de un registro.


Recuerde que la ARM puede realizar un cierto conjunto de manipulaciones en el valor inmediato como parte de la palanca de cambio del cañón que se incorpora a los códigos de operación de la ARM.

Este pequeño artículo tiene una de las explicaciones más claras de algunos de los trucos que un ensamblador ARM puede usar para incluir un gran número inmediato en el pequeño espacio disponible de una instrucción ARM:

El artículo describe el truco que probablemente se usó en su ejemplo específico de generar un código de operación MVN para cargar el complemento a nivel de bits del valor inmediato.

Este tipo de manipulación no se puede hacer con todos los valores inmediatos, pero los ensambladores ARM son supuestamente muy inteligentes al respecto (y los compiladores de C ciertamente lo son). Si no se pueden realizar trucos de cambio / complemento, el valor generalmente se cargará desde una ubicación relativa a la PC o tal vez "acumulando" el valor de varias instrucciones.


Una posibilidad es que el ensamblador ARM descarte los bits significativos del número y use solo el FF más bajo.

La instrucción MOV es una grapa en muchos conjuntos de instrucciones de CPU, y generalmente el ensamblador resuelve el tamaño del registro de destino y el valor inmediato que se proporciona.

Por ejemplo, las siguientes instrucciones MOV del conjunto x86 son

MOV BL, 80h, ; 8bit MOV BX, ACACh ;16bit MOV EBX, 12123434h ; 32bit


Una sola instrucción ARM solo puede codificar una constante inmediata que puede representarse como un valor inmediato de 8 bits, desplazada por cualquier potencia par de dos.

Sin embargo, también hay una instrucción MVN , que es como MOV pero invierte todos los bits. Entonces, mientras MOV R2, #0xFFFFFFFF no puede codificarse como una instrucción MOV , puede codificarse como MVN R2, #0 . El ensamblador puede realizar esta conversión por usted.