assembly binary hex arm opcodes

assembly - Conversión de instrucciones ARM muy simples a binario/hex



assembly to hex (3)

Aquí se explica cómo se codifican las instrucciones de procesamiento de datos:

Usted tiene una tabla de códigos de condición en esa página suya. Los registros están codificados 0000 a 1111 .

Todos sus ejemplos caen dentro de la misma categoría. La imagen se extrajo de algún documento en mi disco duro, pero también logré encontrarla en google . Codificar esas instrucciones es un trabajo tedioso.

Entonces, mov r0, r0 debería ir así:

1110 00 0 0 1101 0000 0000 00000000

Puse a Rn en 0, porque no es realmente aplicable a MOV . En el caso de CMP , creo, S siempre es 1.

He estado tratando de usar esta página , así como varias otras guías para descubrir cómo expresar instrucciones ARM muy simples como binarias y hexadecimales. Parece que debería ser un proceso sencillo para mí, pero todavía no entiendo. Aquí hay algunos ejemplos.

NOP básico:

what goes here? what goes here? _↓_ _____↓____ | | | | mov r0, r0 ; ????00?1101????????????????????? |__||__| ↑ ↑ how do I express registers?

La misma pregunta básica para los demás.

Comparando dos registros:

cmp r1, r0

Agregar inmediato para registrar el valor:

add r0, #0x1a

Todos estos tutoriales en línea son excelentes para describir cómo usar instrucciones como estas, pero ninguno que he podido encontrar realmente explica cómo convertir una instrucción ARM en el código binario / hexadecimal / máquina en el que se ensambla.

Gracias de antemano por tu ayuda.


Debería obtener una copia de ARM ARM que describe la codificación de todas las instrucciones.

La mayoría de las instrucciones ARM usan los 4 bits superiores para un código condicional. Si no desea ejecutar la instrucción condicionalmente, simplemente use la pseudocondición AL (1110).

El primer registro (Rn) en la codificación no se usa para la instrucción MOV y debe establecerse en 0000 tal como lo define ARM ARM.

El segundo registro es el destino, aquí solo codifica el número de registro, por lo que en su caso también sería 0000 porque está utilizando r0 como destino, para r4 sería 0100.

El resto es el llamado operando de cambio que es muy flexible. Podría ser un registro simple como en su caso (r0), entonces es solo 0000 0000 0000 donde los últimos 4 bits nuevamente codifican el registro. También puede codificar diferentes tipos de turnos y gira con registro o valores inmediatos para el procesamiento de datos.

Pero también podría ser un lugar inmediato donde 8 bits están codificados en los bits inferiores y los primeros 4 bits definen un giro a la derecha en pasos de 2 bits. En este caso, bit25 también será 1, en todos los demás casos es 0.


Primero, necesita el ARM Architectural Reference Manual (ARM ARM) en infocenter.arm.com, manuales de referencia, obtenga el más antiguo (armv5 o lo que sea). el conjunto de instrucciones está bien definido allí.

Segundo, ¿por qué no juntas algunas instrucciones y ves qué pasa?

;@test.s cmp r1, r0 add r0, #0x1a

cualquiera que sea el ensamblador cruzado que tenga (vea http://github.com/dwelch67/raspberrypi en el directorio de compilación gcc para un script, solo ejecute binutils en ese script)

arm-none-linux-gnueabi-as test.s -o test.o arm-none-linux-gnueabi-objdump -D test.o

brazo-ninguno-linux-gnueabi vs brazo-ninguno-elf vs brazo-elf, etc. no importa para esto, todos hacen lo mismo

Disassembly of section .text: 00000000 <.text>: 0: e1510000 cmp r1, r0 4: e280001a add r0, r0, #26

Los cuatro primeros bits de una instrucción completa de brazo de 32 bits (no pulgar) son el código de condición, consulte la sección de campo de condición en ARM ARM. un 0xE significa siempre, siempre ejecute esta instrucción. 0b0000 es eq solo se ejecuta si se establece el indicador z, 0b0001 ne solo se ejecuta si z es claro, etc.

En ARM ARM, presione en el conjunto de instrucciones del brazo, luego en la lista alfabética de instrucciones del brazo, luego encuentre cmp. Comienza con el cond 00I10101 rn sbz shifter

De nuestra instrucción cmp anterior, vemos 1110 000101010001 ... entonces, yo soy un cero bits 15:12 son cero bits 27:26 son cero y 24:21 son 1010, así que esta es una instrucción cmp

los bits 19 a 16 anteriores son 0b001 que es rn así que rn = 1 (r1) para el operando de la palanca de cambios en ARM ARM le dice que mire los operandos del procesamiento de datos del Modo 1 de direccionamiento y tiene un enlace en el pdf a la página

sabemos que queremos que el segundo operando sea simplemente un registro, que se llama operandos de procesamiento de datos - registro, y un número de página, vaya a esa página en esa página 15:12 es rd 11: 4 son ceros y 3: 0 es rm . sabemos por la instrucción cmp que dice que 15:12 debe ser cero, me pregunto si le importa, un cmp no almacena un resultado en un registro para que no se use rd. rm es usado y en este caso queremos r0, entonces 0b0000 va en 3: 0 también note que muestra bits 27:25 como ceros, en la instrucción cmp 25 es I, ahora sabemos que queremos un cero allí entonces

entre la página cmp y este procesamiento de datos - página de registro tenemos la imagen completa

1110 condition 000 1010 opcode 1 S (store flags, that is a 1 for a cmp to be useful) 0001 rn 0000 rd/dont care/sbz 00000 000 0000 rm cmp rn,rm cmp r1,r0

el complemento es similar pero usa un inmediato, así que vaya a la instrucción add en la lista alfa de instrucciones. ahora sabemos por el cmp que 24:21 para esta clase de instrucción es el código de operación, podemos ir directamente a las cosas del operando de la palanca de cambios para continuar desde allí

esta vez estamos haciendo add rd, rn, # immediate

así que busca la página para #immediate

y la codificación es

1110 condition, always 001 (note the immediate bit is set) 0100 (opcode for add for this type of instruction) 0 (S not saving the flags, it would be adds r0,r0,#26 for that) 0000 (rn = r0) 0000 (rd = r0)

ahora viene la parte interesante, podemos codificar las 26 formas diferentes. los bits 7: 0 son los inmediatos y los bits 11: 8 permiten que se roten los inmediatos, 26 es 0x1A, simplemente podemos poner 0x1A en los 8 bits inferiores y establecer la rotación en 0, y eso es lo que hizo el ensamblador gnu. probablemente podría poner un 0x68 en los 8 bits inferiores y un 1 en el campo rotar_imm 1101000 rotado a la derecha 1 * 2 bits es 11010 = 0x1A = 26.