Che materia stai cercando?

Anteprima

ESTRATTO DOCUMENTO

org $1000

STRINGA DS.B 255 Buffer per la stringa da convertire.

DS 0

TGLCASE MOVE.B (A0),D0 Preleva dalla memoria il prossimo

* carattere da manipolare.

BEQ FINE_STRINGA Se il carattere corrente e` il

* catarrere NULL, la stringa e`

* terminata.

CMP.B #$41,D0 Verifica se il carattere e` maiuscolo:

BCS NON_LETTERA se il carattere corrente precede il

CMP.B #$5A,D0 carattere 'A' oppure segue il carattere

BLS LETTERA 'Z', allora non e` maiuscolo.

CMP.B #$61,D0 Verifica se il carattere e` minuscolo:

BCS NON_LETTERA se il carattere corrente precede il

CMP.B #$7A,D0 carattere 'a' oppure segue il carattere

BHI NON_LETTERA 'z', allora non e` ne' minuscolo ne'una

* lettera.

LETTERA EOR.B #$20,D0 Se il carattere corrente e` una

MOVE.B D0,(A0)+ lettera maiuscola diventa minuscola e

* vicerversa se e` minuscola diventa

* maiuscola.

NON_LETTERA BRA TGLCASE

FINE_STRINGA RTS

*

INIZIO MOVEM.L A0,-(SP) Salva sullo stack il contenuto del

* registro che serve per operare.

MOVE #STRINGA,A0 Punta alle locazioni dei fattori da

* moltiplicare.

BSR TGLCASE Esegue la conversione della stringa.

MOVEM (SP)+,A0 Ripristina il contenuto precedente

* nel registro servito per operare.

END INIZIO

2.89 EXT Signed extend

1101 R mode ea

dest=dest+sorg

- * * 0 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.90 EXT Sign-extend

01000100 Op-mode 000 Reg

(dest) Esteso in segno Dest

X N Z V C

- * * 0 0

N=1 se il risultato è negativo, azzerato altrimenti

Z=1 se il risultato è zero, azzerato altrimenti

V è sempre azzerato

C è sempre azzerato

X non viene modificato

EXT Dn

Size: W,L

esempio

* LE SEGUENTI LINEE DI PROGRAMMA

* MOSTRANO L'UTILIZZO DEL CODICE EXT

* IL CODICE PUO' ESSERE UTILIZZATO PER

* OPERAZIONI DI CASTING.

* N.B.: OCCORRE PORRE ATTENZIONE AL CASO IN CUI

* GLI OPERANDI SON UNSIGNED ED HANNO IL BIT

* PIU' SIGNIFICATIVO PARI AD 1

* ESEMPIO: SOMMA DI UN BYTE ED UNA WORD SIGNED

*area dati

ORG $8300

wrd: dc.w $1234

*area programma

ORG $8100

start: move.w wrd,d0

move.b #$07,d1

ext.w d1 *d1 ora contiene il valore $0007

add.w d1,d0 *somma in complementi: d0= $123B

end start

ESEMPIO 2

(somma di un byte ad una word)

*area dati

ORG $8300

wrd: dc.w $1234

*area programma

ORG $8100

start: move.w wrd,d0

move.b #$80,d1 * d1=10000000

ext.w d1 * d1=$FF80

add.w d1,d0 * somma in complementi: d0=$11b4

end start

* se d1 era unsigned la somma avrebbe dovuto produrre d0=$12B4

* si puo ovviare al problema introducendo dopo la linea ext.w d1

* l'istruzione andi.w #$00FF,d1

ESEMPIO 3

(Somma di un byte ed una word signed)

*area dati

ORG $8300

wrd: dc.w $1234

*area programma

ORG $8100

start: move.w wrd,d0

move.b #$80,d1 * d1=10000000

ext.w d1 * d1=$FF80

andi.w #$00FF,d1

add.w d1,d0 * somma in complementi: d0=$11b4

end start

* se d1 era unsigned la somma avrebbe dovuto produrre d0=$12B4

* si puo ovviare al problema introducendo dopo la linea ext.w d1

* l'istruzione andi.w #$00FF,d1

2.91 EXTW Sign-extend low order byte of data register to word

0100100010000 Dn

Dn - sign-extend -> Dn

X N Z V C

- * * 0 0

set N if the result is negative.Cleared otherwise

set Z if the result is zero.Cleared otherwise

EXTW Dn

*

esempio

2.92 EXTL Sign-extend low order word of data register to Long

0100100011000 Dn

Dn - sign-extend -> Dn

X N Z V C

- * * 0 0

set N if the result is negative.Cleared otherwise

set Z if the result is zero.Cleared otherwise

EXTL Dn

*

esempio

2.93 JMP Jump

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.94 JMP Jump

0100111011 EA

dest =>PC

X N Z V C

- - - - -

Jump <ea>

size: Unsized

esempio

2.95 JMP Jump

0100 1110 11 ea

PC=Destinazione

X N Z V C

- - - - -

Tutti i flag sono not affected

JMP <ea>

Unsized

ea - Specifica l’indirizzo della prossima istruzione

(destinazione). Sono concessi solo control addressing

modes.

esempio

2.96 JSR Jump to subroutine

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.97 JSR Jump to Subroutine

0100111010 Effective Address

PC=>SP@-

Destination=>PC

X N Z V C

- - - - -

JSR <ea>

size:Unsized

esempio

2.98 JSR Jump to Soubroutine

0100 1110 10 ea

SP@-=PC ; PC=Destinazione

X N Z V C

- - - - -

Tutti i flag sono not affected

JSR <ea>

Unsized

ea - Specifica l’indirizzo della prossima istruzione

(destinazione). Sono concessi solo control addressing

modes.

esempio

Usato in più esempi.

2.99 LEA Load effective address

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.100 LEA Load Effective Address

0100 Register 111 Effective Address

Destination=>An

LEA <ea> into Am

X N Z V C

- - - - -

size: Long

esempio

2.101 LEA Load Effective Address

0100 reg 111 ea

lea <ea> into An

X N Z V C

- - - - -

Tutti i flag sono not affected

LEA <ea>,An

Size : L

reg - Spesifica il registro indirizzo in cui sarà caricato

l’effective address.

ea - Specifica l’operando il cui effective address andrà caricato

in An. Sono concessi solo control addressing modes.

*

esempio

2.102 LINK Link and allocate

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.103 LINK Link and allocate

0100111001010 Reg

An SP@- ; SP An ;SP+d SP

X N Z V C

- - - - -

Nessun flag di CC viene modificato

LINK An,#<displacement>

Size: Unsized

esempio

* LE SEGUENTI LINEE DI PROGRAMMA MOSTRANO L'UTILIZZO

* DEI CODICI LINK E UNLK.

* TALI CODICI SONO UTILI PER L'ALLOCAZIONE DINAMICA

* DEI PARAMETRI SULLO STACK.iL REGISTRO A6 SARA'

* UTILIZZATO COME FP.

ORG $8000 *AREA DATI

frst equ 0

last equ 4

size equ 2

num dc.w 1,2,5,4,3

eanum equ num-(frst*size)

ORG $9000 *AREA STACK

stk ds.w 40

stke equ *

ORG $8100 *AREA SUBROUTINE

* l'array contiene i valori 1 2 5 4 3

* la routine cerca il max e la sua posizione lasciando l'output sullo stk

cercamax link a6,#0 *salva il fp,aggiorna fp e non alloca var locali

movea.w indnum(a6),a0

move.w #frst,d0

move.w d0,d1

mulu.w #size,d1

move.w d1,a1

adda.w a0,a1

move.w #frst,d2 *si assume che il max sia il primo

move.w (a1),d3

iloop add.w #1,d0 *si incrementa l'indice d0

move d0,d1

mulu.w #size,d1

move.w d1,a1

adda.w a0,a1 *a1 punta al successivo

cmp.w (a1),d3 *confronto col max corrente

bge skip

move.w (a1),d3 *a1 punta al nuovo max

move.w d0,d2 *l'indice d0 va salvato in pos

skip cmpi.w #last,d0

ble iloop *a fine ciclo d2 e d3 contengono il max e la

*sua posizione

move.w d2,pos(a6)

move.w d3,max(a6)

unlk a6

indnum equ 8

pos equ 10

max equ 12

rts

* area programma

ORG $8400

start andi.w #$DFFF,sr *pone il processore in stato utente

movea.l #stke,sp

movea.l sp,a6 * a6 frame pointer

adda.w #-4,sp *riserva area parametri di output sullo stk

move.w #eanum,a0

move.w a0,-(sp) *passa l'array per indirizzo

jsr cercamax

move.w -(a6),d0 *max

move.w -(a6),d1 *pos del max

end start

2.104 LINK Link and Allocate

01001110010 Register Displacement

Push(An) ; An=SP ; SP+d#SP

X N Z V C

- - - - -

LINK An,#<displacement>

size: unsized

-Register: specifica il registro indirizzo attraverso il quale

viene realizzato il link

-Displacement: Specifica l’intero espresso in complementi che deve

essere sommato allo start pointer

*

2.105 LSL Logical shift left

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.106 LSL Logical shift left

1110 count|Reg 1 size i/r 01 R (Register Shifts)

dest<=dest<<count

1110 001 111 ea (Memory Shifts)

dest<=dest<<1

X,N,Z,V,C

* * * 0 ?

C= D

m-count+1

X,N,Z,V,C ( count == 0 )

- * * 0 0

LSL Dx,Dy

LSL #<data>,Dy

LSL <ea>

size: B,W,L ( Register Shifts )

size: W ( Memory Shifts )

esempio

ORG $8000

* Si mostra come sia possibile implementare l'operazione di divi-

* sione, unsigned, di dividendo a 32 bit con divisore a 16 bit

* utilizzando operazioni ai SUB e di LSL.

* L'esempio è strutturato come subroutine che effettua l'operazio-* ne

desiderata, a questo proposito si assume che in D0 vi sia il * dividendo e

nella parte bassa di D1 vi sia il divisore.

* La routine restituisce in D0 il risultato dell'operazione, nella * word

bassa il quoto e nella word alta il resto; D1 rimane inal- * terato. Se il

divisore è nullo oppure il quoto non è rappresen- * tabile in 16 bit D0

rimane inalterato mentre i bit 16 e 17 ri- * spettivamente di D1 vengono

posti ad 1

start

* DIVISIONE PER ZERO

MOVE.L #$FE351234,d0

MOVE.L #0,d1

jsr DIVIDE

* OVERFLOW DI DIVISIONE

MOVE.L #$FE351234,d0

MOVE.L #$1234,d1

jsr DIVIDE

* DIVISIONE “NORMALE”

MOVE.L #$FE351234,d0

MOVE.L #$FF34,d1

jsr DIVIDE

STOP #$80

* ROUTINE DI DIVISIONE

DIVIDE

MOVE.L d2,-(a7) Salvataggio sullo stack di D2

CMP.W #0,d1 Test divisione per 0

BNE NOOVFL1

* divisione per zero => set del bit #16 di D1 ad 1 ed uscita dalla * routine

* BSET.L #16,D1 istruzione non funzionante per cui usiamo

OR.L #$10000,d1

BRA ENDDIV

NOOVFL1

SWAP.W d1 porta il divisore nella word alta di D1

CMP.L d1,d0 determina se il quoto sia rappresentabile *

in 1 word

BCS NOOVFL2

* overflow nella rappresentazione del quoto => set del bit #17 di * D1 ed

uscita dalla routine

SWAP.W d1 riporta il divisore nella word bassa di D1

* BSET.L #17,D1 istruzione non funzionante per cui usiamo

OR.L #$20000,d1

BRA ENDDIV

NOOVFL2

* utilizziamo il size L perché nell'attuale implementazione DBF * che

decrementa il registro D2 lo decrementa a 32 bit => se uti- * lizzassimo il

size B o W senza "pulire" la parte restante del * registro il ciclo

potrebbe non effettuare il numero di iterazio-* ni previsto

MOVE.L #15,d2 D2 = loop count

* ciclo di divisione; la precondizione sempre verificata è:

* D0[31..16] < D1[31..16]

FORDIV

* Shift Left del dividendo (corrisponde ad abbassare una cifra nel * classico

algoritmo di divisione)

* nel LSB di D0 verranno man mano memorizzate le cifre del quoto

LSL.L #1,d0

BCS CSETDIV1

* il MSB di D0 prima del LSL era 0

CMP.L d1,d0 determina se D1[31..16] < D0[31..16]

BCS CSETDIV2

* D1[31..16] >= D0[31..16]

SUB.L d1,d0 D0[31..16] = D0[31..16] - D1[31..16]

BSET.L #0,d0 la cifra attuale del quoto è 1

BRA LABDIV

CSETDIV2

* D1[31..16] < D0[31..16]

BCLR.L #0,d0 la cifra attuale del quoto è 0

BRA LABDIV

CSETDIV1

* il MSB di D0 prima del LSL era 1

SUB.L d1,d0 D0[31..16] = D0[31..16] - D1[31..16]

BSET.L #0,d0 la cifra attuale del quoto è 1

LABDIV DBF d2,FORDIV

ENDDIV

MOVE.L (a7)+,d2 Ripristino di D2

RTS

end start

2.107 LSR Logical shift rigth

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.108 LSR Logical shift rigth

1110 count|Reg 0 size i/r 01 R (Register Shifts)

dest<=dest>>count

1110 001 011 ea (Memory Shifts)

dest<=dest>>1

X,N,Z,V,C

* * * 0 ?

C= D

count-1

X,N,Z,V,C ( count == 0 )

- * * 0 0

LSR Dx,Dy

LSR #<data>,Dy

LSR <ea>

size: B,W,L ( Register Shifts )

size: W ( Memory Shifts )

esempio

ORG $8000

* Esempio di utilizzo dell'istruzione LSR

* Si mostra come sia possibile implementare l'operazione di mol-

* tiplicazione, unsigned, di operandi a 16 bit con risultato a 32 * bit

utilizzando operazioni ai ADD e di LSR.

* L'esempio è strutturato come subroutine che effettua l'operazio- * ne

desiderata, a questo proposito si assume che nella parte

* bassa di D0 vi sia il moltiplicatore, a 16 bit, e che nella

* parte alta vi sia il moltiplicando.

* La routine restituisce in D1 il risultato dell'operazione

* Per un descrizione dell'algoritomo vedi Wakerly pag.103

start

MOVE.L #$12341234,d0

MOVE.L #12345,d2

jsr MULTIPLY2

MOVE.W #$FF34F234,d0

jsr MULTIPLY2

STOP #$80

MULTIPLY2

MOVE.L d2,-(a7) Salvataggio sullo stack di D2

* utilizziamo il size L perché nell'attuale implementazione DBF * che

decrementa il registro D2 lo decrementa a 32 bit => se uti- * lizzassimo il

size B o W senza "pulire" la parte restante del * registro il ciclo

potrebbe non effettuare il numero di iterazio-* ni previsto

MOVE.L #15,d2 D2 = loop count

MOVE.L d0,d1 Inizializzazione D1 = risultato parziale

AND.L #$0000FFFF,d1 Pulisce la parte alta di D1

AND.L #$FFFF0000,d0 Pulisce la parte bassa di D0

FOR2 BTST.L #0,d1 testa il LSB del moltiplicando shiftato

BEQ NOADD2

ADD.L D0,D1 somma il moltiplicando shiftato al

* risultato parziale

BCS CARSET2

* il LSB del moltiplicatore shiftato era nullo

NOADD2

LSR.L #1,d1 shift a destra del risultato parziale e

* del moltiplicando

BRA LAB2

CARSET2 * l'addizione ha generato carry

LSR.L #1,d1 shift a destra del risultato parziale e

* del moltiplicando

* BSET.L #31,d1 istruzione non funzionante per cui usiamo

OR.L #$80000000,d1 pone il MSB del prodotto parziale ad 1

LAB2 DBF d2,FOR2

MOVE.L (a7)+,d2 Ripristino di D2

RTS

end start

2.109 MOVE Move data from source to destination

00 size (reg mode) (mode reg)

D S

dest<=*source

- * * 0 0

MOVE <ea>,<ea>

size: B,W,L

esempio

2.110 MOVE Move data from source to destination

00 size (reg mode) (mode reg)

D S

dest *source

X,N,Z,V,C

- * * 0 0

MOVE <ea>,<ea>

size: B,W,L

Modi di indirizzamento non permessi :

- relativo

- relativo indicizzato

- immediato

esempio :

*Sottrazione tra due operandi memoria attraverso registri data

*

org $8200

INIZIO MOVE.L MINUENDO,D0

MOVE.L SOTTRAENDO,D1

SUB.L D0,D1 *RISULTATO IN D1

MOVE.L D1,RISULTATO

FINE NOP

*

MINUENDO DC.L $9E2A127C

SOTTRAENDODC.L $2AB35481

RISULTATO DS.B 1

* END INIZIO

*Scambio tra due vettori in ordine inverso

* org $8200

INIZIO LEA VETTORE1,A0 IND. DI INIZIO DI VETTORE1 IN A0

LEA VETTORE2+10,A1 IND. DI FINE DI

VETTORE2 IN A1

MOVE.B #10,CNT INIZIALIZZAZIONE DEL CONTATORE

CICLO MOVE.B (A0)+,-(A1)

SUBI.B #1,CNT

BNE CICLO

FINE NOP

VETTORE1 DC.B $9E,$2A,$12,$7C,$2E,$F4,$72,$8C,$A2,$B4

VETTORE2 DS.B 10

CNT DC.B 0

END INIZIO

*Sposta in un vettore di word la word + significativa di una serie di

longword.

* org $8200

INIZIO LEA SORGENTE,A0 *IND. DI SORGENTE IN A0

LEA DESTINAZIONE,A1 *IND. DI DESTINAZIONE IN A1

MOVE #0,D0

CICLO MOVE (A0,D0),(A1)

ADDI.B #4,D0

ADDA #2,A1

CMP #20,D0

BNE CICLO

FINE NOP

SORGENTE DC.L $9E347B2C,$21E3F60A,$17AB7B20,$11AE37F6,$31FFE10A

DESTINAZIONE DS.W 5

END INIZIO

2.111 MOVE to CCR Move to condition codes

0100010011 ea

CCR<=*sorg

? ? ? ? ?

I flag saranno settati in accordo al valore posto in sorg

MOVE <ea>,CCR

size: W

esempio

2.112 MOVE to CCR Move to condition codes

0100010011 Ea

CCR<=(sorg)

X N Z V C

* * * * *

I flag saranno settati in accordo al valore posto in sorg

MOVE <Ea>,CCR

Size: W

esempio :

****************************************************************************************

*PROGRAMMA DI PROVA DEL CODICE MOVE to CCR

*Il programma seguente mostra l'utilizzo del codice MOVE to CCR per settare in

*maniera opportuna i codici di condizione in una procedura di ricerca lineare di una

*word in un vettore di word. In particolare MOVE to CCR viene utilizzato per

*abbassare il flag Z utilizzato dalla procedura Srch come indicatore dell'esito

*della ricerca: Z=1 -> esito postivo

* Z=0 -> esito negativo

****************************************************************************************

*Area Programma a partire dalla locazione $8000

ORG $8000

START move.w sr,d0 legge il registro di stato

andi.w #$d8ff,d0 maschera per reg stato (stato utente, int abilitati)

move.w d0,sr pone liv int a 000

move.l #$0d300,sp inizializza stack pointer

lea Array,a0

move.w #$800,d0

jsr Srch

move.w #$810,d0

lea Array,a0

jsr Srch

stop #$FF00

Srch nop

*

*

*Ricerca nel vettore Array (il cui indirizzo base è in a0) la word contenuta in d0

*ed esce con Z=1 se l'elemento cercato è presente.

*

*

ciclo move.w (a0)+,d2

cmp.w d0,d2

beq.s fine elemento presente -> esce con Z=1

cmp.w #riemp,a0

bne.s ciclo

jsr resetZ esito della ricerca negativo -> esce con Z=0

fine rts

*

*Routine per azzerare il flag Z

*

resetZ move sr,d1

andi #$fffb,d1

move d1,ccr

rts

*Area dati a partire dalla locazione $9000

org $9000

Array dc.w

$8000,$4000,$2000,$1000,$800,$400,$200,$100,$80,$40,$20,$10,$8,$4,$2,$1

riemp equ Array+32

end START

2.113 MOVE to CCR

0100010011 ea

CCR=SORG

X N Z V C

? ? ? ? ?

I flag saranno sostituiti dai bit di sorg

MOVE <ea>,CCR

size: W

EA può essere solo un “Data alterable addressing mode”

*

esempio

ORG $9420

VIA MOVE #$FFFF,CCR

MOVE #0,CCR

MOVE #$000F,CCR

END VIA

2.114 MOVE to SR Move to the status register (istr. priv.)

0100011011 ea

SR<=*sorg

? ? ? ? ?

I flag saranno settati in accordo al valore posto in sorg

MOVE <ea>,SR

size: W

esempio

2.115 MOVE to SR move to status register (istr.priv.)

0100011011ea

SR=(source)

X N Z V C

* * * * *

Tutti i flag sono settati in accordo al valore posto in source

MOVE <ea>,SR

size: W

ea - specifica la locazione dell’operando source.

Sono concessi solo data addressing modes.

*

esempio

2.116 MOVE from SR Move from the status register

0100000011 ea

dest<=SR

X,N,Z,V,C

- - - - -

MOVE SR,<ea>

size: W

esempio

2.117 MOVE from SR

01000011 Size ea

dest=SR

X N Z V C

- - - - -

Tutti i flag sono not affected.

MOVE SR,<ea>

size: W

EA può essere solo un “Data alterable addressing mode”

*

esempio

2.118 MOVE from SR Move from the status register

0100000011 Ea

dest<=SR

X N Z V C

- - - - -

MOVE SR,<Ea>

Size: W

esempio :

Vedi esempio su MOVE to CCR

MOVE USP Move user stack pointer

010011100110 dr reg

An<=USP; USP<=An

- - - - -

MOVE USP,An

MOVE An,USP

size: L

esempio

2.119 MOVEA Move address

1101 R mode ea

dest=dest+sorg

- - - - -

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.120 MOVEM Move multiple register

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.121 MOVEM Registers to EA Move multiple registers to effective address

010010001 Sz Ea

Dest=Registers

X N Z V C

- - - - -

MOVEM <Register list>,<Ea>

Size: W,L

esempio :

2.122 MOVEM Registers to EA Move Multiple Registers to EA

010010001 Size ea

<Registers List Mask>

Dest=Registers

X N Z V C

- - - - -

Tutti i flag sono not affected

MOVEM < Register list>,<ea>

Size= W,L

-Sz Specifica la lunghezza dei registri che devono

essere trasferiti

-ea Specifica l’indirizzo della locazione di memoria a

partire dalla quale i registri saranno trasferiti

in memoria . Sono concessi solo control alterable

addressing modes oppure l’indir. per predecremento.

-Register List Mask Specifica i registri che saranno trasferiti.

L’ordine di trasferimento è il seguente:

D0,D1,...,D7,A0,A1,...,A7 per i control modes,

A7,A6,...,A0,D7,D6,...,D0 per il modo predecremento.

*

2.123 MOVEM EA to Registers Move effective address to multiple registers

010011001 Sz Ea

Registers=(Sorg)

X N Z V C

- - - - -

MOVEM <Ea>,<Register list>

Size: W,L

esempio

2.124 MOVEM EA to Registers Move Multiple EA to Register

010011001 Sz ea

<Register List Mask>

Registers=(Source)

X N Z V C

- - - - -

Tutti i flag sono not affected

MOVEM <ea>,<register list>

Size= W,L

-Sz Specifica la lunghezza dei registri che devono

essere operati

-ea Specifica l’indirizzo della locazione di memoria a

partire dalla quale si trasferirà nei registri.

Sono concessi solo control alterable

addressing modes oppure l’indir. per postincremento.

-Register List Mask Specifica i registri che saranno trasferiti.

L’ordine di trasferimento è il seguente:

D0,D1,...,D7,A0,A1,...,A7.

*

esempio (MOVEM)

MOVM ORG $8000

*Questa routine prova il codice MOVEM per i modi d'indirizzamento "control alterable"; i mod

postincremento e preincremento sono stati usati in vari

altri esempi.

BUF DS.L 4 buffer per il salvataggio dei registri

VIA

*------------------------------------------------------------------------

*Prova per Size = Long

MOVE.L #$12121212,A0 si caricano valori arbitrari

MOVE.L #$34343434,A1 nin alcuni registri

MOVE.L #$56565656,A2

MOVE.L #$78787878,D0

MOVEM.L A0/A1/A2/D0,BUF i registri vengono salvati

* nel buffer

MOVE.L #0,A0 vengono azzerati

MOVE.L #0,A1

MOVE.L #0,A2

CLR.L D0

MOVEM.L BUF,A0/A1/A2/D0 vengono ripristinati

*-------------------------------------------------------------------

*Prova per Size = Word

MOVE #$1212,A0

MOVE #$3434,A1

MOVE #$5656,A2

MOVE #$7878,D0

MOVEM A0/A1/A2/D0,BUF

MOVE.L #0,A0

MOVE.L #0,A1

MOVE.L #0,A2

CLR.L D0

MOVEM BUF,A0/D0/A1/A2 notiamo che l'ordine in cui i registri

* vengono elencati non è importante

*----------------------------------------------------------------------

END VIA

NOTA: Con Size=Long il codice: "carica da memoria a registri", su alcuni

computer non funziona per nessuno dei due modi di indirizzamento

consentiti quando size=Long;infatti carica sempre la stessa costante a

prescindere dal valore presente in memoria.

*

2.125 MOVEP Move peripheral data

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.126 MOVEP

0000 R mode 001 R

dest (source)

X,N,Z,V,C

- - - - -

MOVEP Dx,d(Ay)

MOVEP d(Ay),Dx

size :W,L

Modi di indirizzamento :

- based è l’unico permesso

esempio

*Questo esempio trasporta i byte di 3 longword

*in byte consecutivi.

*

* ORG $8400

INIZIO LEA ALTERNATI,A0 INDIR. INIZIALE DI ALTERNATI IN A0

LEA MATRICE,A1 INDIR. INIZIALE DI MATRICE IN A1

MOVE.L #0,D3 CONTATORE POSTO A ZERO

CICLO MOVE.L (A1,D3),D1 IN D1 CI SONO 4 BYTE DELLA MATRICE

MOVEP.L D1,0(A0) I 4 BYTE VANNO IN ALTERNATI

ADD.L #4,D3 PREDISPOSIZIONE AL PROSSIMO TRASFERIMENTO

ADDA.L #8,A0 BYTE DI DESTINAZIONE SUCCESSIVI

ADD.L #4,D3

CMPI.B #12,D3

BNE CICLO

*

*

MATRICE DC.L $71AB2C43,$31A52F4A,$1EAF2144

ALTERNATI DS.B 24

*

*

FINE NOP

END INIZIO

note

I trasferimenti su indirizzi dispari non sono consentiti.

2.127 MOVEQ Move quick

1101 R mode ea

dest=dest+sorg

- * * 0 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.128 MOVEQ Move quick

0111 REG 0 data

#<data> --> Dn

- * * 0 0

N=1 se il dato è negativo

Z=1 se il dato è nullo

MOVEQ #<dato>,Dn

size: L

esempio:

* Compatta due long-word in unica long-word se la prima

* long-word è con word 0 nella parte alta e la seconda nella

* parte bassa. *

* Si effettua un preventivo controllo delle due long-word

* per vedere se e' possibile effettuare il compattamento

* E'un esempio di utilizzo di MOVEQ(sia per 'pulire' un registro

* e sia per effettuare inizializzazioni di contatore)e della OR.

* Elaborazione: Gruppo 10 - 96/97

ORG $8000

B1 EQU $0000EFA1

B2 EQU $9F6C0000

START MOVE.L #B1,D1

MOVE.L #B2,D2

*CONTROLLO DELLA PRIMA LONG:VERIFICA SE E' DEL TIPO UPPER-WORD =0*

MOVEQ #0,D7 * PULISCE REGISTRO D7 *

MOVEQ #16,D0 * INIZIALIZZA CONTATORE DO A 16*

POP1 LSL.L #1,D1 * SHIFTA IL REGISTRO DI UNA

* POSIZIONE A SINISTRA

MOVE.W SR,D7 * MASCHERA SUL REGISTRO DI STATO *

ANDI.W #1,D7

CMP #1,D7

BEQ ESCI *LA PAROLA NON PUÒ ESSERE COMPATTATA*

SUBI #1,D0 * DECREMENTA CONTATORE *

CMP #0,D0

BNE POP1

MOVE.L #B1,D1 * RIPRISTINA IL VALORE DI D1 *

* CONTROLLO DELLA SECONDA LONG:VERIFICA SE E' DEL TIPO LOW-WORD =0 *

MOVEQ #0,D7 * PULISCE REGISTRO D7 *

MOVEQ #16,D0 * INIZIALIZZA CONTATORE DO A 16*

POP2 LSR.L #1,D2 * SHIFTA IL REGISTRO D2 DI UNA POSIZIONE A

DESTRA MOVE.W SR,D7 * MASCHERA SUL REGISTRO DI STATO *

ANDI.W #1,D7

CMP #1,D7

BEQ ESCI *LA PAROLA NON PUÒ ESSERE COMPATTATA*

SUBI #1,D0 * DECREMENTA CONTATORE *

CMP #0,D0

BNE POP2

MOVE.L #B2,D2 * RIPRISTINA IL VALORE DI D2 *

OR.L D1,D2 * COMPATTA *

MOVE.L D2,AREA * REGISTRA IL VALORE IN MEMORIA *

AREA DS.L 1

ESCI END START

2.129 MOVEQ Move quick

0111 R 0 Data

<Data> -> dest

- * * 0 0

MOVEQ #<data>,Dn

size: L

2.130 UNLK Unlink

01001110011 Register

SP=An; POP(An)

X N Z V C

- - - - -

UNLK An

size: unsized

-Register: specifica il registro indirizzo attraverso il quale

viene realizzato l’ unlink

*

esempio (LINK-UNLK)

NSUB ORG $9200

*Questo esempio è pensato per mostrare l'utilizzo dei codici

*LINK e UNLINK.

*----------------------------------------------------------------

*Subroutine ricorsiva che nega un numero espresso su N word.

*Il numero da negare, N e i flags sono passati nello stack.

*Il numero negato e i flag risultato vengono restituiti ancora nello stack.

LINK A6,#0

MOVE.W LEN(A6),D0 preleva dallo stack il numero di word

che la subroutine deve negare

CMP.L #1,D0 se il numero di word da negare è 1 la

* subroutine provvede alla sua negazione

BEQ unaw

*Abbiamo più di una (n) word da negare:

*la routine richiama se stessa con n-1 word da negare

SUB.L #1,D0

MOVE.L D0,D1 D1 contiene il numero di word (n-1) da

* passare alla nuova chiamata della subroutine

MULU.W #2,D1

ciclo MOVE.W DAT(A6,D1),-(SP) passa le n-1 word da negare

SUB.L #2,D1

CMP.L #2,D1

BGE ciclo

MOVE.W FLAG(A6),-(SP) passa i flags correnti

MOVE.W D0,-(SP) passa il numero di word da negare

JSR NSUB

* Il numero di word da negare è 1

*Preleva dallo stack i risultati delle chiamate precedenti.

unaw MOVE.W LEN(A6),D1

SUB.L #1,D1

BEQ nega

ADDA.L #2,SP rilascia la lunghezza del dato(input)

MOVE.W (SP)+,FLAG(A6) preleva i flag precedenti

MOVE.L #2,D2 spiazzamento per puntare alle word già negate

cicl1 MOVE.W (SP)+,DAT(A6,D2)copia nella propria area dati le word già

* negate dalla precedente chiamata della subroutine

ADD.W #2,D2

SUB.W #1,D1

BNE cicl1

*Viene eseguita la negazione

nega MOVE FLAG(A6),CCR

NEGX.W DAT(A6)

MOVE.W SR,FLAG(A6)

RET UNLK A6

RTS

*-----------------------------------------------------------------------

ORG $9500

DATOL DC.L $00880077

DATOH DC.L $00AA0099 numero da negare su 4 WORD

N DC.W 4 numero di word su cui è espresso il dato

* Spiazzamenti rispetto al FP

LEN EQU 8 numero di word su cui è espresso il dato

FLAG EQU 10 word in cui è memorizzato il CCR corrente

DAT EQU 12 dato da negare

MAIN ANDI #$DFFF,SR passaggio a stato utente

MOVEA.L #$00000000,A6 inizializzazione FP

* (solo a scopo di riferimento)

*Caricamento dei parametri nello stack

MOVE.L DATOL,-(SP)

MOVE.L DATOH,-(SP)

MOVE.W #$0004,-(SP) poniamo nello stack i valori iniziali dei flag:

* il flag X (riporto entrante) è 0;

* il flag Z è 1

MOVE.W N,-(SP)

JSR NSUB chiama la subroutine

END MAIN

*

2.131 MULS Signed multiply

1101 R mode ea

dest=dest+sorg

- * * 0 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.132 MULS Signed multiply

1100 R 111 ea

dest=dest*sorg

X N Z V C

- * * 0 0

N=1 se dest<0

Z=1 se dest=0

MULS <ea>,Dn

size: W

2.133 MULS Signed multiply

1100 R 111 ea

(dest)*(source)=dest

- * * 0 0

N=1 se il risultato è <0

Z=1 se il risultato è 0

MULS <ea>,Dn

size: W

MULS moltiplica due interi con segno rappresentati

in complementi alla base su 16 bit salvando il

risultato nel registro destinazione e rappresen-

tandolo in complementi alla base su 32 bit.

esempio1

ORG $9200

DATI DC.W -$0005,$0005

BEGIN MOVE.W (DATI),D0

MOVE.W (DATI+2),D1

MULS D0,D1

END BEGIN

Dopo l’istruzione MULS:

N=1 (risultato negativo);

Z=0;

esempio2

* Questo programma implementa il prodotto scalare

* di due vettori numerici mediante il codice MULS

ORG $9200

VET1 DC.W $1325,$16BD,-$155A,-$517E,-$1111,$3CA1,$0000

VET2 DC.W -$4317,$73A9,-$2A3F,$09FB,$25AB,$74A3

BEGIN CLR.L D2 azzera la somma

LEA.L VET1,A0 carica gli indirizzi

LEA.L VET2,A1 dei vettori

LOOP MOVE.W (A0)+,D0 scarica gli elementi

CLR.L D1 da moltiplicare nei

MOVE.W (A1)+,D1 registri-dato D0 e D1

MULS.W D0,D1 moltiplica con segno

ADD.L D1,D2 aggiorna somma

TST.W (A0) il vettore è finito?

BNE LOOP

END BEGIN

2.134 MULS Moltiplicazione con segno

Esegue la moltiplicazione con segno tra due operandi a 16 bit, di cui l’operando destinazione è un

registro dati; il risultato è a 32 bit ed è memorizzato, ovviamente, nello stesso registro dati.

1100 R 111 ea

dest<=*(dest) x *(sorg)

X,N,Z,V,C

- * * 0 0

N=1 se MSB *(dest)=1

Z=1 se *(dest)=0

MULS <ea>,Dn

size: W

* $VER: domuls.a 1.1 (26-11-96)

* NOME

* DOMULS -- Moltiplicazione con segno a 16 bit.

* FUNZIONE

* Questo programma effettua la moltiplicazione con segno

* di due stringhe di 16 bit contenute in memoria; il risultato e` a 32 bit e *

