Il processore PD32 Set Istruzioni Set Istruzioni • Sono organizzate in 8 classi – – – – – – – – Movimento dati Aritmetiche (somma e sottrazione) Tipo Logico Rotazione e shift Operazioni sui bit di stato controllo del programma controllo della macchina ingresso/uscita Formato Istruzione int i,j ……… i=i+j Programma compilatore Codice mnemonico Tipo di dato L (longword) W (word) B (byte) ADDW R2 , R1 Linguaggio Assembly Destinazione Sorgente (R2+R1 => R1) Programma assemblatore (Assembler) 31 29 28 24 23 16 15 14 13 12 11 9 8 6 5 3 2 0 Classe Tipo K pos. I/O L-W-B Modo Sg Sorg. Modo Ds Dest Linguaggio Macchina (PD 32 ogni istruzione è rappresentata con 32 bit) Formato istruzioni • Ogni istruzione (che non utilizza l’indirizzamento immediato) è lunga 32 bit (4 byte) ed è composta da 9 campi • Alcune istruzioni ignorano alcuni campi CLASSE TIPO Codice Operativo Specifica il tipo d’istruzione DATO K I/O S MODO S SORG MODO D Operandi Specifica i dati su cui operare DEST Campo Classe Tipo dato k I/O s modo s sorg n°.Bits 3 5 8 2 2 3 3 modo d dest 3 3 Commento Indica la classe di istruzione (movimento dati, rotazione e shift, aritmetiche…) Al''interno della classe viene indicato quale tra le operazioni disponibili deve essere eseguita Campo contenente un dato utilizzato nelle istruzioni di rotazione e shift e nelle istruzioni di I/O Campo utilizzato nelle istruzioni di I/O, codifica il modo con cui l'indirizzo del device può essere recuperato Indica il formato del dato che deve essere trattato dall'operazione. Indica il modo di indirizzamento dell'operando sorgente. In caso di indirizzamento diretto a registro, indiretto a registro, con predecremento e con postincremento indica uno degli otto registri di uso generale R0-R7 Indica il modo di indirizzamento dell'operando destinazione. In caso di indirizzamento diretto a registro, indiretto a registro, con predecremento e con postincremento indica uno degli otto registri di uso generale R0-R7 Ciclo Istruzione Ciclo Istruzione - Fetch Il registro “Program Counter” contiene l’indirizzo da cui prelevare l’istruzione da eseguire. Bus memoria Il SCO lo incrementa di 4 ad ogni fetch Fetch 1) 2) 3) MEMORIA DI LAVORO PC PC -> MAR (MAR) -> MDR MDR -> IR, PC + 4 -> PC Istruzione 1 Istruzione 2 IR = Instruction Register Istruzione 3 Segnali di comando per la SCA e per lo SCO Alcune istruzioni Assembler • MOVB R1,R2 • MOVW R1,(R2) • MOVL (R1),R2 • SUBs R1,R2 • ADDs #d,R2 copia il contenuto del primo byte di R1 in R2 copia il contenuto dei primi 2 byte di R1 nei due byte di memoria il cui indirizzo iniziale è memorizzato in R2 copia in R2 il contenuto dei 4 bytes di memoria il cui indirizzo è specificato in R1 sottrai il contenuto del primo, dei primi 2 o i 4 bytes del registro R1 con il corrispondente in R2, il risultato memorizzalo in R2 addiziona al contenuto del registro R2 la quantità d di dimensione s. Esempi di traduzione istruzioni assembler in linguaggio macchina MOVB R4,R3 Codice mnemonico CLASSE 001 31 29 28 formato dato campo s diretto con registro TIPO 0000 24 23 operandi e modo indiriz. operandi byte ….. … 4 00 000 16 15 14 13 12 11 3 100 9 8 Modo sorg 000 6 5 011 32 Modo dest 0 Esempi di traduzione istruzioni assembler in linguaggio macchina (cont.) ADD B Codice mnemonico CLASSE 010 31 29 28 #20,R3 formato dato campo s TIPO 0000 24 23 operandi e modo indiriz. operandi byte ….. … Indirizzamento Immediato Indirizzamento (vedi byte diretto con registro successivo) 00 16 15 14 13 12 11 001 …… 9 8 000 6 5 3 011 32 0 00010100 7 0 Ciclo Istruzione – Execute Nel PD32 la fase di esecuzione di un ciclo istruzione consiste in un numero variabile di cicli macchina dipendente dal numero di accessi in memoria necessari (oltre al fetch) Entrambi gli operandi sono contenuti in registri interni del PD32 (indirizzamento a registro) Uno degli operandi (0x20) è definito nell’istruzione L’assembler lo memorizza nella locazione di memoria esterna immediatamente successiva a quella contenente l’istruzione (indirizzamento immediato) ADDW R1, R2 ADDW #20h, R2 1) 2) 3) 1) 2) 3) 4) R1 -> Temp1 R2 -> Temp2 ALU-OUT (Temp1+Temp2) -> R2 (nessun accesso a memoria esterna) PC -> MAR (MAR) -> MDR , R2 -> Temp1 MDR -> Temp2, PC + 2 -> PC ALU-OUT (Temp1+Temp2) -> R2 (1 accesso a memoria esterna) Un esempio di programma assembler •Saldo (S) nelle 2 celle puntate da R5 (dato di una parola) •Tre versamenti (V1,V2,V3) immagazzinati nelle tre coppie di celle consecutive puntate da R4 •Due prelievi (P1,P2) immagazzinati nelle due coppie di celle puntate da R3 S=S+V1+V2+V3-P1-P2 Un esempio di programma assembler PC PC+4 PC+8 PC+13 PC+17 PC+22 PC+26 PC+30 PC+35 PC+39 1 2 3 4 5 6 7 8 9 10 MOVW (R5),R0 ADDW (R4),R0 ADDB #2,R4 ADDW (R4),R0 ADDB #2,R4 ADDW (R4),R0 SUBW (R3),R0 ADDB #2,R3 SUBW (R3),R0 MOVW R0,(R5) ; R0:=S ;R0:=R0+V1 ;punta al prossimo versamento ;R0:=R0+V2 ;punta al prossimo versamento ;R0:=R0+V3 ;R0:=R0-P1 ;punta al prossimo prelievo ;R0:=R0-P2 ;S:=R0 Altre istruzioni JMP SALTO INCONDIZIONATO JZ SALTO CONDIZIONATO HALT FINE PROGRAMMA MOVB #dato,R1 ESTENSIONE SEGNO #dato sui rimanenti bits di R1 MOVB #3,R4 R4 = 00h 00h 00h 00000100 MOVB #-1,R5 R5 = FFh FFh FFh 11111111 Un programma per l’aggiornamento del saldo di un conto bancario Ipotesi •Tutti i dati sono a 16 bit (word) •Il saldo iniziale è memorizzato nella coppia di celle di indirizzo 00001B00 •I movimenti (versamenti e prelievi) sono memorizzati in posizioni consecutive di memoria, a partire da quella di indirizzo 00001F00 •I movimenti non hanno un ordine particolare: i versamenti sono positivi e i prelievi negativi •Non è noto il numero dei movimenti effettuati •L’ultimo movimento è seguito da una posizione di memoria contente il numero 0 Una prima soluzione START R5 punta al Saldo R5:=1B00 R4 punta al I vers. R4:=1F00 R0 memorizza il Saldo R0:=(R5) R1 mem. il versamento R1:=(R4) R1:=R1+0 R1=0 ? si JZ no R0:=R1+R0 Somma al saldo il vers. R4:=2+R4 R4 punta al vers. succ. (R5):=R0 ora in memoria c’è il saldo aggiornato HALT Il codice ASSEMBLER INDIRIZZO 0400 0408 0410 0414 0418 041D CODICE MOVL #1B00h,R5 MOVL #1F00h,R4 MOVW (R5),R0 MOVW (R4),R1 ADDB #0,R1 JZ 0436h 0425 0429 042E 0436 043A ADDW R1,R0 ADDB #2,R4 JMP 0414h MOVW R0,(R5) HALT COMMENTO ;inizializza il registro R5 ;inizializza il registro R4 ;carica in R0 il saldo attuale ;carica in R1 il movimento puntato da R4 ;aggiorna il registro SR ;salta a memorizza il nuovo saldo se non vi sono altri movimenti ;aggiungi al saldo il movimento in R1 ;incrementa il puntatore ai movimenti ;procedi con un nuovo movimento ;memorizza il nuovo saldo Una soluzione “equivalente” START R5 punta al Saldo R5:=1B00 R4 punta al I vers. R4:=1F00 R0 memorizza il Saldo R0:=(R5) Somma al saldo il vers. R0:=R0+(R4) scrivi il saldo in memoria (R5):=R0 R4 punta al vers. succ. R4:=2+R4 Somma al saldo il vers. R0:=(R4)+R0 confronta il saldo attuale con il saldo in mem. R1:=R0-(R5) JNZ no HALT si Assemblatore • Traduce il codice scritto in assembly in codice macchina • Ad ogni istruzione macchina è associato un codice menmonico • E’ possibile usare riferimenti simbolici • E’ possibile inserire delle direttive che indicano all’assemblatore come procedere nella traduzione – Ad esempio, ORG specifica dove sarà caricato il programma una volta tradotto. Questo serve a tradurre i riferimenti simbolici assoluti nel codice sorgente. – Ad esempio, CODE .. END indicano l’inizio e la fine della sezione codice. Esempio MOVB #0,R1 • Significato: “Poni a 0 il byte meno signif. di R1” • Codice assembly MOVB #0, R1 Destinazione Tipo (byte) Sorgente ORG 400H CODE movb #0,R1 HALT END 400 istruzione operando 01H 02H 00H 20H 00H Contenuto memoria 3 2 1 0 20 00 02 01 400 404 ? ? ? 00 ?? ?? ?? ? 408 Prima istruzione Operando Seconda istruzione 0x20 00 02 01 400: 0010 0000 0000 0000 0000 0010 0000 0001 404: 0000 …. Esempio MOVB #0,R1 Indirizzo Iniziale Altro esempio Il codice sarà caricato in posizione 0x600 ORG 600H CODE movw r2, r1 movb #-2, r0 HALT END 2000101081 2000000200 FE 1111 1110 Rappresentazione compl. a 2 Modi di indirizzamento • Stabiliscono la posizione degli operandi – Possono trovarsi nei registri (R0..R7) – In memoria di lavoro (la posizione è stabilita dall’indirizzo di memoria in cui è memorizzato il valore) • Chiamiamo la posizione di un operando Effective Address (EA) – EA può essere pertanto un registro o una locazione di memoria • Il valore di EA deve essere noto al tempo di esecuzione del programma (run-time), può però non essere noto al momento della sua scrittura (compile-time). Ciò consente di ottenere una grande flessibilità Modi di indirizzamento • Modi diretti – Diretto con registro – Immediato – Assoluto • Modi indiretti – – – – – Indiretto con registro Indiretto con spiazzamento Relativo Indiretto con predecremento Indiretto con postdecremento Indirizzamento a registro • EA=Ri • Esempio: MOVL R1,R5 (significato: R1->R5) Indirizzamento immediato • Il dato si trova in memoria immediatamente dopo l’istruzione • Esempio: MOVL #0,R5 (significato: poni 0 in R5) Indirizzamento assoluto • Esempio: MOVB R1,1280H (sposta il byte basso di R1 nella cella di memoria di indirizzo 1280H. • Tale valore, 1280H, è memorizzato dopo l’istruzione ed è riferito da PC dopo che è stato incrementato) • Effective address = 1280H Indirizzamento indiretto con registro • Il registro contiene l’indirizzo dell’operando (corrisponde alla nozione di puntatore nei linguaggi di programmazione) • Esempio: MOVL (R5),R1 (significato: sposta in R1 in contenuto della locazione il cui indirizzo è contenuto in R5) Indirizzamento indiretto con registro e con predecremento • Il registro, opportunamente decrementato, contiene l’indirizzo dell’operando • Esempio: MOVL R1,-(R7) (sposta nella locazione il cui indirizzo è pari al contenuto in R7 meno 4 ciò che è memorizzato in R1) Indirizzamento indiretto con registro e con postincremento • Il registro contiene l’indirizzo dell’operando, una volta acceduto la memoria il registro viene opportunamente incrementato • Esempio: MOVL (R7)+,R1 (sposta in R1 quanto memorizzato nella locazione il cui indirizzo è pari al contenuto in R7, dopodiché incrementare di 4 ciò che è memorizzato in R7) Indirizzamento con spiazzamento • L’indirizzo effettivo dell’operando è la somma di un valore base (mem. in un reg.) con il valore di spiazzamento • Esempio: MOVB D(R0),R1 (significato: sposta in R1 il contenuto della cella con indirizzo D+R0) Indirizzamento relativo • Usato nei salti, per consentire riferimenti relativi e caricare il PC con valori differenti da quelli ottenuti con semplici incrementi. • Esempio: JMP LABEL(PC) (metti nel PC quanto ottenuto dalla somma del contenuto della locazione il cui indirizzo è dato dall’etichetta LABEL con il valore corrente del PC) Indirizzamento Riepilogo org 400h code movl #20, r1 addl r1,r1 ; r1=20, ind. immediato ; r1=40, ind. a registro movb #0FFh, 800h ;mem[0x800]=0xFF, ind. assoluto movl #800h,r2 ;r2=0x800 movb #0EEh, (r2);mem[r2]=0xEE, ind. con registro movb #0FFh, -(r2) ;r2=0x800-0x1=0x7FF, mem[0x7FF]=0xFF ;ind. con predecremento movb #0AAh, (r2)+ ;mem[0x7FF]=0xAA, r2=0x800 ;ind. con postincremento ;mem[0x808]=0xFF, r2=0x800 ;ind. con spiazzamento movb #0FFh, 8(r2) end Tipi di istruzioni • Set Istruzioni • Sono organizzate in 8 classi – – – – – – – – Movimento dati Aritmetiche (somma e sottrazione) Tipo Logico Rotazione e shift Operazioni sui bit di stato controllo del programma controllo della macchina ingresso/uscita Istruzioni Movimento dati Istruzioni MOVs • Sono usate per copiare dati da – Registro-registro • movl r1,r2 – Registro-memoria • movl r1,(r2) – Memoria-registro • movl (r1),r2 – Memoria-memoria • movl (r1),(r2) Istruzioni aritmetiche Istruzione CMP CMPL R1,R2 Confronto fra registri Aritmetica non segnata • CMPB R1,R2 (ipotesi: R1,R2>=0) – Equivale ad eseguire R2-R1 senza aggiornare R2 CMPB R1,R2 Z=0 C=1 C=0 R2-R1<0 (R1>R2) C=1 R1>R2 Z=1 R1=R2 C=0 and Z=0 R1<R2 Z=1 R2-R1>=0 R1=R2 R1<>R2 (R1<=R2) Z=0 R1<R2 not C=0 R1<=R2 Z=0 R1<>R2 Z=1 or C=1 R1>=R2 Confronto fra registri Aritmetica segnata R1,R2 rappresentati in complemento a 2 • CMPB R1,R2 Equivale ad eseguire R2-R1 senza aggiornare R2 N=V R1>=R2 N<>V R1<=R2 CMPB R1,R2 Z=1 R2-R1=0 (R1=R2) N=V N<>V Z=0 R2-R1>=0 R1<=R2 R1<>R2 (R2>=R1) Z=0 Z=0 R2>R1 R1<R2 Z=1 R1=R2 Z=0 R1<>R2 Esempio … movl #100,r1 movl #99,r2 ; a questo punto del codice, r1 ed r2 ; contengono valori positivi cmpl r1,r2 ;c=1, n=1, z=0 movl #100,r2 cmpl r1,r2 ;c=0, n=0, z=1 movl #101,r2 cmpl r1,r2 … ;c=0, n=0, z=0 Istruzioni controllo di programma Istruzioni di controllo esecuzione • Istruzioni di salto incondizionato – JMP, JSR, RET, RETI • Istruzioni di salto condizionato – Jc Label, (salta a Label se c=1), JNc (salta a Label se c<>1) • c qualunque flag: C (Carry), N (Negative) , Z (Zero) V (oVerflow), P (Parity), I (Interrupt Enable) – I flag sono modificati dopo un’istruzione. Si usa solitamente l’istruzione “compare”, CMPs , che equivale ad eseguire una sottrazione ma senza modificare il registro di destinazione • Ex: CMPL R1,R2 (equivale ad eseguire R2-R1, ma senza modificare il registro destinazione R2) Esempio R1>R2 si: R1>R2 R1>R2 no: R1<=R2 no: R1<=R2 I1 L2: Istruzione I1 Istruzione I2 I1 I2 I2 cmpl R1 R2 JC L2 si: R1>R2 cmpl R1 R2 JNC L2 ;se R1>R2 ;salta ad I2 L2: Istruzione I1 Istruzione I2 ;se R1<=R2 ;salta ad I2 Esempio if R1>R2 then <I1> else <I2> <I3> no: R1<=R2 R1>R2 I2 si: R1>R2 cmpl R1 R2 JNC L2 ;R2-R1 ;se R2<=R1 ;esegui I2 L1: I1 jmp L3 ;ramo then L2: I2 ;ramo else L3: I3 ;continua I1 I3 Istruzioni controllo macchina: CLASSE 0 Istruzioni di tipo logico: Classe 3 Istruzioni di rotazione e shift Classe 4 Istruzioni di rotazione e shift Istruzioni (sottoinsieme) di Ingresso Uscita Classe 7 TIPO 0 CODICE Ins OPERANDI dev, D0 CNZV P I ------ COMMENTO Il dato contenuto nel buffer del device dev è trasferito nella destinazione D0. dev ->d0 1 OUTs S,dev ------ Il dato sorgente S viene trasferito nel buffer del device dev. S->dev 2 START dev ------ 3 CLEAR dev ------ Viene azzerato il flipflop STATUS del dev e viene avviata l'operazione. Viene azzerato il flipflop STATUS del dev senza avviare l'operazione. Esempio programma assembly • Problema – Trovare il massimo in un insieme di 15 interi positivi • Ipotesi – Assumiamo che i valori siano compresi nell’intervallo 0..255 Programma 15 interi fra 0 e 255 Valore massimo Esempio programma assembly (cont) • Dobbiamo stabilire – Che tipo e quanti variabili usare • Dove memorizzare i valori in ingresso – -> Vettore V di 15 elementi • Quali variabili ausiliare sono eventualmente necessarie • Dove memorizzare il valore di uscita – registro – Algoritmo che risolve il problema • Per esempio, ipotizzare come valore massimo 0 e confrontarlo con tutti i 15 valori, aggiornandolo ogni volta che se ne trova uno maggiore Algoritmo e dati Inizio V 0 1 i i=0 max=0 i<15 max 14 no si V[i]>max max=V[i] i=i+1 no Fine Uso dei registri.. Memoria (mem) R3 R1 (i) 0x1300 0 1 Inizio R1=0,R2=0 R3=0X1300 R1<15 no si 14 mem[R3]>R2 R2(max) R2=mem[R3] R1=R1+1 R3=R3+1 no Fine Soluzione prima versione Memoria (mem) R3 R1 (i) 0x1300 0 1 Inizio XORL R1,R1 XORL R2,R2 MOVL #1300h,R3 R1=0,R2=0 R3=0X1300 R1>=15 si Fine loop: CMPB #15,R1 JNC fine; //SALTA QUANDO R1=15 no 14 mem[R3]>R2 si R2=mem[R3] R2(max) no skip: R1=R1+1 R3=R3+1 fine: CMPB (R3),R2 JNC skip MVLB (R3),R2 ADDL #1,R3 ADDB #1,R1 jmp loop halt Osservazioni • Parametri nel codice – L’indirizzo dell’inizio del vettore – Numero di elementi • Uso di due registri – Contare il numero di iterazioni – Individuare l’elemento nel vettore in memoria Direttiva di definizione costanti label EQU n costante1 EQU 4 ;il simbolo costante1=4 costante2 EQU -0101b ;il simbolo costante2=-5 costante EQU 0fffh ;il simbolo costante=4095 Il simbolo label è un numero puro che può essere utilizzato come un dato o un indirizzo. …. MOVB costante, R0 ; il byte all’indirizzo 4095 ; è spostato in R0 MOVB #costante,R1 ; R1=4095 Soluzione seconda versione org 1400h code XORL R1,R1 XORL R2,R2 MOVL #1300h,R3 loop: skip: fine: end CMPB #15,R1 JNC fine; CMPB (R3),R2 JNC skip MVLB (R3),R2 ADDL #1,R3 ADDB #1,R1 jmp loop halt org 1400h base equ 1300h numel equ 15 code loop: skip: fine: end XORL R1,R1 XORL R2,R2 CMPL #numel,R1 JNC fine; CMPB base(R1),R2 JNC skip MVLB base(R1),R2 ADDB #1,R1 jmp loop halt Soluzione terza versione Un accesso in meno alla memoria org 1400h base equ 1300h numel equ 15 code loop: skip: fine: end XORL R1,R1 XORL R2,R2 CMPL #numel,R1 JNC fine; CMPB base(R1),R2 JNC skip MVLB Base(R1),R2 ADDB #1,R1 jmp loop halt org 1400h base equ 1300h numel equ 15 code loop: skip: fine: end XORL R1,R1 XORL R2,R2 MOVL #numel,R3 CMPL R3,R1 JNC fine; CMPB base(R1),R2 JNC skip MVLB base(R1),R2 ADDB #1,R1 jmp loop halt Scrittura ed assemblaggio Confronto modi indirizzamento • Problema dato un array di 10 longword allocato a partire dalla locazione 2500h costruirne l‘inverso a partire dalla locazione 3000h Soluzione 1: indirizzamento indiretto con registro Soluzione 2: indirizzamento con post-incremento e predecremento Soluzione 3: indirizzamento con spiazzamento Il problema Array1 2500h 2504h 2508h . . . 2536h V1 V2 V3 … Vi … V8 V9 Array2 3000h 3004h . . . . 3036h V9 V8 … Vi … V3 V2 V1 Soluzione 1: indirizzamento indiretto con registro ORG 400H ;****************Dichiarazione Costanti******************** DIM EQU 10 ARRAY1 EQU 2500H ARRAY2 EQU 3000H ;******************Corpo del Programma********************* CODE MOVL #ARRAY1,R1 ; carica in R1 l'indirizzo base dell'array originale MOVL #ARRAY2,R2 ; carica in R2 l'indirizzo base dell'array invertito MOVL #DIM,R0 ; carica in R0 la dimensione (numero di elementi) dell'array da invertire SUBL #1,R0 ; decrementa il contatore R0, R0=#DIM-1 ASLL #2,R0 ; R0=R0*4, calcola l'offset da sommare all'ind.base ; del'array per ottenere l'ind. dell'ultimo elemento ADDL R0,R2 ; pone in R2 l'ind. dell'ultimo elemento dell'array MOVL #DIM,R0 ; ricarica la dimensione dell'array in R0 per usarlo come contatore REPEAT: MOVL (R1),(R2) ; copia memoria memoria di ARRAY1[i] in ARRAY2[#DIM-1-i] ; i=[0...#DIM-1] ADDL #4,R1 SUBL #4,R2 SUBL #1,R0 JNZ REPEAT HALT END ; R1 ora punta all'elemento succ. di ARRAY1 ; R2 ora punta all'elemento prec. di ARRAY2 ; decrementa il contatore R0 di 1 ; salta a REPEAT se R0 diverso da 0 ; fine programma Soluzione 2: indirizzamento con post-incremento e predecremento ORG 400H ;****************Dichiarazione Costanti******************** DIM EQU ? ARRAY1 EQU 2500H ARRAY2 EQU 3000H ;******************Corpo del Programma********************* CODE MOVL #ARRAY1,R1 ; carica in R1 l'indirizzo base dell'array originale MOVL #ARRAY2,R2 ; carica in R2 l'indirizzo base dell'array invertito MOVL #DIM,R0 ; carica in R0 la dimensione (numero di elementi) dell'array da invertire ASLL #2,R0 ; calcola l'offset da sommare ad #ARRAY2 per puntare locazione ; corrispondente a ARRAY2[#DIM] NB: se ARRAY2 è di dimensione #DIM ; allora ARRAY2[0..#DIM-1] ADDL R0,R2 ; R2 ora punta a ARRAY[#DIM] MOVL #DIM,R0 ; Inizializza R0 a #DIM REPEAT: MOVL (R1)+,-(R2) ; Copia memoria memoria dalla cella puntata da R1 in quella puntata da ; R2-4 (MOVL!). Alla fine del com. R1=R1+4, R2=R2-4 SUBL #1,R0 ; Decrementa il contatore R0 JNZ REPEAT ; Se R0!=0 salta a REPEAT HALT END ; Fine programma Soluzione 3: indirizzamento con spiazzamento ORG 400H ;****************Dichiarazione Costanti******************** DIM EQU ? ARRAY1 EQU 250H ARRAY2 EQU 278H ;******************Corpo del Programma********************* CODE MOVL #DIM,R0 ; carica in R0 la dimensione (numero di elementi) dell'array da invertire SUBL #1,R0 ; decrementa il contatore R0, R0=#DIM-1 ASLL #2,R0 ; R0=R0*4, calcola l'offset da sommare all'ind.base ; del'array per ottenere l'ind. dell'ultimo elemento (ARRAY[#DIM-1]) MOVL R0,R2 ; Copia il contenuto di R0 in R2 MOVL #DIM,R0 ; ed inizializza R0 a #DIM REPEAT: MOVL ARRAY1(R1),ARRAY2(R2) ; Copia memoria memoria dall'indirizzo ARRAY1[i] in ; ARRAY2[#DIM-1-i], i=[0..#DIM-1] ADDL #4,R1 ; Incrementa di 4 byte R1 (gli elementi dell'array sono longwords!) SUBL #4,R2 ; Decrementa di 4 byte R2 ; R1=i*4, R2=(#DIM-1-i)*4 SUBL #1,R0 ; Decrementa il contatore R0 JNZ REPEAT HALT END