Il processore PD32 Set Istruzioni
Set Istruzioni L istruzione (almeno 32 bit) è divisa in più campi codice operativo specifica operazione (classe e tipo) parte indirizzo specifica modalità di uso deidati registri interni registri di memoria (più modalità) dati immediati (ad es. costanti): memorizzati nei byte successivi nome simbolico
Set Istruzioni Sono organizzate in 8 classi (3 bit codice operativo specificano la classe) 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 istruzioni int i,j i = i + j Programma compilatore Codice mnemonico Tipo di dato L (longword) W (word) B (byte) ADDW R2, R1 Sorgente Destinazione Linguaggio Assembly (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 DATO K I/O S MODO S SORG MODO D DEST Codice Operativo Specifica il tipo d istruzione Operandi Specifica i dati su cui operare
Campo n.bits Commento Classe Indica la classe di istruzione (movimento dati, rotazione e shift, 3 aritmetiche ) Tipo Al''interno della classe viene indicato quale tra le operazioni disponibili 5 deve essere eseguita dato k Campo contenente un dato utilizzato nelle istruzioni di rotazione e shift e 8 nelle istruzioni di I/O I/O Campo utilizzato nelle istruzioni di I/O, codifica il modo con cui l'indirizzo 2 del device può essere recuperato s 2 Indica il formato del dato che deve essere trattato dall'operazione. modo s 3 Indica il modo di indirizzamento dell'operando sorgente. sorg In caso di indirizzamento diretto a registro, indiretto a registro, con 3 predecremento e con postincremento indica uno degli otto registri di uso generale R0-R7 modo d 3 Indica il modo di indirizzamento dell'operando destinazione. dest In caso di indirizzamento diretto a registro, indiretto a registro, con 3 predecremento e con postincremento indica uno degli otto registri di uso generale R0-R7
Alcune istruzioni Assembler MOVB R1,R2 - copia il contenuto del primo byte di R1 in R2 MOVW R1,(R2) - copia il contenuto dei primi 2 byte di R1 nei due byte di memoria il cui indirizzo iniziale memorizzato in R2 MOVL (R1),R2 - copia in R2 il contenuto dei 4 bytes di memoria il cui indirizzo è specificato in R1 nel seguito s indica una lettera tra B (byte), W (word, 2 byte) L (long word, 4 byte) SUBs R1,R2 - 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 ADDs #d,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 formato dato campo s operandi e modo indiriz. operandi CLASSE TIPO byte diretto con registro 4 3 001 0000.. 00 000 100 000 011 31 29 28 24 23 16 15 14 13 12 11 9 8 6 5 3 2 0 Modo sorg Modo dest
Esempi di traduzione istruzioni assembler in linguaggio macchina (cont.) ADD B #20,R3 Codice mnemonico CLASSE TIPO formato dato campo s byte Indirizzamento Immediato (vedi byte successivo) operandi e modo indiriz. operandi Indirizzamento diretto con registro 3 010 0000.. 00 001 000 011 31 29 28 24 23 16 15 14 13 12 11 9 8 6 5 3 2 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) ADDW R1, R2 1) R1 -> Temp1 2) R2 -> Temp2 3) ALU-OUT (Temp1+Temp2) -> R2 (nessun accesso a memoria esterna) 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 #20h, R2 1) PC -> MAR 2) (MAR) -> MDR, R2 -> Temp1 3) MDR -> Temp2, PC + 2 -> PC 4) 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 1 MOVW (R5),R0 ; R0:=S PC+4 2 ADDW (R4),R0 ;R0:=R0+V1 PC+8 3 ADDB #2,R4 ;punta al prossimo versamento PC+13 4 ADDW (R4),R0 ;R0:=R0+V2 PC+17 5 ADDB #2,R4 ;punta al prossimo versamento PC+22 6 ADDW (R4),R0 ;R0:=R0+V3 PC+26 7 SUBW (R3),R0 ;R0:=R0-P1 PC+30 8 ADDB #2,R3 ;punta al prossimo prelievo PC+35 9 SUBW (R3),R0 ;R0:=R0-P2 PC+39 10 MOVW R0,(R5) ;S:=R0
Altre istruzioni JMP JZ HALT MOVB #dato,r1 SALTO INCONDIZIONATO SALTO CONDIZIONATO FINE PROGRAMMA 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 R4 punta al I vers. R0 memorizza il Saldo R1 mem. il versamento R1=0? si R5:=1B00 R4:=1F00 R0:=(R5) R1:=(R4) R1:=R1+0 JZ no R0:=R1+R0 R4:=2+R4 Somma al saldo il vers. R4 punta al vers. succ. (R5):=R0 HALT ora in memoria c è il saldo aggiornato
Il codice ASSEMBLER INDIRIZZO CODICE COMMENTO 0400 MOVL #1B00h,R5 ;inizializza il registro R5 0408 MOVL #1F00h,R4 ;inizializza il registro R4 0410 MOVW (R5),R0 ;carica in R0 il saldo attuale 0414 MOVW (R4),R1 ;carica in R1 il movimento puntato da R4 0418 ADDB #0,R1 ;aggiorna il registro SR 041D JZ 0436h ;salta a memorizza il nuovo saldo se non vi sono altri movimenti 0425 ADDW R1,R0 ;aggiungi al saldo il movimento in R1 0429 ADDB #2,R4 ;incrementa il puntatore ai movimenti 042E JMP 0414h ;procedi con un nuovo movimento 0436 MOVW R0,(R5) ;memorizza il nuovo saldo 043A HALT
Una soluzione equivalente
START R5 punta al Saldo R4 punta al I vers. R0 memorizza il Saldo Somma al saldo il vers. scrivi il saldo in memoria R4 punta al vers. succ. Somma al saldo il vers. confronta il saldo attuale con il saldo in mem. R5:=1B00 R4:=1F00 R0:=(R5) R0:=R0+(R4) (R5):=R0 R4:=2+R4 R0:=(R4)+R0 R1:=R0-(R5) JNZ no HALT si
Assemblatore Traduce il codice scritto in assembler in codice macchina Ad ogni istruzione macchina è associato un codice mnemonico 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 Tipo (byte) Sorgente Destinazione 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??? 00??????? 400 404 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) Effective Address (EA): la posizione di un operando in memoria EA può essere un registro o una locazione di memoria Il valore di EA deve essere noto al tempo di esecuzione del programma (run-time); in generale non è noto al momento della sua scrittura (compiletime). Ciò consente di ottenere una grande flessibilità (rilocazione del codice)
Modi diretti Modi di indirizzamento Diretto con registro Immediato Assoluto Modi indiretti Indiretto con registro Indiretto con spiazzamento Relativo Indiretto con predecremento Indiretto con postdecremento
EA=Ri Indirizzamento a registro 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) il dato è memorizzato nei 4 byte successivi al codice dell istruzione
Indirizzamento assoluto MOVL R1,1280H (assegna il valore di R1 alla cella di memoria di indirizzo 1280H) 1280H, è memorizzato dopo l istruzione ed è riferito da PC dopo che è stato incrementato) Effective address = 1280H
Indirizzamento relativo Usato nei salti, permette di aggiornare il PC con valori differenti di semplici incrementi. JMP LABEL(PC) (metti nel PC quanto ottenuto dalla somma del contenuto della locazione il cui indirizzo è dato da LABEL con il valore corrente del PC)
Indirizzamento relativo JMP LABEL(PC) (metti nel PC quanto ottenuto dalla somma del contenuto della locazione il cui indirizzo è dato da LABEL con il valore corrente del PC) Label indica lo scostamento rispetto al valore corrente di PC se il programma viene spostato in una diversa zona di memoria cambia il valore di PC in due diverse esecuzioni MA lo spostamento relativo non cambia aritmetica in complemento a due (per permettere salti in avanti e indietro)
Indirizzamento indiretto con registro Il registro contiene l indirizzo dell operando (corrisponde alla nozione di puntatore nei linguaggi di programmazione) MOVL (R5),R1 (sposta in R1 in contenuto della locazione di mem. il cui indirizzo è contenuto in R5)
Indirizzamento indiretto con registro se si aggiorna il registro cambia l indirizzo di memoria esempio inserendo in un ciclo il frammento di istruzioni ADDL (R2),R1 ADDB #4, R2 - somma a R1 il contenuto della locazione di mem. il cui indirizzo è contenuto in R2) - somma 4 a R2 permette di sommare a R1 i contenuti di locazine di memoria successive - domanda perché somma 4 e non 1 o 2?
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: MOVL D(R0),R1 (significato: sposta in R1 il contenuto della cella con indirizzo D+R0)
Indirizzamento Riepilogo org 400h code movl #20, r1 addl r1,r1 movb #0FFh, 800h movl #800h,r2 movb #0EEh, (r2) movb #0FFh, -(r2) movb #0AAh, (r2)+ movb #0FFh, 8(r2) end ; r1=20, ind. immediato ; r1=40, ind. a registro ;mem[0x800]=0xff, ind. assoluto ;r2=0x800 ;mem[r2]=0xee, ind. con registro ;r2=0x800-0x1=0x7ff, mem[0x7ff]=0xff ;ind. con predecremento ;mem[0x7ff]=0xaa, r2=0x800 ;ind. con postincremento ;mem[0x808]=0xff, r2=0x800 ;ind. con spiazzamento
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
Registri di stato il registro di stato contiene informazioni sull ultima operazione eseguita Carry, C: 1 se c e stato riporto Negative, N: 1 se risultato ultima oper. è neg. Zero, Z: 1 se ultima oper. ha 0 come risultato overflow, V: 1 se ultima oper. da overflow Parity, P: 1 se risultato ult. oper. ha numero pari di 1 Interrupt enable: se la CPU può accettare interruzioni esterne (es. per operazioni di I/O)
Istruzione CMP CMPs effettua la sottrazione SENZA modificare la destinazione es. CMPL R1,R2 sottrai R1 a R2 aggiorna registro stato ma NON modificare R2 registri di stato di interesse aritmetico Z risultato è zero C segnala segno (ricorda la rappresentazione circuito per la sottrazione in compl. a 2)
Istruzione CMP CMPs effettua la sottrazione SENZA modificare la destinazione es. CMPL R1,R2
Confronto fra registri Aritmetica non segnata CMPL R1,R2 (ipotesi: R1,R2>=0) Equivale ad eseguire R2-R1 senza aggiornare R2 C=1 CMPL R1,R2 C=0 Z=1 Z=0 C=1 ÛR1>R2 Z=1 Û R1=R2 C=0 and Z=0 Û R1<R2 R2-R1<0 (R1>R2) R2-R1>=0 (R1<=R2) Z=0 R1<R2 R1=R2 R1<>R2 not C=0 ÛR1<=R2 Z=0 Û R1<>R2 Z=1 or C=1 Û R1>=R2
CMPB R1,R2 Confronto fra registri Aritmetica segnata R1,R2 rappresentati in complemento a 2 Equivale ad eseguire R2-R1 senza aggiornare R2 Z=1 R2-R1=0 (R1=R2) CMPB R1,R2 N=V R2-R1>=0 (R2>=R1) N<>V R1<=R2 Z=0 Z=0 R1<>R2 N=V ÛR1>=R2 N<>V Û R1<=R2 Z=1 Û R1=R2 Z=0 Û R1<>R2 Z=0 R1>R2 R1<R2
Esempio movl #100,r1 movl #99,r2 ; a questo punto 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, RTI JMP: serve a modificare il contenuto del PC JSR: modifica il contenuto del PC ma SALVA il valore corrente del PC in una pila (utile nelle chiamate di sottoprogramma) RET modifica il valore del PC con il valore salvato precedentemente in cima alla pila RTI come RET ma quando il salto è causato da una interruzione
Istruzioni di controllo esecuzione Istruzioni di salto condizionato: J, JN 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 (esegue R2-R1, non modifica R2)
Esempio R1>R2 si: R1>R2 R1>R2 si: R1>R2 I1 no: R1<=R2 no: R1<=R2 I1 I2 I2 cmpl R1 R2 JC L2 ;se R1>R2 ;salta ad I2 Istruzione I1 L2: Istruzione I2 cmpl R1 R2 JNC L2 Istruzione I1 L2: Istruzione I2 ;se R1<=R2 ;salta ad I2
no: R1<=R2 R1>R2 Esempio si: R1>R2 if R1>R2 then <I1> else <I2> <I3> I2 I1 cmpl R1 R2 JNC L2 ;R2-R1 ;se R2<=R1 ;esegui I2 I3 L1: I1 ;ramo then jmp L3 L2: I2 ;ramo else L3: I3 ;continua
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 CODICE OPERANDI C N Z V P I COMMENTO 0 Ins dev, D0 - - - - - - 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 - - - - - - Viene azzerato il flipflop STATUS del dev e viene avviata l'operazione. 3 CLEAR dev - - - - - - 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 15 interi fra 0 e 255 Programma Valore massimo
Esempio programma assembly (cont) Decidere tipo e numero variabili da usare Dove memorizzare i valori in ingresso -> Vettore V di 15 elementi Quali variabili ausiliare sono necessarie Dove memorizzare il valore di uscita registro Algoritmo che risolve il problema ipotizzare come valore massimo 0 e confrontarlo con tutti i 15 valori, aggiornandolo ogni volta che se ne trova uno maggiore
Algoritmo e dati V Inizio max 0 1 14 i i=0 max=0 i<15 si no Fine V[i]>max no max=v[i] i=i+1
Uso dei registri.. Memoria (mem) Inizio R3 0x1300 0 1 R1 (i) R1=0,R2=0 R3=0X1300 R1<15 no Fine 14 si mem[r3]>r2 no R2(max) R2=mem[R3] R1=R1+1 R3=R3+1
Soluzione prima versione R3 0x1300 Memoria (mem) 0 1 R1 (i) Inizio R1=0,R2=0 R3=0X1300 R1>=15 si Fine loop: XORL R1,R1 XORL R2,R2 MOVL #1300h,R3 CMPB #15,R1 JNC fine; R2(max) 14 no mem[r3]>r2 si R2=mem[R3] R1=R1+1 no skip: CMPB (R3),R2 JNC skip MVLB (R3),R2 ADDL #1,R3 ADDB #1,R1 jmp loop R3=R3+1 fine: 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 label EQU n costanti 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: 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: XORL R1,R1 XORL R2,R2 CMPL #numel,r1 JNC fine; movl base(r1),r3 CMPB R3,R2 JNC skip MVLB R3,R2 ADDB #1,R1 jmp loop halt end end
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- e pre-incremento Soluzione 3: indirizzamento con spiazzamento
Il problema Array1 Array2 2500h 2504h 2508h... 2536h V1 V2 V3 Vi V8 V9 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 XORL R0,R0 ; resetta R0 XORL R1,R1 ; resetta R1 XORL R2,R2 ; resetta R2 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 ; R1 ora punta all'elemento succ. di ARRAY1 SUBL #4,R2 ; R2 ora punta all'elemento prec. di ARRAY2 SUBL #1,R0 ; decrementa il contatore R0 di 1 JNZ REPEAT ; salta a REPEAT se R0 diverso da 0 HALT END ; fine programma
Soluzione 2: indirizzamento con post- e pre-incremento
ORG 400H ;****************Dichiarazione Costanti******************** DIM EQU? ARRAY1 EQU 2500H ARRAY2 EQU 3000H ;******************Corpo del Programma********************* CODE XORL R0,R0 ; resetta R0 XORL R1,R1 ; resetta R1 XORL R2,R2 ; resetta R2 MOVL #ARRAY1,R1 ; carica in R1 l'indirizzo base dell'array originale MOVL #ARRAY2,R2 ; carica in R2 l'indirizzo base dell'array invertito REPEAT: MOVL #DIM,R0 ASLL #2,R0 ADDL R0,R2 MOVL #DIM,R0 MOVL (R1)+,-(R2) SUBL #1,R0 JNZ REPEAT ; carica in R0 la dimensione (numero di elementi) dell'array da invertire ; 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] ; R2 ora punta a ARRAY[#DIM] ; Inizializza R0 a #DIM ; 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 ; Decrementa il contatore R0 ; 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 XORL R0,R0 ; resetta R0 XORL R1,R1 ; resetta R1 XORL R2,R2 ; resetta R2 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