viene posto anch'esso in memoria.

* INGRESSI

* A0 - Contiene l'indirizzo di memoria a 32 bit delle due

* stringhe di 16 bit, poste in memoria in locazioni adiacenti.

* A1 - Contiene l'indirizzo di memoria a 32 bit in cui siceglie di *

depositare il risultato della moltiplicazione.

* RISULTATO

* (A1) - Contiene il risultato della moltiplicazione.

* ESEMPIO

org $1000

FATTORI DS.W 2

RISULTATO DS.L 1

domul move.w (A0)+,D0 preleva dalla memoria il primo

* fattore da moltiplicare e punta

* al secondo fattore.

muls.w (A0),D0 Preleva il secondo fattore ed

* effettua la moltiplicazione.

move.l D0,(A1) Salva il risultato nella loc.

* di memoria ad esso destinata.

rts

INIZIO MOVEM.L D0/A0-A1,-(SP) Salva sullo stack il contenuto

* dei registri che servono per op.

MOVE.W #FATTORI,A0 Punta alle locazioni dei fattori da

moltiplicare MOVE.W #RISULTATO,A1 Punta alla locazione in cui memor. il

risultato BSR DOMUL Esegue la moltiplicazione.

MOVEM (SP)+,D0/A0-A1 Ripristina il contenuto prec. nei reg.

