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