2012-08-02 9 views
21

Ho cercato di utilizzare this page e varie altre guide per capire come esprimere istruzioni ARM molto semplici come binario e hex. Sembra che dovrebbe essere un processo semplice per me, ma ancora non capisco. Ecco alcuni esempi.Conversione di istruzioni ARM molto semplici in binario/esadecimale

base NOP:

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

Stessa domanda di base per gli altri.

a confronto due registri:

cmp r1, r0 

l'aggiunta immediata di registrare il valore:

add r0, #0x1a 

Tutti questi tutorial online sono eccellenti a descrivere come utilizzare le istruzioni come queste, ma nessuno ho potuto per trovare effettivamente passare attraverso come convertire un'istruzione ARM nel codice binario/hex/macchina in cui viene assemblato.

Grazie in anticipo per il vostro aiuto.

+2

ottima domanda; sfortunatamente il collegamento è morto. per le persone che passano, ecco un rapido [collegamento all'archivio web] (https://web.archive.org/web/20150426195854/http://www.nyx.net/~troddis/ARM.html) – Asu

risposta

29

Ecco come le istruzioni di elaborazione dei dati sono codificati:

ARM data processing instructions

Hai condizioni tabella codici in quella pagina del tuo. I registri sono codificati 0000 tramite 1111.

Tutti i tuoi esempi rientrano nella stessa categoria. L'immagine viene estratta da un documento sul mio HDD, ma sono anche riuscita a trovarla per google. Codificare queste istruzioni è un lavoro noioso.

Quindi, mov r0, r0 dovrebbe andare in questo modo:

1110 00 0 0 1101 0000 0000 00000000 

ho messo Rn a 0, perché non è in realtà applicabile a MOV. Nel caso di CMP, credo che S sia sempre 1.

5

Si dovrebbe ottenere una copia del BRACCIO ARM che descrive la codifica per tutte le istruzioni.

La maggior parte delle istruzioni ARM utilizza i 4 bit superiori per un codice condizionale. Se non si desidera eseguire l'istruzione in modo condizionale, utilizzare solo la pseudo-condizione AL (1110).

Il primo registro (Rn) nella codifica non viene utilizzato per l'istruzione MOV e deve essere impostato su 0000 come definito dal BRACCIO ARM.

Il secondo registro è la destinazione, qui basta codificare il numero di registro, quindi nel tuo caso sarebbe anche 0000 perché si sta utilizzando R0 come destinale, per r4 sarebbe 0100.

Il resto è il cosiddetto shifter operando che è molto flessibile. Potrebbe essere un semplice registro come nel tuo caso (r0), quindi è solo 0000 0000 0000 dove gli ultimi 4 bit codificano nuovamente il registro. Può anche codificare diversi tipi di turni e ruota con i valori registrati o immediati per l'elaborazione dei dati.

Ma potrebbe anche essere un immediato dove 8 bit sono codificati nei bit inferiori e i primi 4 bit definiscono un diritto di rotazione in incrementi di 2 bit. In questo caso, bit25 sarà anche 1, in tutti gli altri casi sarà 0.

+5

ARM ARM è un divertente acronimo, ma è terribile fare una ricerca su Google per questo. L'espansione è "Manuale di riferimento Architettura ARM" e sono disponibili [qui] (http://infocenter.arm.com/help/topic/com.arm.doc.subset.architecture.reference/index.html#reference) dopo una registrazione gratuita. –

+0

@Kevin No, l'espansione è in realtà ** Avanzata (Riduzione del set di istruzioni dell'insegnamento) Manuale di riferimento dell'architettura della macchina **. Ma questa non è una buona ricerca su google :) –

9

Prima di tutto, è necessario il Manuale di riferimento architettonico ARM (ARM ARM) su infocenter.arm.com, manuali di riferimento, ottenere il più vecchio (armv5 o qualsiasi altra cosa). il set di istruzioni è ben definito lì.

In secondo luogo, perché non basta assemblare alcune istruzioni e vedere cosa succede?

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

qualunque assembler Croce hai (vedi http://github.com/dwelch67/raspberrypi nella directory di compilazione gcc per uno script, basta eseguire fino thru binutils in quello script)

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

braccio-nessuno-linux-gnueabi vs Supporto, none-elf vs braccio-elf, ecc dont matter per questo, tutti fanno la stessa

Disassembly of section .text: 

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

i primi quattro bit di un'istruzione completa a 32 bit braccio (non il pollice) sono il codice di condizione, vedere il campo condizioni sezione nel BRACCIO ARM. un 0xE significa sempre, esegui sempre questa istruzione. 0b0000 è solo eq eseguito se il flag z è impostato, 0b0001 ne viene eseguito solo se z è chiaro, ecc.

Nel BRACCIO BRACCIO inserire nel set di istruzioni del braccio, quindi nell'elenco alfabetico delle istruzioni del braccio, quindi trovare cmp Si avvia con cond 00I10101 rn sbz shifter

Dalla nostra istruzione cmp sopra vediamo 1110 000101010001 ... quindi I è un bit zero 15:12 sono zero bit 27:26 sono zero e 24:21 sono 1010 quindi questo è un cmp istruzione

bit da 19 a 16 sopra sono 0b001 che è rn così rn = 1 (r1) per l'operatore di shifter nel BRACCIO ARM che ti dice di guardare gli operandi Modalità di indirizzamento 1 Data Processing e ha un link nel pdf a la pagina

sappiamo che vogliamo che il secondo operando sia semplicemente un registro, che si chiama operandi di elaborazione dati - registra e un numero di pagina, vai a quella pagina in quella pagina 15:12 è rd 11: 4 sono zeri e 3 : 0 è rm. sappiamo dall'istruzione cmp che dice che 15:12 dovrebbe essere zero, mi chiedo se gliene importa, un cmp non memorizza un risultato in un registro quindi non viene usato. rm è usato e in questo caso vogliamo r0, quindi 0b0000 va in 3: 0 nota anche che mostra bit 27:25 come zero, nell'istruzione cmp 25 è I, ora sappiamo che vogliamo uno zero lì così

tra la pagina cmp e questo l'elaborazione dei dati - registrazione pagina abbiamo il quadro completo

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 

del componente aggiuntivo è simile ma utilizza un immediato, in modo da andare per l'istruzione add nella lista alpha di istruzioni. ora sappiamo dal cmp che 24:21 per questa classe di istruzioni è l'opcode, possiamo praticamente andare direttamente all'offand shifter per continuare da lì

questa volta stiamo facendo add rd, rn, # immediate

in modo da cercare la pagina per la #immediate

e la codifica è

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) 

arriva ora la parte interessante, siamo in grado di codificare i 26 modi diversi.i bit 7: 0 sono l'immediato ei bit 11: 8 permettono che l'immediato sia ruotato, 26 è 0x1A, potremmo semplicemente mettere 0x1A negli 8 bit inferiori e impostare il valore su 0, e questo è ciò che ha fatto l'assemblatore di gnu. potrebbe probabilmente mettere un 0x68 negli 8 bit più bassi e 1 nel campo rotate_imm 1101000 ruotato a destra 1 * 2 bit è 11010 = 0x1A = 26.

Problemi correlati