END INIZIO

2.135 MULU Unsigned multiply

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.136 MULU Unsigned multiply

1100 R 011 ea

dest=dest*sorg

X N Z V C

- * * 0 0

N=1 se il bit più significativo di dest è 1

Z=1 se dest=0

MULU <ea>,Dn

size: W

Esempio:

Il seguente sottoprogramma moltiplica due numeri da 16 bit contenuti nei

registri d1 e d2 e pone il risultato nei 32 bit di d3

mul movem.l d2-d4,-(sp) salva i registri

move.w d1,d3 d1L in d3

move.w d2,d4 d2L in d4

swap d1 d1H in d1

swap d2 d2H in d2

* crea i prodotti

mulu d3,d2 d2=d1L*d2H

mulu d4,d1 d1=d2L*d1H

mulu d4,d3 d3=d2L*d1L

* soma i termini incrociati

add.w d2,d1

* pone i termini incrociati nella cifra più alta del

* risultato swap d1

clr d1

* inserisce la cifra più bassa

add.l d3,d1

movem.l (sp)+,d2-d4 ripristina i

* registri usati

rts

2.137 MULU Unsigned multiply

1100 R 011 ea

(dest)*(source)-->dest

* * * * *

N=1 se l’MSB di dest

Z=1 se dest=0

V è sempre settato basso

C è sempre settato basso

X non viene influenzato

MULU <ea>,Dn

size: W

MULU esegue la moltiplicazione di due numeri

interi “unsigned” su 16 bit producendo un risulta-

to “unsigned” memorizzato su 32 bit.

A causa dell’ampiezza del campo in cui si salva

il risultato non si verifica mai overflow.

esempio

* Questo programma è una variante di quello pre-

* sentato a proposito del codice AND. In questo

* caso le maschere per I confronti vengono gene-

* rate moltiplicando per 2 iterativamente il con-

* tenuto di un registro inizialmente caricato con

* il valore 1

ORG $8000

NUM DC.B $F1 numero da processare

BEGIN CLR.B D3

MOVE.W #1,D1

LOOP MOVE.B (NUM),D0

AND D1,D0

BEQ NOADD se la AND è <>0

ADD #1,D3

NOADD MULU #2,D1 prepara prossima maschera

CMP #$0100,D1 il byte è finito?

BNE LOOP

END BEGIN

2.138 MULU Moltiplicazione senza segno

Esegue la moltiplicazione senza segno tra due operandi a 16 bit, il risultato è a 32 bit ed è

memorizzato in un registro dati.L’operazione è eseguita usando l’aritmetica senza segno, il registro

dati contiene (nei primi 16 bit) uno dei due fattori quando inizia l’operazione.

1100 R 011 ea

dest<=*dest x *sorg

X,N,Z,V,C

- * * 0 0

N=1 se MSB(*dest)=1

Z=1 se *dest=0

MULU <ea>,Dn

size: W

*Esempio di MULU

org $1000

*Effettua la moltiplicazione unsigned tra fattori a 32 bit

*il risultato è a 64 bit;i parametri sono passati tramite stack.

f1a equ 8

f1b equ 10

f2a equ 12

f2b equ 14

res equ 8

stato equ -2

mltip link a0,#-2

move.w sr,stato(a0)

move.w f1a(a0),d0

move.w f2a(a0),d1

mulu.w d1,d0 moltiplico le parti alte

move.w f1b(a0),d1

move.w f2b(a0),d2

mulu.w d2,d1 moltiplico parti basse

move.w f1a(a0),d2

move.w f2b(a0),d3

mulu.w d3,d2 p. alta di f1 * p. bassa di f2

move.w f1b(a0),d3

move.w f2a(a0),d4

mulu.w d4,d3 p. bassa di f1 * p. alta di f2

add.l d3,d2 sommo parti miste

move.l d2,d3

move.b #15,d5

roxr.l #1,d2 prendo i 16 bit + significativi

lsr.l d5,d2 per sommarli al prodotto delle p. alte

add.b #1,d5

lsl.l d5,d3 mentre i 16 bit - sign. li sommo al prod. delle p.

basse

add.l d3,d1

addx.l d2,d0

move.l d0,res(a0)

move.l d1,res+4(a0)

move.w sr,d0 setto i bit di flag

andi.b #$0c,d0

or.b stato(a0),d0

move.w d0,ccr

unlk a0

rts

start andi.w #$00ff,sr

move.w #$32fc,-(sp) 003212de*44de32fc

move.w #$44de,-(sp)

move.w #$12de,-(sp)

move.w #$0032,-(sp)

jsr mltip

end start

2.139 NBCD Negate decimal with extend

1101 R mode ea

dest=dest+sorg

* U ? U ?

C=prestito decimale

·...·¬R

Z=Z·¬R

m 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.140 NBCD Negate decimal with extend

0100100000 Ea -X

dest=0-(Dest)

10

X N Z V C

* U * U *

N è indefinito

Z è invariato se il risultato è zero, azzerato altrimenti

V è indefinito

C=1 se si è generato un riporto decimale di sottrazione, azzerato altrimenti

X=C

NBCD <Ea>

Size: B

esempio

*************************************************************************************

*PROGRAMMA DI PROVA DEL CODICE NBCD

*Il programma seguente mostra l'utilizzo del codice NBCD per realizzare la

*sottrazione OP1-OP2 in precisione multipla in aritmetica di decimali.

*L'algoritmo utilizzato è generico e consente di effettuare la sottrazione con

*operandi di lunghezza generica, specificabile tramite le variabili lung e

*definendo quindi opportunamente anche la lunghezza del risultato.

*

*N.B. L'eventuale riporto di sottrazione sarà il negato del flag C

* e in caso di risultato negativo sarà N=1

*************************************************************************************

*Area Programma a partire dalla locazione $8000

ORG $8000

START move.w sr,d0 legge il registro di stato

andi.w #$d8ff,d0 maschera per reg stato (stato utente, int abilitati)

move.w d0,sr pone liv int a 000

movea.l #$d300,sp

move.w lung,d0

lea strnd,a1

lea mnd,a2

movea.l #result,a3 a3 punta al LSB del risultato

adda.wlung,a1

adda.wlung,a2

subq #1,d0

move.w #$0010,-(sp) salva i codici di condizione sullo stack

ciclo move.w #$0010,ccr set X

nbcd -(a1)

move.b(a1),d1

move.b-(a2),d2

move (sp)+,ccr ripristina i codici di condizione del passo

precedente

abcd d1,d2 esegue la generica sottrazione x-y come x+(-y)

move sr,-(sp) salva i codici di condizione sullo stack

move.bd2,-(a3)

dbra d0,ciclo

move (sp)+,ccr ripristina i codici di condizione dell'ultima

operazione

*Area Dati a partire dalla locazione $8300

org $8300

strnd dc.l $12345678,$98765432

mnd dc.l $98765432,$12345678

res ds.b 8 lunghezza risultato = 8byte = 16 cifre

result equ *

lung dc.w 8 lunghezza operandi = 8byte = 16 cifre

END START

2.141 NBCD Negate Decimal with Extend

0100100000 ea

Destination=0-Destination-X

X N Z V C

* U * U *

Z : Z·¬Dm...·¬D0

C : Decimal borrow

X =C

NBCD <ea>

Size= B

ea - Specifica l’operando Destinazione

Sono concessi solo data alterable addressing modes

*

esempio

NEGD ORG $9500

*Questa subroutine nega un numero bcd di una data lunghezza.

*Essendo nbcd un operazione esclusivamente sul byte si suppone

*che il numero occupi in ogni caso un numero intero di byte (eventualmente

*si aggiungo zeri in testa).

*La lunghezza del numero è passata in D0 (è corrisponde al numero di cifre

*su cui esso è epresso diviso 2); l'indirizzo di partenza dell'operando è

*passato in A0.

ADDA.L D0,A0 il puntatore al dato viene spostato

* al suo byte meno significativo

SUBQ.L #1,D0 si tiene conto che il codice

* DBcc salta a 0 e non a 1

MOVE #$0004,CCR viene settato il bit zero resettati gli altri

ciclo NBCD -(A0)

DBEQ D0,CICLO

RTS

*Esempio di programma chiamante

MAIN ORG $9200

OP DC.B $40,$00,$00

VIA ANDI #$DFFF,SR passaggio a stato utente

LEA OP,A0

MOVEQ.L #3,D0

JSR NEGD

END VIA

NOTA: NBCD non opera correttamente sullo zero

*

2.142 NEG Negate

1101 R mode ea

dest=dest+sorg

* * * ? ?

·R , C=D +R

V=D

m m m m

V=D ·R , C=D +R

m m m m

Z=Z·¬R ·...·¬R ADD <ea>,Dn

m 0

ADD Dn,<ea>

size: B,W,L

esempio

2.143 NEG Negate

01000100 Size Ea

dest :=0-(dest)

X N Z V C

* * * * * ), azzerato altrimenti

N=1 se il risultato è negativo (N:=R

n

Z=1 se il risultato è zero, azzerato altrimenti

V=1 se si è generato un overflow, azzerato altrimenti

C=1 se si è generato un riporto di sottrazione, azzerato altrimenti

X=C

NEG <Ea>

Size: B,W,L

esempio

*************************************************************************************

*PROGRAMMA DI PROVA DEL CODICE DI NEGAZIONE NEG

*Il programma seguente mostra l'utilizzo del codice NEG per realizzare la

*sottrazione OP1-OP2 modulo 2^8 e modulo 2^16 mediante addizione modulo 2^8

*e 2^16 rispettivamente.

*************************************************************************************

*Area Programma a partire dalla locazione $8000

ORG $8000

START move.w sr,d0 legge il registro di stato

andi.w #$d8ff,d0 maschera per reg stato (stato utente, int abilitati)

move.w d0,sr pone liv int a 000

neg.b OP2b

move.bOP2b,d0

add.b d0,OP1b

neg.w OP2w

move.w OP2w,d1

add.w d1,OP1w

*Area Dati a partire dalla locazione $8300

org $8300

OP1b dc.b $85

OP2b dc.b $12

OP1w dc.w $9876

OP2w dc.w $5432

END START

2.144 NEG Negate

01000100 Size ea

dest=0-dest

X N Z V C

* * * ? ?

X è settato come C

N=1 se il risultato è negativo; 0 altrimenti

·R ,

V=D

m m

+R

C=D

m m

Z=Z·¬R ·...·¬R

m 0

NEGX <ea>

size: B,W,L

-ea specifica l’operando destinazione.Sono permessi solo i modi

di indirizzamento “data alterable”.

*

2.145 NEGX Negate with extend

1101 R mode ea

dest=dest+sorg

* * * ? ?

·R , C=D +R

V=D

m m m m

V=D ·R , C=D +R

m m m m

Z=Z·¬R ·...·¬R ADD <ea>,Dn

m 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.146 NEGX Negate with extend

01000000 Size Ea

dest :=0-(dest)-X

X N Z V C

* * * * * ) , azzerato altrimenti

N=1 se il risultato è negativo (N:=R

n

Z è invariato se il risultato è zero, azzerato altrimenti

V=1 se si è generato un overflow, azzerato altrimenti

C=1 se si è generato un riporto di sottrazione, azzerato altrimenti

X=C

NEG <Ea>

Size: B,W,L

esempio

*************************************************************************************

*PROGRAMMA DI PROVA DEL CODICE NEGX

*Il programma seguente mostra l'utilizzo del codice NEGX per realizzare la

*sottrazione OP1-OP2 per operandi di 64 bit. Il risultato è contenuto nei registri

*d2(long word più significativa) e d3(long word meno significativa).

*

*N.B. L'eventuale riporto di sottrazione sarà il negato del flag C e in caso di

* risultato negativo sarà N=1

*

*************************************************************************************

*Area Programma a partire dalla locazione $8000

ORG $8000

START move.w sr,d0 legge il registro di stato

andi.w #$d8ff,d0 maschera per reg stato (stato utente, int abilitati)

move.w d0,sr pone liv int a 000

movea.l #$d300,sp

move.w lung,d0

divs #4,d0

lea strnd,a1

lea mnd,a2

movea.l #result,a3 a3 punta al LSB del risultato

adda.wlung,a1

adda.wlung,a2

subq #1,d0

move.w #$0010,-(sp) salva i codici di condizione sullo stack

ciclo move.w #$0010,ccr set X

negx.l -(a1)

move.l (a1),d1

move.l -(a2),d2

move (sp)+,ccr ripristina i codici di condizione del passo

precedente

addx.l d1,d2 esegue la generica sottrazione x-y come x+(-y)

move sr,-(sp) salva i codici di condizione sullo stack

move.l d2,-(a3)

dbra d0,ciclo

move (sp)+,ccr ripristina i codici di condizione dell'ultima

operazione

*Area Dati a partire dalla locazione $8300

org $8300

mnd dc.l $02345678,$98765432

strnd dc.l $10000000,$12345678

res ds.l 2 lunghezza risultato = 8byte = 64bit

result equ *

lung dc.w 8 lunghezza operandi = 8byte = 64bit

END START

2.147 NEGX Negate with extend

01000000 size ea

dest=0-(dest)-X

X N Z V C

* * ? ? ?

X è settato come C

N=1 se il risultato è negativo; 0 altrimenti

·R

V=D

m m

C=D +R

m m

Z=Z·¬R ·...·¬R

m 0

NEGX <ea>

size: B,W,L

EA può essere solo un “Data alterable addressing mode”

*

esempio (NEG NEGX)

*Questa subroutine fornisce un esempio di utilizzo dei codici NEG e NEGX. *Essa nega un nu

espresso su D0 elementi di D1 word ciascuno.

*------------------------------------------------------------------------

*NOTA 1 : Prima della negazione in multipla precisione il flag Z deve

* esere 1. Dopo la negazione esso sarà 0 se il numero negato

* è diverso da zero.

*NOTA 2 : Dopo la negazione flag V=0 indica che il risultato è corretto.

* Se V=1 la negazione ha dato risultato errato. Ciò accade nel

* solo caso in cui il numero da negare è -(b**n)/2 ove

* b=2 e n è il numero di bit su cui è espresso il numero.

NEGMUL ORG $9200

MOVE D0,D2

SUBQ #2,D0 modifichiamo D0 per il suo uso nel ciclo FOR

MULU D1,D2

MULU #2,D2 ora D2 contiene il numero di byte su cui è espresso

* il numero da negare

MOVEA.L SP,A0 usiamo A0 come stack-pointer

ADD.L #DAT,A0 A0 punta al numero da negare

ADD.L D2,A0 A0 punta alla locazione successiva

* all'elemento meno significativo del numero

ORI #$04,CCR poniamo Z=1

NEG -(A0)

FOR NEGX -(A0)

DBF D0,FOR

FINE RTS

*Un esempio di programma chiamante di NEGMUL

MAIN ORG $9300

* numero da negare

NUM3 DC.W $FFFF elemento più significativo

NUM2 DC.W $FFFF "

NUM1 DC.W $FFFF "

NUM0 DC.W $FFFF elemento meno significativo

LEN DC.W 4 numero di elementi in cui è suddiviso il numero

SIZE DC.W 1 numero di word che compongono un elemento

DAT EQU 4 spiazzamento per la subrotine

VIA ANDI #$DFFF,SR passaggio a stato utente

MOVE SIZE,D1

MOVE LEN,D0

MOVE NUM0,-(SP) passiamo il numero da negare tramite lo stack

MOVE NUM1,-(SP)

MOVE NUM2,-(SP)

MOVE NUM3,-(SP)

JSR NEGMUL

END VIA

*

2.148 NOP No operation

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.149 NOP No operation

0100111001110001

No operation

X N Z V C

- - - - -

NOP

size: Unsized

esempio:

BLOCCO1: .

.

.

JMP BLOCCO3

BLOCCO2: .

.

.

BLOCCO3: NOP

END

2.150 NOP No Operation

0100111001110001

X N Z V C

- - - - -

Tutti i flag sono not affected

NOP

Unsized

*

esempio

2.151 NOT Logical complement

1101 R mode ea

dest=dest+sorg

- * * 0 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.152 NOT Logical complement

01000110 Size Ea

dest=-(dest)

X N Z V C

- * * 0 0

N=1 se il risultato è negativo, azzerato altrimenti

Z=1 se il risultato è zero, azzerato altrimenti

V è sempre azzerato

C è sempre azzerato

X è invariato

NOT <Ea>

Size: B,W,L

esempio

2.153 NOT Logical complement

01000110 Size ea

dest=not(dest)

X N Z V C

- * * 0 0

NOT <ea>

size: B,W,L

-ea specifica l’operando destinazione.Sono permessi solo i modi

di indirizzamento “data alterable”.

*

esempio

*Questa routine simula un semisottrattore realizzato tramite un *semiaddizionatore.Essa cos

esempio di prova del codice NOT.

*Gli operandi sono passati in D0 (minuendo) e D1 (sottraendo).

*Il risultato e restituito in D1.

*Il numero di bit della aritmetica (8,16,32) è passato nei flag V C :

* V C NBIT

* 1 - 16

* 0 1 8

* 0 0 32

*I flag restituiti al programma chiamante sono coerenti con quelli forniti

*dal codice SUB del 68000

HALF_SUB ORG $8000

BVS WRD

BCS BYT

*LONG CMP.L #0,D1 nel caso in cui il sottraendo è 0

BEQ ADDL half_sub ed half_add sono equivalenti

NOT.L D1 complemento a (b^n)-1 del sottraendo

ADD.L #1,D1 complemento a b^n " "

ADDL ADD.L D0,D1 sottrazione

BRA SFL

WRD CMP.W #0,D1

BEQ ADDW

NOT.W D1

ADD.W #1,D1

ADDW ADD.W D0,D1

BRA SFL

BYT CMP.B #0,D1

BEQ ADDB

NOT.B D1

ADD.B #1,D1

ADDB ADD.B D0,D1

*I bit Z,N ed O non hanno bisogno di correzioni

*Il resto del sottrattore è uguale al negato di

quello dell'addizionatore; (X=C)

SFL BCS CX1 se C e X sono 0

ORI #$11,CCR vengono messi ad 1

BRA FINE se sono 1

CX1 ANDI #$EE,CCR vengono messi a 0

FINE RTS

*Esempio di programma chiamante

MAIN ORG $8200

ANDI #$DFFF,SR passaggio a stato utente

*Chiamata per Size=byte

MOVE.B #$33,D0

MOVE.B #$32,D1

ORI #$01,CCR

JSR HALF_SUB

*Chiamata per Size=Word

MOVE.W #$3333,D0

MOVE.W #$3334,D1

ORI #$02,CCR

JSR HALF_SUB

*Chiamata per Size=Long

MOVE.L #$10000000,D0

MOVE.L #$00000001,D1

ANDI #$F6,CCR

JSR HALF_SUB

END MAIN

NOTA:

E’ stato riscontrato un errore di ASIM nel settaggio del bit

di overflow della addizione (vedi chiamata per Size=Long)

*

2.154 OR Inclusive or logical

1101 R mode ea

dest=dest+sorg

- * * 0 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

OR Inclusive or logical

1000 REG op-mode ea

SORG or DEST -->DEST

- * * 0 0

N=1 se il bit più significativo del risultato è 1

Z=1 se il risultato è nullo

OR <ea>,Dn

OR Dn,<ea>

size: B,W,L

esempio :

* Questo programma compatta due word in una long-word *

* mettendo la prima word nella parte alta della long-word e la *

* seconda nella parte bassa. Seconda versione. *

* E' un esempio di utilizzo della OR . *

* Elaborazione: Gruppo 10 - 96/97

ORG $8000

B1 EQU $EFA1

B2 EQU $9F6C

START move.w #b1,d1

move.w #b2,d2

swap d1 * sposta la word nella parte alta del registro d1

or.l d2,d1

END START

2.155 OR Inclusive or logical

1000 R OpMode EffAddr

dest=dest OR sorg

- * * 0 0

OR <ea>,Dn

OR Dn,<ea>

size: B,W,L

2.156 ORI Inclusive or immediate

1101 R mode ea

dest=dest+sorg

- * * 0 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.157 ORI Inclusive or immediate

00000000 size ea + 1,2 ext word

dest dest + sorg

X,N,Z,V,C

- * * 0 0

N=1 se MSB(*dest)=1

Z=1 se *dest=0

ORI #<data>,<ea>

size: B,W,L

Modi di indirizzamento non permessi :

- diretto con registro indirizzo

- relativo

- relativo indicizzato

- immediato

esempio :

* Tale segmento di programma consente di settare il bit più significativo

degli

* elementi di posto pari o dispari di un vettore di long word .

* D7 deve contenere il bit di controllo per determinare i posti dispari o

pari .

* org $8000

INIZIO move.l #VETINI,A0 carica A0 per indirizzare gli elementi del

vettore

btst.l #0,D7 testa il bit meno significativo del registro

beq.s PARI se il bit è 0 si opera sugli elementi di posto pari

DISPARI moveq.l #1,D0 D0 ha l'indice del primo elemento di

posto dispari

bra.s LOOP

PARI moveq.l #0,D0 D0 ha l'indice del primo elemento di

posto pari

LOOP cmp.b NUMEL,D0 controlla se sono esauriti gli elementi del

vettore

bge.s FINE

move.l D0,D1

mulu.w #4,D1 D1 contiene lo spiazzamento dell'elemento da settare

move.l 0(A0,D1),D2

ori.l #$80000000,D2 effettua il settaggio del bit più significativo

move.l D2,0(A0,D1) aggiorna il vettore in memoria

addq.l #2,D0 aggiorna l'indice dell'elemento

bra.s LOOP

*

VETINI org $8040 indirizzo del primo elemento del vettore

VETTORE dc.l $004531A0,$0103F34A,$0005E781,$120056BC,$D4C6F002

NUMEL dc.b 5 numero degli elementi del vettore

*

FINE nop

END INIZIO

2.158 PEA Push effective address

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.159 PEA Push effective address

0100100001 Ea

-(SP)=dest

X N Z V C

- - - - -

Nessun flag di CC viene modificato

PEA <Ea>

Size: L

esempio

*LE SEGUENTI LINEE MOSTRANO L'UTILIZZO DEL CODICE PEA

*TALE CODICE RISULTA UTILE NEL PASSAGGIO DEI PARAMETRI PER

*INDIRIZZO, COME NEL CASO DEGLI ARRAY, QUANDO I PARAMETRI SONO

*SCAMBIATI TRAMITE STACK.PUO' ESSERE USATO IN COMBINAZIONE

*CON I CODICI LINK ED UNLK

*ESEMPIO:INIZIALIZZAZIONE DI UN ARRAY DI WORD

*L'ARRAY E' SCAMBIATO PER INDIRIZZO TRAMITE STK

org $8500 *area dati

frst equ 1

last equ 5

size equ 2

vect ds.b ((last-frst+1)*size)

eavect equ vect-(frst*size)

org $9000 *area stk

stk ds.w 40

stke equ *

org $8100 *area subroutine

init link a6,#0

move.l par(a6),a1

move.l #frst,d0

iloop move.l d0,d2

mulu.w #size,d2

move.l d2,a2

add.l a1,a2

move.w #0,(a2)

add.w #1,d0

cmpi.l #last,d0

ble iloop

unlk a6

par equ 8

rts

org $8300 *area codice

start andi.w #$DFFF,sr

move.l #stke,sp

move.l sp,a6

move.l #eavect,a0

pea (a0)

jsr init

end start

2.160 PEA Push effective address

0100100001ea

SP@-=Destinazione

X N Z V C

- - - - -

Tutti i flag sono not affected

PEA <ea>

Size= L

ea - Specifica l’indirizzo che deve essere messo in testa allo stack

Sono concessi solo control addressing modes

*

esempio

2.161 RESET Reset external devices

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.162 RESET Reset External Device

0100111001110000

RESET

X N Z V C

- - - - -

X N Z V C,=Not affected

size:

Esempio

2.163 RESET Reset External Devices

0100111001110000

X N Z V C

- - - - -

Tutti i flag sono not affected

RESET

Unsized

*

esempio

2.164 ROL Rotate left without extend

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.165 ROR Rotate rigth without extend

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.166 ROR Rotate rigth without extend

1110 count|Reg 0 size i/r 11 R (Register Shifts)

dest = dest >> count

1110 011 011 ea (Memory Shifts)

M[ea] = M[ea] >> 1

X,N,Z,V,C

- * * 0 ?

C= D

count-1

X,N,Z,V,C ( count == 0 )

- * * 0 0

ROR Dx,Dy

ROR #<data>,Dy

ROR <ea>

size: B,W,L ( Register Shifts )

size: W ( Memory Shifts )

esempio

ORG $8000

* Esempio di utilizzo dell'istruzione ROR ( ROtate Right )

* Si mostra come sia possibile implementare l'operazione di mol-

* tiplicazione, unsigned, di operandi a 16 bit con risultato a 32

* bit utilizzando operazioni ai ADD di ROR e di LSR.

* L'esempio è strutturato come subroutine che effettua l'operazio-* ne

desiderata, a questo proposito si assume che in D0, nei 16 * LSBs vi sia il

moltiplicando e che in D1, nei 16 LSBs, vi sia il * moltiplicatore.

* La routine restituisce in D2 il risultato dell'operazione, *

modificando consistentemente i vari FLAG.

* Per un descrizione dell'algoritomo vedi Wakerly pag.

start

MOVE.W #$1234,d0

MOVE.W #$1234,d1

jsr MULTIPLY

MOVE.W #$FF34,d0

MOVE.W #$F234,d1

jsr MULTIPLY

STOP #$80

MULTIPLY

MOVE.L d3,-(a7) Salvataggio sullo stack di D3

* utilizziamo il size L perché nell'attuale implementazione DBF * che

decrementa il registro D3 lo decrementa a 32 bit => se uti- * lizzassimo il

size B o W senza "pulire" la parte restante del * registro il ciclo

potrebbe non effettuare il numero di iterazio-* ni previsto

MOVE.L #15,d3 D3 = loop count

MOVE.L #0,d2 Inizializzazione D2 = risultato parziale

FOR BTST.L #0,d0 testa il LSB del moltiplicando shiftato

BEQ NOADD

ADD.W D1,D2 somma il moltiplicando shiftato al

* risultato parziale

BCS CARSET

* il LSB del moltiplicatore shiftato era nullo

NOADD ROR.L #1,d2 * shift a destra del risultato

* parziale e salvataggio del suo

BRA LAB1 * LSB nel MSB di D2

CARSET * l'addizione ha generato carry

ROR.L #1,d2 * shift a destra del risultato parziale e

* salvataggio del suo LSB nel MSB di D2

* BSET.L #31,D2 istruzione non funzionante per cui usiamo

OR.W #$8000,d2 pone il MSB del prodotto parziale ad 1

LAB1 LSR.W #1,d0 Shift a destra del moltiplicatore

DBF d3,FOR

MOVE.L (a7)+,d3 Ripristino di D3

SWAP.W d2 Correzione del risultato

RTS

end start

2.167 ROXL Rotate left with extend

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.168 ROXL Rotate left with extend

1110 count|Reg 1 size i/r 10 R (Register Shifts)

1110 010 111 ea (Memory Shifts)

X,N,Z,V,C

* * * 0 ?

C= D

m-count+1

X,N,Z,V,C ( count == 0 )

- * * 0 ?

C= X

ROXL Dx,Dy

ROXL #<data>,Dy

ROXL <ea>

size: B,W,L ( Register Shifts )

size: W ( Memory Shifts )

* Esempio di utilizzo dell'istruzione ROXL ( ROtate with X Left )

* Si mostra come sia possibile implementare l'istruzione ROL per

* operandi di dimensionioni maggiori di una LONGWORD (LW).

* L'esempio è strutturato come subroutine che effettua l'operazio-* ne

desiderata, a questo proposito si assume che il dato su cui

* effettuare il ROL sia di 64-bit memorizzato in D0-D1 ( D0 LW

* più significativa ).

* Viene mostrato come effettuare il ROL di 1 bit e poi tale

* operazione viene utilizzata per effettuare il ROL di più bit

ORG $8000

start

* operazione di ROL generica

MOVE.l #$2AAAAAAF,d0 d0 = 00101010101010101010101010101111

MOVE.l #$7D6A80AF,d1 d1 = 01111101011010101000000010101111

JSR ROL1M

* questi dati servono per verificare la corretta modifica di Z

MOVE.l #$80000000,d0 d0 = 10000000000000000000000000000000

MOVE.l #$00000000,d1 d1 = 00000000000000000000000000000000

JSR ROL1M

MOVE.l #$00000000,d0 d0 = 00000000000000000000000000000000

MOVE.l #$01000000,d1 d1 = 00000001000000000000000000000000

JSR ROL1M

STOP #$80

ROL1M

LSL.L #1,d1 X = C = ex D1[31]

BEQ ZERO Salta se la prima LW è = 0

* La prima LW è risultata essere non nulla

ROXL.L #1,d0 X = C = ex D0[31]

BCC.S END1 salta se C = 0

BSET #0,d1 D1[0] = C = 1

END1 ANDI.B #$FB,CCR Z = 0 La prima LW era != 0

BRA.S ENDROL1M

* La prima LW del dato è risultata essere nulla

ZERO ROXL.L #1,d0 X = C = ex D0[31]

BCC.S ENDROL1M salta se C = 0

BSET #0,d1 D1[0] = C = 1

* a questo punto bisogna modificare il flag Z in modo consistente * con la

dimensione del dato: infatti le singole operazioni di LSL * e ROXL modificano

i flag in modo consistente con le dimensioni * BYTE WORD e LW, mentre noi

stiamo operando su un dato di 2 LW;

* i flag X C V N risultano già modificati correttamente per il * dato

a 64 bit,mentre il flag Z potrebbe dare un'informazione * sbagliata in

quanto esso indica solo se D0, cioè parte del dato, * è nullo. Un modo

semplice per settare correttamente Z è l’ag- * giunta

dell'istruzione

ANDI.B #$FB,CCR Z = 0

* in quanto se in D1[0] entra 1 certamente il numero è !=0

ENDROL1M

RTS

END START

2.169 ROXR Rotate rigth with extend

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.170 ROXR Rotate rigth with extend

1110 count|Reg 0 size i/r 10 R (Register Shifts)

1110 010 011 ea (Memory Shifts)

X,N,Z,V,C

* * * 0 ?

C= D

count-1

X,N,Z,V,C ( counto == 0 )

- * * 0 ?

C= X

ROXR Dx,Dy

ROXR #<data>,Dy

ROXR <ea>

size: B,W,L ( Register Shifts )

size: W ( Memory Shifts )

* Esempio di utilizzo dell'istruzione ROXR ( ROtate with X Right )

* Si mostra come sia possibile implementare l'istruzione ROR per

* operandi di dimensioni maggiori di una LONGWORD (LW).

* L'esempio è strutturato come subroutine che effettua l'operazio-* ne

desiderata, a questo proposito si assume che il dato su cui

* effettuare il ROL sia di 64-bit memorizzato in D0-D1 ( D0 LW

* più significativa ).

* Viene mostrato come effettuare il ROR di 1 bit.

ORG $8000

start

* operazione di ROR generica

MOVE.l #$2AAAAAAF,d0 d0 = 00101010101010101010101010101111

MOVE.l #$7D6A80AF,d1 d1 = 01111101011010101000000010101111

JSR ROR1M

* questi dati servono per verificare la corretta modifica di Z

MOVE.l #$00000000,d0 d0 = 10000000000000000000000000000000

MOVE.l #$00000001,d1 d1 = 00000000000000000000000000000000

JSR ROR1M

MOVE.l #$01000000,d0 d0 = 00000000000000000000000000000000

MOVE.l #$00000000,d1 d1 = 00000001000000000000000000000000

JSR ROR1M

STOP #$80

ROR1M

LSR.L #1,d1 X = C = ex D1[0]

BEQ ZEROR Salta se la prima LW è = 0

* La prima LW è risultata essere non nulla

ROXR.L #1,d0 X = C = ex D0[0]

BCC.S ENDR salta se C = 0

BSET.L #31,d1 D1[31] = C = 1

ENDR ANDI.B #$FB,CCR Z = 0 La prima LW era != 0

BRA.S ENDROR1M

* La prima LW del dato è risultata essere nulla

ZEROR ROXR.L #1,d1 X = C = ex D0[31]

BCC.S ENDROR1M salta se C = 0

BSET #31,d1 D1[31] = C = 1

* a questo punto bisogna modificare il flag Z in modo consistente * con la

dimensione del dato: infatti le singole operazioni di LSL * e ROXL modificano

i flag in modo consistente con le dimensioni * BYTE WORD e LW, mentre

noi stiamo operando su un dato di 2 LW;

* i flag X C V N risultano già modificati correttamente per il * dato a

64 bit, mentre il flag Z potrebbe dare un'informazione * sbagliata in

quanto esso indica solo se D0, cioè parte del dato, * è nullo. Un modo

semplice per settare correttamente Z è l’ag- * giunta dell'istruzione

ANDI.B #$FB,CCR Z = 0

* in quanto se in D1[31] entra 1 certamente il numero è != 0

ENDROR1M

rts

END start

2.171 RTE Return from exception

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.172 RTE Return from Exception

0100111001110011

SP@+=>SR

SP@+=>PC

X N Z V C

* * * * *

X N Z V C - modificati a secondo del contenuto della word sullo stack

RTE

size: Unsized

esempio:Vedi l’esempio del codice Trap

2.173 RTE Return from Exception - privileged instruction

0100111001110011

SP@+ -> SR

SP@+ -> PC

X N Z V C

* * * * *

X,N,Z,V,C : set according to the content of the word on the stack

esempio

Usato in più esempi.

2.174 RTR Return and restore condition codes

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.175 RTR Return and Restore Condition Code

0100111001110111

SP@+=>CC

SP@+=>PC

RTR

X N Z V C

* * * * *

X,N,Z,C,V - Settati In Funzione Dell’operando

size: Unsized

esempio

2.176 RTR Return and Restore Condition Codes

0100111001110111

CC=SP@+ ; PC=SP@+

X N Z V C

* * * * *

Tutti i flag sono accordati secondo il contenuto della word

nello stack

RTR

Unsized

*

esempio

2.177 RTS Return from subroutine

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.178 RTS Return from Subroutine

0100111001110101

SP@+=>PC

X N Z V C

- - - - -

RTS

size: Unsized

esempio:Vedi l’esempio del codice CHK

2.179 RTS Return from Subroutine

0100111001110101

SP@+ -> PC

X N Z V C

- - - - -

Tutti i flag sono not affected

RTS

Unsized

*

esempio

Usato in più esempi.

2.180 SBCD Subtract decimal with extend

1101 R mode ea

dest=dest+sorg

* U ? U ?

C=prestito decimale

·...·¬R

Z=Z·¬R

m 0

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.181 SBCD Subtract decimal with extend

1000 Rx 10000 R/M Ry

dest=dest-sorg

* U * U *

X=settato come il carry

Z=0 se il risultato e’ diverso da 0. Altrimenti resta invariato.

C=1 se si verifica il borrow (decimale). Altrimenti e’ 0.

SBCD Dy,Dx

SBCD -(Ay),-(Ax)

size: B

esempio

* Il programma esegue una DIVU in BCD tra due numeri (codificati in BCD)

* aventi la stessa dimensione (in byte), utilizzando il codice operativo SBCD

* con operandi del tipo indirizzo predecrementato.

* Il quoto è memorizzato nel registro D2 ed il resto (sempre BCD)

* e’ nel registro D3.

* Il controllo di fine ciclo viene realizzato ispezionando il flag X (=C)

* per vedere se il resto è negativo in seguito ad un CPMI con lo zero.

* Elaborazione: Gruppo 10 - 96/97.

*Area Programma a partire dalla locazione $8000

ORG $8000

START MOVEQ #0,D2 Inizializza il quoto in D2

INIT MOVE.L (A0),D3 Inizializza il resto in D3

MOVE.L #FOP1,A0 In A0 indirizzo base 1^ addendo

MOVE.L #FOP2,A1 In A1 indirizzo base 2^ addendo

MOVE.L #DIST,D1 In D1 il valore della var. di cont. del ciclo SBCD

LOOP SBCD -(A1),-(A0) Una sottrazione BCD per ogni coppia di

nibble

DBEQ D1,LOOP

MOVE.W SR,D4 Sposta SR in D4 per fare il controllo con la maschera

CMP #$2711,D4 Controllo con la maschera

BEQ FINE

ADDI #1,D2 In D2 il conto dei cicli per DIV, e cioè il quoto

BRA INIT Deve effettuare ancora almeno una SBCD

FINE STOP #$2000 Istruzione illecita in quanto privilegiata. Serve

* per fermare l'esecuzione del programma.

*----------------------------------------------------------------------------

*

*Area Dati a partire dalla locazione $8032

ORG $8032

OP1 DC.B $96,$22,$00,$17 Definizione del dividendo

FOP1 EQU * Fine 1^operando

OP2 DC.B $17,$99,$41,$44 Definizione del divisore

FOP2 EQU * Fine 2^operando

DIST EQU FOP2-FOP1-1 Calcolo del numero di cifre del divisore

END START

2.182 SBCD Subtract decimal with extend

1000 Rx 10000 R/M Ry

dest=dest-sorg

* U ? U ?

C=prestito decimale

·...·¬R

Z=Z·¬R

m 0

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

SBCD Dn,Dn

SBCD -(An),-(An)

size: B

Esempio bcdbin.a68

:

* Utilizzo del codice operativo: SBCD

* Conversione di un numero di due cifre BCD in Binario.

* Incrementa il registro D2, che conterrà il risultato, ogni volta

* che viene decramentato di uno il numero da convertire.

* ORG $8200

UNO EQU 1

NUM EQU $25 Numero da convertire

START MOVEQ #UNO,D0

MOVEQ #NUM,D1

CLR D2 Azzera contatore

LOOP SBCD D0,D1

ADDQ #UNO,D2

CMP #0,D1

BNE LOOP

STOP #$2000

END START

2.183 Scc Set according to condition

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.184 SCC Set according to condition

0101 Condition 11 ea

if cc then 1’s=>dest else 0’s => dest

X N Z V C

- - - - -

Scc <ea>

size: B

ESEMPIO

Questa sobroutine effettua l'estenzione in segno su due byte di un

dato caricato nel byte piu' basso di una word puntata da A0

ORG $8000 Indirizzo di partenza

ESSCC MOVE.W 1(A0),D0 Carica byte basso dato

BTST #7,D0 Controlla il segno del dato

SNE (A0) Estendi in segno

RTS

ORG $9000 Area Dati

BUFFER DC.W 128

MAIN

LEA.L BUFFER,A0 Carica in A0 l'indirizzo dato

JSR ESSCC Salto a sottoprogramma

END MAIN

S Poni byte a 1 su condizione

CC Con Effective

ditio Address

n

Scc <ea>

operazione effettuata : if cc then poni a 1 destinazione else poni a zero destinazione.

Consentito il solo size di byte.

Non sortisce alcun effetto sul CCR (bit di flag).

Condizioni implementate : Test su Test

su ¬C C | Z

0100 - 0011 -

C (N&

0101 - 1101 -

Z N

0111 - 1011 - ¬Z

0001 - 0110 - Not

(N&V) | (¬N&¬V) ¬N

1100 - 1010 -

(N&V&¬Z)|(¬N&

1110 - 0000 -

¬C&¬Z ¬V

0010 - High 1000 -

Z|(N&¬V)|(¬N&V V

1111 - Less 1001 -

Questa istuzione verifica i valori dei bit di stato : se la condizione è soddisfatta il byte

destinazione viene caricato con $FF, altrimenti lo stesso byte viene azzerato.

L’istruzione Scc è particolarmente utile per memorizzare lo stato di un particolare codice

condizione in attesa di verificarlo in seguito

2.185 STOP Load status register and stop

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.186 STOP Load Status Register and Stop

1100111001110010 Immediate data

Immediate data =>SR

STOP

X N Z V C

* * * * *

X N Z V C - Modificati a secondo dell’operando

size: unsized

esempio

2.187 STOP Load Status Register and Stop- privileged instruction

0100111001110010

<Immediate Data>

Immediate Data -> SR; STOP

X N Z V C

* * * * *

X,N,Z,V,C : set according to the immediate operand

Imm. Field: Specifica il dato da caricare nel registro di stato

*

esempio

2.188 SUB Subtract binary

1101 R mode ea

dest=dest+sorg

* * * ? ?

·D ·¬R +S ·¬D ·R

V=¬S

m m m m m m

C=S ·¬D +R ·¬D +S ·R

m m m m m m

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.189 SUB Subtract binary

1001 R opmode ea

dest=dest-sorg

* * * * *

X=settato come il carry

N=1 se il risultato e’ negativo. Nullo altrimenti.

Z=1 se il risultato e’ nullo. Nullo altrimenti.

V=1 se e’ generato OVERFLOW. Nullo altrimenti.

C=1 se e’ generato un BORROW. Nullo altrimenti.

SUB <ea>,Dn

SUB Dn,<ea>

size: B,W,L

esempio *** VEDI ESEMPI ISTRUZIONI: DIVS & DIVU ***

2.190 SUB Subtract binary

1001 R OpMode EffAddr

dest=dest-sorg

* * * ? ?

·D ·¬R +S ·¬D ·R

V=¬S

m m m m m m

C=S ·¬D +R ·¬D +S ·R

m m m m m m

SUB <ea>,Dn

SUB Dn,<ea>

size: B,W,L

Esempio restr.a68

:

* Utilizzo dei codici operativi:MOVEQ e SUB

* Restoring: effettua la divisione mediante sottrazioni successive.

* Esegue D0/D1: 25/3

* ORG $8000

DVD EQU 25

DVS EQU 3

START MOVEQ #0,D2 Azzera il registro D2 che funge da contatore.

MOVEQ #DVD,D0 D0 è il dividendo

MOVEQ #DVS,D1 D1 è il divisore

INIZIO CMPD1,D0 Confronto D1 e D0 e salto a FINE se dovessi

effettuare

* una divisione illecita (DVS>DVD), oppure se ho

finito.

BLT FINE

SUB.L D1,D0 Il registro D0 alla fine conterrà il resto.

ADDQ.L #1,D2 Il registro D2 alla fine conterrà il quoto.

JMP INIZIO

FINE NOP No operation nel caso in cui DVS>DVD, oppure

se ho * finito di sottrarre.

STOP #$2000

END START

2.191 SUBA Subtract address

1101 R mode ea

dest=dest+sorg

* * * * *

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

C,X=1 se si genera riporto (decimale)

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.192 SUBI Subtract immediate

1101 R mode ea

dest=dest+sorg

* * * ? ?

·D ·¬R +S ·¬D ·R

V=¬S

m m m m m m

C=S ·¬D +R ·¬D +S ·R

m m m m m m

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.193 SUBI Subtract immediate

00000100 size ea + 1,2 ext word

dest *dest-imm

X,N,Z,V,C

* * * ? ?

V=¬S ·D ·¬R +S ·¬D ·R

m m m m m m

C=S ·¬D +R ·¬D +S ·R

m m m m m m

SUBI #<imm>,<ea>

size: B,W,L

Modi di indirizzamento non permessi :

- Immediate

- Relative

- Relative indexed

esempio :

* Questo segmento di programma estrae una colonna da una matrice di

long word e * la trasferisce in una certa area di memoria con

l'ordine invertito per gli * elementi.

* D0 contiene l'indice della colonna e A1 contiene l'indirizzo di

partenza dell' * area di memoria in cui deve essere trasferita la

colonna.

* org $8000

START subq.l #1,D0 individua l'indirizzo di partenza

mulu.w #4,D0 dell' ultimo elemento della colonna

addi.l #TABINI+3*16,D0 selezionata;

moveq.l #3,D1 inizializza il contatore;

LOOP move.l D0,A0 per utilizzare l'indirizzamento

indiretto;

move.l (A0),(A1)+ trasferisce l'elemento e aggiorna il

puntatore;

subi.l #16,D0 seleziona il successivo elemento della

colonna;

dbf D1,LOOP

*

TABINI org $8020 inizializza l'area della tabella

*

RIGA1 dc.l $004531A0,$0103F34A,$0005E781,$120056BC

RIGA2 dc.l $17C3B001,$A9D361C0,$01050641,$F20D501C

RIGA3 dc.l $1045F380,$D010520A,$0005E000,$AB00D12C

RIGA4 dc.l $030581A0,$0AB3F51A,$0503D081,$1263A0BC

end START

2.194 Note:

- Il modo di indirizzamento ‘Address-direct-register’ non è permesso,

contrariamente a quanto è scritto sia sul manuale ( ‘Only data

alterable addressing modes are allowed’) sia sul Wakerly (‘a_dst’).

2.195 SUBQ Subtract quick

1101 R mode ea

dest=dest+sorg

* * * ? ?

·D ·¬R +S ·¬D ·R

V=¬S

m m m m m m

C=S ·¬D +R ·¬D +S ·R

m m m m m m

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.196 SUBQ Subtract quick

0101 data 1 size ea

dest<=*dest-sorg

X N Z V C

* * * ? ?

·D ·¬R +S ·¬D ·R

V=¬S

m m m m m m

C=S ·¬D +R ·¬D +S ·R

m m m m m m

SUBQ #data,<ea>

size: B,W,L

ESEMPIO

Questa subroutine permette il calcolo dei bit alti di un dato passato

in D0,restituisce il risultato in d1.

ORG $8000 indirizzo di partenza

ESSUBQ MOVE.L #32,D0 Inizializza a 32 d1

MOVE.L #32,D2 Inizializza il contatore

LAB1 ROL #1,D0 Shifta a sinista D0

BSC LAB2 Controlla il primo bit di D0

SUBQ #1,D1

LAB2 SUBQ #1,D2

BNE LAB1

RTS Ritorno al chiamante

MAIN MOVE.L #$10000003,D0 Metti in D0 il dato

JSR ESSUBQ Salto a sottoprogramma

END MAIN

SUBQ Sottrazione

D Effective

a Address

t

a

SUBQ #<data>,<ea>

Sottrae al valore contenuto in dst un valore immediato compreso tra 1 ed 8. La destinazione

può essere un indirizzo effettivo alterabile. Sono permessi i size BWL tranne che per gli An

dove non è permesso utilizzare il size Byte.

X N Z V C

* * * ? ?

X è settato allo stesso modo di C Sm bit più significativo del sorgente

N è settato se il risultato è negativo Dm bit più significativo della

destinazione

Z è settato se il risultato è zero Rm bit più significativo del risultato

·D ·¬R +S ·¬D ·R

V = ¬S

m m m m m m

C = S ·¬D +R ·¬D +S ·R

m m m m m m

L’istruzione SUBQ torna utile laddove serve decrementare un puntatore ad una word (2 unità) o

ad una long word (4 unità).

Differenze con SUBI: è più corta ed è ad essa preferita quando si ha a che fare con parole in

doppia precisione ; può usare un An come destinazione ed, in tal caso, si comporta come un

SUBA con un dato immediato (sono consentite come dimensioni, in questo caso, soltanto W e

L e i bit di stato restano intatti).

2.197 SUBX Subtract with extend

1101 R mode ea

dest=dest+sorg

* * ? ? ?

·D ·¬R +S ·¬D ·R

V=¬S

m m m m m m

C=S ·¬D +R ·¬D +S ·R

m m m m m m

Z=Z·¬R ·...·¬R

m 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.198 SUBX Subtract with extend

1001 Rx 1 size 00 R/M Ry

dest=dest-sorg-x

* * * * *

X=settato come il carry

N=1 se il risultato e’ negativo. Nullo altrimenti.

Z=1 se il risultato e’ nullo. Inalterato altrimenti.

V=1 se e’ generato OVERFLOW. Nullo altrimenti.

C=1 se e’ generato un riporto. Nullo altrimenti.

SUBX Dx,Dy

SUBX -(Ay),-(Ax)

size: B,W,L

esempio

* Esempio d'uso di SUBX per la sottrazione in multiprecisione TOT=num0-num1

* num0 = 3.459.327.408.245.962.467 e quindi occupa due longword, cosi' come

* num1 = 1.153.390.864.253.429.473

* Il risultato, solo per una verifica veloce anche dei bit di flag,

* e' salvato anche nei registri D0,D4

* NB: Data la scelta precisa dei due numeri num0 e num1,

* si verifichera' il BORROW durante la SUBX.

* Di conseguenza la parte LOW del risultato sara' un num negativo.

* E' quindi logico che spostando tale parte nel registro D4,

* verra' settato il bit N dell'SR.

* Elaborazione: Gruppo 10 - 96/97

ORG $8000 *

START MOVEA.L #0,A0 * AZZERA IL REGISTO A0

MOVEA.L A0,A1 * AZZERA IL REGISTRO A1

NUM0H EQU $3001FFF3 * SPLITTA L'INTERO NUMERO IN DUE LONGW: NUM0H

(HIGH)

NUM0L EQU $1245F6E3 * E NUM0L (LOW)

NUM1H EQU $1001AAE1 * STESSA OPERAZIONE PER NUM1

NUM1L EQU $4F01A6E1

N0 DS.L 2 * RISERVA LO SPAZIO PER ALLOCARE IN MEMORIA I DUE NUMERI

N1 DS.L 2

MOVE.L #NUM0H,N1 * PONE NUM0H IN MEMORIA

MOVE.L #NUM0L,N1+4 * PONE NUM0L IN MEMORIA, DOPO NUM0H

* (QUINDI 4 BYTES DOPO NUM0H)

MOVE.L #NUM1H,N0 * STESSA OPERAZIONE PER NUM2

MOVE.L #NUM1L,N0+4 *

LEA.L N1+8,A0 * CARICA IN A0 L'INDIRIZZO DI NUM0

LEA.L N0+8,A1 * CARICA IN A1 L'INDIRIZZO DI NUM1

MOVE.W #0,CCR * AZZERA LO SR

SUBX.L -(A1),-(A0) * EFFETTUA LA SOTTRAZIONE TRA NUM0L E NUM1L

* IN MODO PREDECREMENTATO

SUBX.L -(A1),-(A0) * SOTTRAE LE PARTI HIGH DEI DUE NUMERI COMPRESO

* L'EVENTUARE BORROW DELLA SOTTRAZIONE

PRECEDENTE

MOVE.L (A0)+,D0 * PONE LA PARTE HIGH DEL RISULTATO IN D0

MOVE.L (A0)+,D4 * PONE LA PARTE LOW DEL RISULTATO IN D4

* (N=1 SE C'E' STATO BORROW)

END START * FINE.

2.199 SUBX Subtract with extend

1001 Rdest 1 Size 00 R/M Rsrc

dest=dest-sorg-X

* * ? ? ?

·D ·¬R +S ·¬D ·R

V=¬S

m m m m m m

C=S ·¬D +R ·¬D +S ·R

m m m m m m

Z=Z·¬R ·...·¬R

m 0

SUBX Dy,Dx

SUBX -(Ay),-(Ax)

size: B,W,L

Esempio subx.a68

:

*Utilizzo del codice operativo:SUBX

*Il programma seguente mostra l'utilizzo del codice SUBX con l'indirizzamento

*con predecremento. Il minuendo e' il numero op1=67381185, il sottraendo

*op2=22419153.

*La differenza dei due numeri è 44F68032, e viene calcolata, tenendo conto

del prestito memorizzato nei flag X e C, componendo la sottrazione parziale

delle *coppie di cifre decimali contenute in ciascuno dei 4 byte in cui

ciascun numero *e'memorizzato.

*La differenza è posta nelle stesse locazioni di op1 e nel registro D2.

*Area Programma a partire dalla locazione $8000

ORG $8000

START MOVE.L #EOP1,A0 In A0 indirizzo base 1^ addendo

MOVE.L #EOP2,A1 In A1 indirizzo base 2^ addendo

MOVE.L #COUNT,D1 In D1 il valore della variabile di conteggio *

del ciclo

LOOP SUBX.B -(A1),-(A0)

DBEQ D1,LOOP Quando D1 vale 0 ho finito di

sottrarre, * altrimenti

torno a LOOP

MOVE.L (A0),D2

STOP #$2000

*Area Dati a partire dalla locazione $8300

ORG $8300

OP1 DC.B $67,$38,$11,$85

EOP1 EQU *

OP2 DC.B $22,$41,$91,$53

EOP2 EQU *

COUNT EQU EOP2-EOP1-1 Inizializza contatore

END START


ACQUISTATO

1 volte

PAGINE

178

PESO

325.95 KB

AUTORE

Sara F

PUBBLICATO

+1 anno fa


DETTAGLI
Corso di laurea: Corso di laurea in ingegneria informatica
SSD:
A.A.: 2013-2014

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher Sara F di informazioni apprese con la frequenza delle lezioni di Calcolatori elettronici I e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Napoli Federico II - Unina o del prof Canonico Roberto.

Acquista con carta o conto PayPal

Scarica il file tutte le volte che vuoi

Paga con un conto PayPal per usufruire della garanzia Soddisfatto o rimborsato

Recensioni
Ti è piaciuto questo appunto? Valutalo!

Altri appunti di Calcolatori elettronici i

Quaderno appunti presi a lezione con esercizi esame svolti
Appunto
Calcolatori elettronici I - Esercizi sugli Automi
Esercitazione
Calcolatori Elettronici I - Appunti e esercizi
Appunto
Calcolatori elettronici I - analisi
Appunto