Che materia stai cercando?

Anteprima

ESTRATTO DOCUMENTO

2.22 ADD Add binary

1101 R mode ea

dest<=*dest+*sorg

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

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

2.22.1.1.1.1.1 esempio

*Il programma calcola il prodotto di due numeri con l'algoritmo delle

addizioni successive allo scopo di testare il codice operativo ADD

inizializzando il prodotto a zero e aggiungendo MPY volte MCND a se'

stesso.L'istruzione ADD.B usata effettua la somma su due operandi su 8 bit

usando l'addizione binaria con carry iniziale nullo e memorizza la somma su 8

bit nell'op.dest. e setta i conditions bit in base al valore degli operandi.

ADD e' valido sia per numeri signed two's complement che per numeri unsigned.

Per i signed,N e V indicano lo stato del risultato,mentre per gli unsigned, C

indica un riporto che si estende oltre la *posizione

dell'MSB.L'istruzione ADD setta consistentemente tutti questi bit di

condizione.Per quanto riguarda il campo <ea> (effective address),si ha che se

nella locazione specificata vi e' un operando sorgente,allora tutti i modi di

indirizzamento sono concessi.Se il size e'il byte,allora il modo address

register direct non e' permesso.

*

*Descrizione dello SR durante l'esecuzione del seguente listato:

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

--------------------------------------------------------------

* moltiplicando 12 20 30 40 -35

-127 d1(inizialmente contiene MPY)

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

---------------------------------------------------------------

* add.b D1,D0 00000 00000 00000 00000 01000 01000

* add.b #-1,d1 10001 10001 10001 10001 10001 10001

6

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

-----

* 00000 00000 00000 00000 11001 10011

* 10001 10001 10001 10001 10001 10001

5

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

-----

* 00000 00000 00000 00000 11001 01000

* 10001 10001 10001 10001 10001 10001

4

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

----------------------------------------------------------------------

* 00000 00000 00000 01010 10011 10011

* 10001 10001 10001 10001 10001 10001

3

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

-----------------------------------------------------------------------

* 00000 00000 01010 01000 10001

01000

* 10001 10001 10001 10001 10001

10001 2

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

----------------------------------------------------------------------

* 00000 00000 01000 01000 10001

10011

* 10001 10001 10001 10001 10001

10001 1

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

-------------------------------------------------------

* 00000 01010 01000 10001 10001

01000

* 10101 10101 10101 10101 10101

10101 0

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

-------------------------------------------------------

Non sono stati riscontrati errori nel posizionamento dei flag del registro

SR.

org $8200

main lea mcnd,a0

bsr mult

done move.b d0,prod

cmp.w #mcnde,a0

bne mult

stop #$ff00

mult

move.b (a0)+,d2

move.b mpy,d1

clr.w d0

loop add.b d2,d0

add.b #-1,d1

bne loop

beq done

rts

org $9000

mpy dc.b 7

moltiplicatore fisso

prod ds.b 1

mcnd dc.b 12,20,30,40,-35,-127 moltiplicandi

utilizzati

mcnde equ mcnd+6

end main

2.23 ADD Add binary

1101 R mode 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

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

*Il seguente listato calcola il prodotto di due numeri con l'algoritmo delle

addizioni uccessive allo scopo di testare il

*codice operativo ADD inizializzando il prodotto a zero e aggiungendo MPY

volte MCND a se' stesso.L'istruzione

*ADD.B usata effettua la somma su due operandi su 8 bit usando l'addizione

binaria con carry iniziale nullo

*e memorizza la somma su 8 bit nell'op.dest. e setta i conditions bit in base

al valore degli operandi.

*ADD e' valido sia per numeri signed two's complement che per numeri

unsigned.

*Per i signed,N e V indicano lo stato del risultato,mentre per gli unsigned,C

indica un riporto che si estende oltre la *posizione

dell'MSB.L'istruzione ADD setta consistentemente tutti questi bit di

condizione.Per quanto riguarda

*il campo <ea> (effective address),si ha che se nella locazione specificata

vi e' un operando sorgente,allora

*tutti i modi di indirizzamento sono concessi.Se il size e'il byte,allora il

modo address register direct non e' permesso.

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

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

*

*Descrizione dello SR durante l'esecuzione del seguente listato:

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

--------------------------------------------------------------

* moltiplicando 12 20 30 40 -35

-127 d1(inizialmente contiene MPY)

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

---------------------------------------------------------------

* add.b D1,D0 00000 00000 00000 00000 01000 01000

* add.b #-1,d1 10001 10001 10001 10001 10001 10001

6

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

---------------------------------------------------------------------

* 00000 00000 00000 00000 11001 10011

* 10001 10001 10001 10001 10001 10001

5

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

----------------------------------------------------------------------

* 00000 00000 00000 00000 11001

01000

* 10001 10001 10001 10001 10001

10001 4

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

----------------------------------------------------------------------

* 00000 00000 00000 01010 10011

10011

* 10001 10001 10001 10001 10001

10001 3

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

-----------------------------------------------------------------------

* 00000 00000 01010 01000 10001

01000

2.24 ADDA Add address

1101 R mode ea

dest<=*dest+*sorg

X,N,Z,V,C

- - - - -

ADDA <ea>,An

size: W,L

esempio

2.25 ADDI Add immediate

00000110 size ea + 1,2 ext word

dest<=*dest+imm

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

ADDI #<imm>,<ea>

size: B,W,L

esempio

2.26 ADDI Add immediate

00000110 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

ADDI #<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.

* 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 del primo elemento della colonna

addi.l #TABINI,D0 selezionata;

moveq.l #3,D1 inizializza il contatore;

LOOP move.l D0,A0 consente di utilizzare

l'indirizzamento indiretto;

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

addi.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.27

2.28 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.29 ADDQ Add quick

0101 data 0 size ea

dest<=*dest+data

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

ADDQ #data,<ea>

size: B,W,L

esempio

2.30 ADDQ Add quick

0101 data 0 size ea

dest<=*dest+data

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

ADDQ #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

ESADDQ MOVE.L #32,D1 Inizializza a 32 d1

MOVE.L #32,D2 Inizializza il contatore

LAB1 ROL #1,D0 Shifta a sinista D0

BCS 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 ESADDQ Salto a sottoprogramma

END MAIN

ADDQ Somma

D Effective

a Address

t

a

ADDQ #<data>,<ea>

Somma 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 ADDQ torna utile laddove serve incrementare un puntatore ad una word (2 unità) o

ad una long word (4 unità).

Differenze con ADDI: è 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

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

L e i bit di stato restano intatti).

2.31 ADDX Add extended

1101 Rx 1 size 00 R/M Ry

dest<=*dest+*sorg+X

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

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

m 0

ADDX Dy,Dx

ADDX -(Ay),-(Ax)

size: B,W,L

esempio

2.32 ADDX Add extended

1101 Rx 1 size 00 R/M Ry

dest<=*dest+*sorg+X

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

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

m 0

ADDX Dy,Dx

ADDX -(Ay),-(Ax)

size: B,W,L

esempio

*Esempio 2 includente operazioni in multipla precisione sfruttando addx.l;

*D5 contiene l'high order longword somma di D1 e D3,mentre D6 contiene

*la low order longword somma di D0 e di D2.

*Al fine di testare anche il modo di indir. data reg. to data reg.,la somma

di D0

*e di D2 è stata infine salvata in D7.

*TST1=D1-D0=11111100001010101111010100101111- *

11111100001110101111011110001001

*TST2=D3-D2=01111010001010101010001110101010- *

01101010101001001011101001100111

org $8000

start move.l #$fc2af52f,d0 load registers D0-D1 and *

D2-D3 to do two longwords

move.l #$fc3af789,d1

move.l #$6aa4ba67,d2

move.l #$7a2aa3aa,d3

move.l d0,TST1L

move.l d1,TST1H

move.l d2,TST2L

move.l d3,TST2H

lea.l TST1+8,a0 addressing for auto-decrement *

access lea.l TST2+8,a1 addressing for auto-decrement *

access move.w #0,ccr clear X

* SR: XNZVC

addx.l -(a1),-(a0) 10001 * adds

TST1 to TST2 one longword at a time

move.l (a0),d5 10000 * saves

result of D1+D3 in D5(it isn't change X)

addx.l -(a1),-(a0) 10001 * adds

with X-Flag getted by the first addx

move.l (a0),d6 10000 * saves

result of D0+D2 in D6(X is unchanged)

move.l d6,d7 10000 * and now

D7 contains D0+D2 addx.l d5,d6 01010 * this

instruction has only the task to test addx

* for data register to data register.

stop #$ff00

org $8500

TST1 ds.l 2

TST2 ds.l 2

TST1L equ TST1

TST1H equ TST1+4

TST2L equ TST2

TST2H equ TST2+4

end start

2.33 AND And logical

1100 R mode ea

dest<=*dest & *sorg

X,N,Z,V,C

- * * 0 0

AND <ea>,Dn

AND Dn,<ea>

size: B,W,L

esempio

2.34 AND And binary

1100 R mode ea

dest=dest and sorg

X,N,Z,V,C

- * * 0 0

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

Z=1 se dest=0

AND <ea>,Dn

AND Dn,<ea>

size: B,W,L

esempio:

Il seguente frammento di programma conta i bit alti in un byte

org $8000

mask dc.b 1,2,4,8,16,32,64,128 ognuno di

* questi byte ha un solo bit 1

pippo ds.b 1 byte da analizzare

init move.b #%10011001,pippo fornisce un

* valore al byte pippo

cont move.b #8,d2 inizializza il

* contatore del ciclo

movea.l #mask,a0

loop move pippo,d0 d0 verrà modificato

* dalla and

add.b #-1,d2 decrementa il

* contatore

and.b 0(a0,d2),d0

beq zero

add.b #1,d1 il bit di posizione

* d2 è 1

zero cmp #0,d2 controlla la fine del

* ciclo

bne loop

end init d1 contiene il numero

* di bit alti del byte pippo

2.35 AND And logical

1100 R mode ea

dest<=*dest & *sorg

X,N,Z,V,C

- * * 0 0

N=1 se MSB del risultato=1

Z=1 se il risultato=0

AND <ea>,Dn

AND Dn,<ea>

size: B,W,L

se <ea> è sorg. sono permessi solo modi

di indirizamento “data”

se <ea> è dest. sono permessi solo modi di ind. “alterable memory” (cfr.

MC68000,Table B-1)

esempio

* Questo programma conta il numero di bit alti in un byte * (NUM); allo scopo

di testare il bit i-esimo di NUM * esegue una AND tra NUM ed un byte-

maschera in cui tutti * i bit sono settati bassi tranne l’i-esimo che è alto.

* Se il risultato produce Z=0 (AND <> 0) vuol dire che * il corrispondente

bit di NUM è alto, per cui si * incrementa di 1 un contatore. I byte-

maschera vengono * memorizzati tutti in uno stesso registro semplicemente *

shiftando il suo contenuto a sinistra in ogni ciclo di * confronto.

ORG $8000

NUM DC.B $F1 numero da processare

BEGIN CLR.B D3

MOVE.B #1,D1 in D1 la prima maschera

MOVE.B (NUM),D0

MOVE.B D0,D2

LOOP MOVE.B D2,D0

AND D1,D0

BEQ NOADD se Z=0 non inc. il contatore

ADD #1,D3 se Z=1 inc. il contatore

NOADD LSL.B #1,D1 prepara prossima maschera

TST.B D1 controlla se il byte è finito

BNE LOOP altrimenti ripete il ciclo

END BEGIN

* in D3 è contenuto il numero di bit alti del byte NUM

2.36 AND And logico

And logico tra <destinazione> e <sorgente>, il risultato va in <destinazione>; uno dei due operandi

deve essere un registro dati.

1100 R mode ea

dest<=*dest & *sorg

X,N,Z,V,C

- * * 0 0

N=1 se MSB(*dest)=1

Z=1 se *dest=0

AND <ea>,Dn

AND Dn,<ea>

size: B,W,L

*Esempio di AND

org $1000

*conta i bit alti di una word.

*In d0 viene passato il dato per valore e sempre in d0 viene

*restituito il numero di bit alti.

contb move.w #1,d1 maschera per d0

move.b #16,d2 contatore del ciclo

move.b #0,d3 num. di bit alti

ciclo move.w d0,d4 in d4 ho una copia di d0

and.w d1,d4

beq noinc il bit d2-esimo è 0

add.b #1,d3

noinc asl.w #1,d1 cambio maschera

sub.b #1,d2

bne ciclo

move.w d3,d0

rts

start andi.w #$00ff,sr

move.w #$3f33,d0 il risultato deve essere 10

jsr contb

end start

2.37 ANDI And immediate

00000010 size ea + 1,2 ext word

dest<=*dest & imm

X,N,Z,V,C

- * * 0 0

N=1 se MSB(*dest)=1

Z=1 se *dest=0

ANDI #<data>,<ea>

size: B,W,L

esempio

2.38 ANDI And immediate

00000010 size ea + 1,2 ext word

dest *dest & imm

X,N,Z,V,C

- * * 0 0

N=1 se MSB(*dest)=1

Z=1 se *dest=0

ANDI #<data>,<ea>

size: B,W,L

Modi di indirizzamento non permessi :

- Immediate

- Relative

- Relative indexed

esempio :

* Questo segmento di programma costruisce una Longword con blocchi di

bit conte- * nuti in BYTE, WORD e LWORD. Tali blocchi sono estratti a

mezzo dell'istruzione * ANDI e sono assemblati in D0.

* ORG $8000

* MOVE.B BYTE,D0 Sposta BYTE in D0

ANDI.B #$3C,D0 Estrae il blocco di bit da 2

a 5 MOVE.W WORD,D1 Sposta WORD in D1

ANDI.W #$7C00,D1 Estrae il blocco di bit da 10 a 14

OR.W D1,D0 Impacchetta i 2 blocchi

MOVE.L LWORD,D2 Sposta LWORD in D2

ANDI.L #$F0700000,D2 Estrae i blocchi da 20 a 22 e da 28

a 31

OR.L D2,D0 Impacchetta i 4 blocchi

*

BYTE DC.B %01101001

WORD DC.W %1010010110111000

LWORD DC.L %11101100100100011111101001000111

2.39 Note :

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

accordo con Wakerly (‘d_dst’) ma contrariamente a quanto è scritto sul

manuale ( ‘Only data alterable or the status register addressing modes

are allowed’) .

2.40 ASL Arithmetic shift left

1110 count|Reg dr size i/r 00 R

dest<=dest<<count

X,N,Z,V,C

* * * * *

N=1 se dest=1

Z=1 se dest=0

V=1 se si genera overflow

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

ASL Dx,Dy

ASL #<data>,Dy

ASL <ea>

size: B,W,L

esempio

2.41 ASR Arithmetic shift rigth

1110 count|Reg dr size i/r 00 R

dest<=dest<<count

X,N,Z,V,C

* * * * *

N=1 se dest=1 RIVEDERE DA QUI IN POI FLAG !!!!!!

Z=1 se dest=0

V=1 se si genera overflow

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

ASR Dx,Dy

ASR #<data>,Dy

ASR <ea>

size: B,W,L

esempio

2.42 ASR Arithmetic shift rigth

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

dest<=dest>>count

1110 000 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

ASR Dx,Dy

ASR #<data>,Dy

ASR <ea>

size: B,W,L

esempio

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

*Il seguente programma testa il codice operativo ASR eseguendo il controllo

*della divisibilità per due di un numero incluso in tst.

*Gli shift aritmetici trattano i loro operandi come signed two's complement;

*lo shift aritmetico ASR equivale alla divisione per due.

*Nell'operazione ASR,l'overflow aritmetico è impossibile,così il bit di flag

V

*è sempre zero.

*Nel seguente listato,la divisione per due di un numero dispari eseguita con

*ASR.W genera X:=C con C:=1 così come dovrebbe;

*ASR.W per numeri pari genera X:=C con C:=0 (ok);

*ASR.W per numeri negativi pari genera X:=C con C:=1;N:=1;

*ASR.W per numeri negativi dispari genera X:=C con C:=1;N:=1.

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

org $8000

main lea test,a0

bsr divideby2

done1 move.b #0,d3 pone 0 in d3 se il

numero non è divisibile per 2

bsr newtst

done2 move.b #1,d3 pone 1 in d3 se il

numero è divisibile per 2

newtst cmp.l #testend,a0

bne divideby2

stop #$ff00

divideby2 move.w (a0)+,d1

move.w d1,d2 salva numero

attuale in d2 asr.w #1,d1 effettua

la divisione per 2

mulu.w #2,d1

cmp.w d1,d2

bgt done1

beq done2

rts

org $8700

test dc.w 4,7,20,21,120,125,1000,2307,-124,-1005

numeri per il test

testend equ test+20

end main

2.43 Bcc Branch conditionally

0110 Cond 8bit_disp+[16bit_disp]

if (cc) PC+disp=>PC

X,N,Z,V,C

- - - - -

N=1 se dest<0

Z=1 se dest=0

V=1 se si genera overflow

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

Per i cc si veda la tabella xx

Bcc <label>

size: B,W

esempio

B Diramazione su condizione

CC Con 8-bit Displacement

ditio

n

16-bit Displacement if 8-bit Displacement = 0

Bcc <label>

operazione effettuata : if cc then PC + spiazzamento -> PC

Consentiti i size di byte e word.

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 -

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

1100 - 0110 - Not

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

1110 - 1010 -

¬C&¬Z ¬V

0010 - High 1000 -

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

1111 - Less 1001 -

Quando si devono confrontare numeri dotati di segno si usano BLT e BGE.

BLT si comporta come BMI finché non si ha Overflow, altrimenti è equivalente a BPL.

2.44 Bcc Branch conditionally

0101 Condition 11001 8-bit Displacement

16-bit Displacement if 8-bit Displacement=0

if cc then Pc+d=>Pc

Bcc <label>

X N Z V C

- - - - -

Bcc <label>

Size (Byte,Word)

ESEMPIO

Questa subroutine restituisce in D0 il valore assoluto di un byte

passato in D0 , setta il Flag v =1 se D0 = -128.

ORG $8000 indirizzo di partenza

ESBCC CLR D1 Inizializza a zero D1

CMP.B #0,D0 Controlla se D0 < 0

BGE LAB1

SUB.B D0,D1 Calcola D1 = 0 - D0

MOVE.L D1,D0

CMP.B #-128,D0 Controlla se D0 = - 128

BNE LAB1

MOVE.W #$2,CCR Attiva il flag v

LAB1

RTS Ritorno al chiamante

MAIN MOVE.L #-128,D0 Metti in D0 il dato

JSR ESBCC Salto a sottoprogramma

END MAIN

2.45 BCHG Test a bit and change

1101 R mode ea

dest=dest+sorg

- - ? - -

Z=¬D

n

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.46 BCHG Test a bit and change

0000 R 101 ea (bit number dynamic)

0000100001 ea + 1 ext word (bit number static)

← ∼(<bit

Z number> of dest)

∼(<bit

(<bit number> of dest)← number> of dest)

X,N,Z,V,C

- - ? - -

∼Dn

Z =

BCHG Dn,<ea>

BCHG #<data>,<ea>

size: B,L

Modi di indirizzamento non permessi :

- diretto con registro dati

- diretto con registro indirizzo

- relativo

- relativo indicizzato

- immediato

esempio :

* L'esempio permette di complementare bit per bit un byte ottenendone la

* rappresentazione per complementi diminuiti .

* In D2 è riportato il numero di 1 presenti nel byte complementato .

* org $8000

BYTE dc.b %00110100 byte da complementare

CNT dc.b 7 contatore

*

INIZIO org $8020

clr.l D0

clr.l D1

clr.l D2

move.b CNT,D1 inizializza il contatore

move.b BYTE,D0

*

LOOP bchg.l D1,D0 complementa a partire dal bit 7 fino al bit 0

beq NUM1 salta NUM1 se è avvenuta la transizione 0-1

dbf D1,LOOP

bra.s FINE

NUM1 addi.b #1,D2 aggiorna il numero di 1 del complemento

diminuito

* cmpi.b #-1,D1

dbf D1,LOOP

*

FINE nop

* END INIZIO

2.47 BCLR Test a bit and clear

1101 R mode ea

dest=dest+sorg

- - ? - -

Z=¬D

n

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.48 BCLR Test a bit and clear

0000 R 110 ea (bit number dynamic)

0000100010 ea + 1 ext word (bit number static)

← ∼(<bit

Z number> of dest)

<bit number> of dest 0

X,N,Z,V,C

- - ? - -

∼Dn

Z =

BCLR Dn,<ea>

BCLR #<data>,<ea>

size: B,L

Modi di indirizzamento non permessi :

- diretto con registro dati

- diretto con registro indirizzo

- relativo

- relativo indicizzato

- immediato

esempio :

* L'esempio permette di eseguire una operazione OPER1 solo se si riscontra il

* passaggio dal valore 1 al valore 0 del bit in posizione 4 del byte CONTROL

.

* Si noti l'analogia con l'esempio del codice BSET .

* org $8000

CONTROL dc.b %10110101 byte di controllo

CNT dc.b 10 contatore

*

INIZIO org $8020

clr.l D0

clr.l D1

move.b #10,D3 inizializza il contatore

move.b CONTROL,D7

*

LOOP bclr.l #4,D7 se il bit 4 passa da 1 a 0 il flag Z

rimane basso

bne OPER1 salta ad OPER1 se è avvenuta la transizione

addi.b #1,D1 altrimenti esegue altre operazioni

cmpi.b #4,D1

bne.s SALTA

ori.b #16,D7 riporta a 1 il bit 4 del byte di controllo

SALTA dbf D3,LOOP decrementa il contatore

bra FINE

OPER1 addi.b #2,D0

dbf D3,LOOP

*

FINE nop

* END INIZIO

2.49 BRA Branch always

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

BRA Salta sempre

8-bit Displacement

16-bit Displacement if 8-bit Displacement = 0

BRA <label>

operazione effettuata : PC + spiazzamento -> PC

Consentiti i size di byte e word.

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

A differenza dell’istruzione JMP che effettua un salto ad un indirizzo assoluto, la BRA salta ad

un indirizzo relativo alla posizione corrente del PC.

2.50 BSET Test a bit and set

1101 R mode ea

dest=dest+sorg

- - ? - -

Z=¬D

n

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.51 BSET Test a bit and set

0000 R 111 ea (bit number dynamic)

0000100011 ea + 1 ext word (bit number static)

← ∼(<bit

Z number> of dest)

<bit number> of dest 1

X,N,Z,V,C

- - ? - -

∼Dn

Z =

BSET Dn,<ea>

BSET #<data>,<ea>

size: B,L

Modi di indirizzamento non permessi :

- diretto con registro dati

- diretto con registro indirizzo

- relativo

- relativo indicizzato

- immediato

esempio :

* L'esempio permette di eseguire una operazione OPER1 solo se si riscontra il

* passaggio dal valore 0 al valore 1 del bit in posizione 4 del byte CONTROL

.

* Si noti l'analogia col l'esempio del codice BCLR .

* org $8000

CONTROL dc.b %10100101 byte di controllo

CNT dc.b 10 contatore

*

INIZIO org $8020

clr.l D0

clr.l D1

move.b #10,D3 inizializza il contatore

move.b CONTROL,D7

*

LOOP bset.l #4,D7 se il bit 4 passa da 0 a 1 si alza il

flag Z beq OPER1 salta ad OPER1 se è avvenuta la transizione

addi.b #1,D1 altrimenti esegue altre operazioni

cmpi.b #4,D1

bne.s SALTA

andi.b #239,D7 riporta a 0 il bit 4 del byte di

controllo

SALTA dbf D3,LOOP decrementa il contatore

bra FINE

OPER1 addi.b #2,D0

dbf D3,LOOP

*

FINE nop

* END INIZIO

2.52 BSR Branch 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

BSR Salto a sottoprogramma

8-bit Displacement

16-bit Displacement if 8-bit Displacement = 0

BSR <label>

operazione effettuata : PC->SP@- ; PC + spiazzamento -> PC

Consentiti i size di byte e word.

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

BSR salva il PC all’indirizzo antecedente a quello contenuto in A7 (indirizzo di ritorno).

Modifica il PC in maniera tale da saltare all’etichetta della subroutine. L’indirizzo di ritorno viene

salvato in cima alla pila puntata da SP.

In virtù dell’utilizzo dello Stack Pointer la BSR può essere richiamata più volte anche all’interno di

porzioni di codice a cui si è giunti da un’altra BSR. Ad ogni BSR il valore di SP è decrementato di 4

unità e il nuovo indirizzo di ritorno viene memorizzato nella nuova posizione dello stack.

2.53 BTST Test a bit

1101 R mode ea

dest=dest+sorg

- - ? - -

Z=¬D

n

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.54 BTST Test a bit

0000 R 100 ea (bit number dynamic)

0000100000 ea + 1 ext word (bit number static)

← ∼(<bit

Z number> of dest)

X,N,Z,V,C

- - ? - -

∼Dn

Z =

BTST Dn,<ea>

BTST #<data>,<ea>

size: B,L

Modi di indirizzamento non permessi :

- diretto con registro indirizzo

- immediato

- BTST.B non può avere come dest un registro dati

esempio :

* Tale programma consente di contare il numero di bit '1' in un byte e di

* valutarne la parità .

* org $8200

BEGIN move.b BYTE1,D0

clr.l D2 Azzera il contatore dei bit '1'

move.b #7,D1 Inizializza bitnum a 7

LOOP btst.l D1,D0 Test di D0[D1] dinamico

beq.s NEXT Salta se Z=1

addq.b #1,D2 Incrementa il contatore se Z=0

NEXT dbf D1,LOOP

btst.l #0,D2 Setta Z se il numero di bit è pari (test statico)

FINE nop

org $8500

byte1 dc.b 214 in binario 11010110

end BEGIN

Note sulle istruzioni di bit manipulation

Innanzitutto in teoria le istruzioni di manipolazione di bit possono operare

solo su operandi di size byte e long word, e non su word come indicato sul

manuale. org $8000

CONTROL dc.l $AEBA8423

INDICE dc.l 70

INIZIO org $8020

move.l CONTROL,D7

move.l INDICE,D0

LOOP1 btst.l D0,D7

dbf D0,LOOP1

move.l CONTROL,D7

move.l INDICE,D0

LOOP2 bset.l D0,D7

dbf D0,LOOP2

move.l CONTROL,D7

move.l INDICE,D0

LOOP3 bclr.l D0,D7

dbf D0,LOOP3

move.l CONTROL,D7

move.l INDICE,D0

LOOP4 bchg.l D0,D7

dbf D0,LOOP4

*

FINE nop

* END INIZIO

Provando a simulare questo programma con Asim, osservando i registri

influenzati e l’SR, è possibile evidenziare alcuni malfunzionamenti delle

istruzioni di bit manipulation se il size è long word :

! BTST opera correttamente solo sugli 8 bit meno significativi di una long word,

settando il flag Z=1 per tutti gli altri ;

! BSET,BCLR operano correttamente solo sui 16 bit meno significativi, lasciando

inalterati quelli più significativi. In particolare se si manipola il bit in

posizione 15 si nota che :

- BSET setta tutti i 16 bit più significativi ;

- BCLR pone a 0 tutti i 16 bit più significativi ;

! BCHG opera correttamente solo sugli 8 bit meno significativi, lasciando inalterati

quelli più significativi. In particolare se si manipola il bit in posizione 15 si

nota che vengono settati i 16 bit più significativi, ed inoltre quelli dalla

posizione 15 alla 8 sono trattati come se in origine fossero tutti 0.

2.55 CHK Check register against bounds

1101 R mode ea

dest=dest+sorg

- * U U U

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.56 CHK Check Register against Bounds

0100 Reg 110 EA

If Dn<0 or D>(<ea>) then TRAP

X N Z V C

- * U U U

N - Settato se Dn<0, Azzerato se Dn>(<ea>).Indefinito negli altri casi

CHK <EA>,Dn

size: WORD

esempio

*il programma seguente mostra l'utilizzo del codice chk

*il programma gestisce uno coda interna di qlen word, ogni volta che si cerca di fare

un inserimento

*attraverso chk si controlla se la coda e' piena, se lo e' si genera una eccezione che

*manda a video la scritta di queue overflow.

org $8000 start at address $8000

*procedure enqueue: inserisce un dato in coda

enq movea.l tail,a0 carica in a0 il puntatore alla coda della struttura

coda

move.b d0,(a0) se non è pieno mette il valore d0 in coda

adda.l #2,a0 ed incrementa il puntatore alla coda

* controlla se il blocco di memorizzazione è pieno

add.l #1,d1

chk #qlen,d1

eend rts

start move $0000,sr

lea.l stacke,sp

lea.l queue,a0

move.l a0,head

move.l a0,tail

clr d1

rep jsr enq

jmp rep

stop #$2000 istruzione privilegiata illecita, genera

* eccezione a 8 a $20

org $8300

ter equ $a000

ans dc.b 'error: queue overflow ',0

qlen equ 20 lunghezza della coda

queue ds.w qlen blocco di memorizzazione

head ds.l 1

tail ds.l 1

stack ds.l 50 spazio per gli indirizzi di ritorno

stacke equ *

org $8500 isr per la gestione della exception

stop #$a000

org $8600 isr per la gestione della ecezione generata da chk

movea.l #ter,a2

movea.l a2,a0

add.l #1,a2

move.b #$30,(a2) setta il registro di controllo del terminale

lea.l ans,a1

output move.b (a1)+,d0

cmp #0,d0 se il carattere da inviare è 0 termina

beq fine

move.b d0,(a0) manda il carattere d0 a video

bcc output

fine rte

end start

2.57 CHK Check Register against Bounds

0100 reg 110 ea

if Dn<0 or Dn>(<ea>) then TRAP

X N Z V C

- * U U U

N : settato se Dn<0; resettato se Dn>(<ea>);

indefinito altrimenti.

CHK <ea>,Dn

Size : W

reg - Specifica il registro dato il cui contenuto viene testato.

ea - Specifica l’operando word che rappresenta il limite

superiore del confronto. Sono concessi solo data addressing

modes.

*

esempio

INSTR ORG $9200

*Questa ISR preleva una stringa dal buffer di tastiera, trasforma eventuali *caratteri minu

caratteri maiuscoli e la porta nella memoria centrale.

*Essa è associata ad una linea di interruzione con priorità 1 e quindi il suo *indirizzo dev

all' indirizzo $64 della ROM.

MOVEM.L A0/A1/A2/D0,-(SP) vengono salvati i registri usati

MOVE.L #TRDAT,A0

MOVE.L #TRCTR,A1

LEA BUF,A2

while MOVE.B (A0),D0 il carattere viene portato in D0

CMP.B #13,D0 si controlla se la stringa è terminata

BEQ fin

SUB.B #$41,D0 si controlla se il carattere sia maiuscolo

CHK #12,D0 in caso contrario viene generata una TRAP

ADD.B #$41,D0 viene rinormalizzato il codice

MOVE.B D0,(A2)+ si inserisce il carattere nel buffer

BRA while

fin MOVE.B D0,(A2)+ l'enter viene inserito nel buffer e

* funge da terminatore

*A scopo di prova il risultato viene displayato

OSTR ORI.B #$0C,(A1) pulisce il buffer di tastiera e

* effettua il clearscreen

LEA BUF,A2

while1 MOVE.B (A2)+,D0

CMP.B #13,D0

BEQ fine

MOVE.B D0,(A0)

BRA while1

fine MOVE.B D0,(A0)+

MOVE.B #$33,(A1) si ripristinano le condizioni iniziali *

del terminale

MOVEM.L (SP)+,A2/A1/A0/D0 i registri salvati vengono ripristinati

RTE

CONV ORG $9300

*Questa routine controlla se in DO vi sia un carattere minuscolo

*nel qual caso lo trasforma in maiuscolo

*La routine è chiamata da una trap generata dal codice CHK il cui

*Vector Number è 7 e quindi il suo indirizzo deve comparire allo

*indirizzo $18 della ROM

CMP.B #$20,D0

BLT rit

CMP.B #$39,D0

BGT rit

SUB.B #$20,D0

rit RTE

*Esempio di programma chiamante

MAIN ORG $9500

BUF DS.B 256

TRDAT EQU $2000

TRCTR EQU $2001

VIA MOVE.L #$11111111,A0 viene messo un valore arbitrario nei registri

MOVE.L #$22222222,A1 usati dalla ISR per provare il corretto funz.

MOVE.L #$33333333,A2 del codice MOVEM

MOVE.L #$44444444,D0

ANDI #$D8FF,SR passaggio a stato utente

MOVE.B #$33,(TRCTR) inizializzazione terminale: si abilitano echo *

tastiera e interruzioni

LOOP JMP LOOP attesa di CR

END VIA

*

2.58 CLR Clear an operand

1101 R mode ea

dest=dest+sorg

- * * 0 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.59 CLR Clear an operand

01000010 Size Ea

dest=0

X N Z V C

- 0 1 0 0

CLR <Ea>

Size: B,W,L

esempio

2.60 CLR Clear an operand

01000010 Size ea

dest=0

X N Z V C

- 0 1 0 0

CLR <ea>

size: B,W,L

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

*

esempio

ORG $9420

LOC DS.B 2

*Il codice viene provato per alcuni dei modi

*di indirizzamento consentiti

VIA MOVE #$FFFF,D0

CLR D0

LEA.L LOC,A0

MOVE.B #$FF,(A0)

CLR.B (A0)

MOVE.B #$FF,(A0)

CLR.B (A0)+

MOVE.B #$FF,(A0)

CLR.B -(A0)

MOVE.B #$FF,1(A0)

CLR.B 1(A0)

MOVE.B #$FF,1(A0,D0)

CLR.B 1(A0,D0)

MOVE.B #$FF,LOC

CLR.B LOC

END VIA

Le prove hanno dato risultati correti

*

2.61 CMP Compare

1011 R mode ea

dest-sorg

X,N,Z,V,C

- * * * *

N=1 se il bit più significato è 1, 0 altrimenti

Z=1 se i due dati sono uguali

V=1 se il risultato di dest-sorg genera overflow

C=1 se il risultato di dest-sorg genera un carry

CMP <ea>,Dn

size: B,W,L

esempio :

* Programma che utilizza la routine di inizializzazione di array

monodimensionali

* ARRIN. Questo programma non fa altro che dichiarare tre array ;

* il primo di byte, il secondo di word ed il terzo di long word.

* dopo la dichiarazione li inizializza con tre diversi valori.

ORG $4000 Localizza il programma

SIZE1 EQU 35 Dimensione primo array

SIZE2 EQU 6 Dimensione secondo array

SIZE3 EQU 8 Dimensione terzo array

ARR1 DS.B SIZE1 Riserva spazio per primo array

ARR2 DS.W SIZE2 Riserva spazio per secondo array

ARR3 DS.L SIZE3 Riserva spazio per terzo array

VAL1 EQU 53 Primo valore inizializzazione

VAL2 EQU 32001 Secondo valore inizializzazione

VAL3 EQU 1000000 Terzo valore inizializzazione

*** Procedura ARRIN : effettua l'inizializzazione di un array.

* L'indirizzo dell'array è posto in A0.

* La dimensione dell'array è posta in D2.

* il tipo di dato è identificato da un valore posto in D0 : 1 = Byte

* 2 = Word

* 4 = Long

* Nel caso in D0 sia presente un valore diverso da questo allora la routine

* procederà come se il dato fosse un Byte.

* Il valore di inizializzazione è posto in d1.

ARRIN CMP.B #1,D0 if D0=1 then goto INIB

BEQ INIB

CMP.B #2,D0 if D0=2 then goto INIW

BEQ INIW

CMP.B #4,D0 if d0=4 then goto INIL

BEQ INIL

INIB MOVE.W #0,D0 d0:=0

INIB1 MOVE.B D1,(A0,D0) ^a0+d0:=d1

ADD.W #1,D0 d0:=d0+1

CMP.W D2,D0 if d0<d2 then goto inib1

BLT INIB1 else goto arrend

BGE ARREND

INIW MULU D0,D2 d2:=d2*d0

MOVE.W #0,D0 d0:=0

INIW1 MOVE.W D1,(A0,D0) ^a0+d0:=d1

ADD.W #2,D0 d0:=d0+2

CMP.W D2,D0 if d0<d2 then goto iniw1

BLT INIW1 else goto arrend

BGE ARREND

INIL MULU D0,D2 d2:=d2*d0

MOVE.W #0,D0 d0:=0

INIL1 MOVE.L D1,(A0,D0) ^a0+d0:=d1

ADD.W #4,D0 d0:=d0+4

CMP.W D2,D0 if d0<d2 then goto inil1

BLT INIL1 else goto arrend

ARREND RTS fine subroutine

* Inizio codice

MAIN MOVE.W #SIZE1,D2 D2 := SIZE1

MOVE.B #1,D0 D0 := 1

MOVE.B #VAL1,D1 D1 := VAL1

LEA.L ARR1,A0 A0 := &ARR1

JSR ARRIN Inizializza ARR1

MOVE.W #SIZE2,D2 D2 := SIZE2

MOVE.B #2,D0 D0 := 2

MOVE.W #VAL2,D1 D1 := VAL2

LEA.L ARR2,A0 A0 := &ARR2

JSR ARRIN Inizializza ARR2

MOVE.W #SIZE3,D2 D2 := SIZE3

MOVE.B #4,D0 D0 := 4

MOVE.L #VAL3,D1 D1 := VAL3

LEA.L ARR3,A0 A0 := &ARR3

JSR ARRIN Inizializza ARR3

END MAIN Fine del codice

2.62 CMP Compare

1011 R mode ea

(destination)-(source)

- * * * *

N=1 se il risultato è <0

Z=1 se il risultato è 0

V=1 se si genera overflow

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

V=¬S

m m m m m m

C=1 se si genera borrow

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

C=S

m m m m m m

X non viene modificato

CMP <ea>,Dn

size: B,W,L

Quando il size dell’operazione è “byte” il modo di

indirizzamento “registro diretto” (con riferimento

all’operando sorgente) non è permesso.

esempio

* Questo programma trova il max in un vettore

* di words

ORG $9000

VET DC.W $0105,$05F0,$5F01,$0003,$0000

BEGIN LEA.L VET,A1 indirizzo vettore in A1

MOVE.W (A1)+,D0 primo elemento in D0

CICLO MOVE.W (A1)+,D1 elemento generico in D1

CMP.W D0,D1 confronta elementi

BLE CICLO1 se D1>D0 allora

MOVE.W D1,D0 il max va in D0

CICLO1 TST.W D1 il vettore è finito?

BNE CICLO

END BEGIN

2.63 CMP Comparazione

Confronta <destinazione> con <sorgente> effettuando la sottrazione; il risultato non viene

memorizzato ma viene usato per modificare i bit di flag. <Destinazione> può essere solo un registro

dato. 1011 R mode ea

*dest-*sorg

X,N,Z,V,C

- * * ? ?

N=1 se MSB(*dest)=1

Z=1 se *dest=0

·Dm·¬R +Sm·¬D ·Rm

V=¬S

m m m

·¬Dm+R ·¬Dm+S ·Rm

C=S

m m m

CMP <ea>,Dn

size: B,W,L

*Esempio di CMP

org $1000

dim equ 5

vect ds.w dim

vmax ds.w 1

vmin ds.w 1

*Verifico se gli elementi di un vettore sono contenuti

*in un intervallo specificato, se è così z=1.

*In a0 è contenuto l'indirizzo iniziale del vettore (di dimensione

dim),

*in d0 e d1 sono contenuti rispettivamente estremo inferiore e

superiore

*dell'intervallo.

contrv move.b #dim,d2

ciclo cmp.w (a0),d0 elemento del vettore deve essere

bgt outr >d0

cmp.w (a0)+,d1

blt outr <d1

sub.b #1,d2

bne ciclo z=1 se esco dal ciclo

bra fine

outr andi.b #$fb,ccr pongo z=0

fine rts

start andi.w #$00ff,sr

*carico il vettore vect, vmax e vmin

move.w vmin,d0

move.w vmax,d1

move.w #vect,a0

jsr contrv

end start

2.64 CMPI Compare 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 ADD <ea>,Dn

m m m m m m

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.65 CMPI Compare immediate

00001100 size ea + 1,2 ext word

*dest-imm

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

CMPI #<imm>,<ea>

size: B,W,L

Modi di indirizzamento non permessi :

- Immediate

- Relative

- Relative indexed

esempio :

* Questo segmento di programma cerca la stringa 'SYNC' all' interno

di un buffer * di caratteri.

* Nel caso in cui la stringa viene trovata, si salta ad una

subroutine (MSGOUT) * che stampa un messaggio appropriato.

*

INIZIO org $800

move.l#BUFADD,A0 inizializza il puntatore del buffer;

*

CERCAS move.l A0,D0 aggira 'Error:invalid

addressing mode';

cmpi.l#BUFADD+BUFSIZE-4,D0 verifica se è ancora possibile

trovare'SYNC'

move.lD0,A0 aggira 'Error:invalid addressing mode';

bgt.s FINE

cmpi.b#'S',(A0)+ confronta 'S' con il carattere puntato;

bne.s CERCAS

CERCAY cmpi.b#'Y',(A0) confronta 'Y' con il carattere

puntato;

bne.s CERCAS

addq.l#1,A0 incrementa il puntatore;

CERCAN cmpi.b#'N',(A0) confronta 'N' con il carattere

puntato;

bne.s CERCAS

addq.l#1,A0 incrementa il puntatore;

CERCAC cmpi.b#'C',(A0) confronta 'C' con il carattere

puntato;

bne.s CERCAS

* jsr MSGOUT

FINE nop

* org $8100

BUFADD dc.b 'DSFGSYBNSYNKHSYNCAEXCLSYN'

BUFSIZE equ 25

end INIZIO

2.66 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.67 CMPM Compare memory

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 ADD <ea>,Dn

m m m m m m

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.68 CMPM Compare memory

1011 Rx 1 Size 001 Ry

CMP Ay@+ TO Ax@+

X, N, Z, V, C

- * * * *

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

Z = 1 se i due operandi sono uguali

V = 1 se dest-sorg genera un overflow

C = 1 se dest-sorg genera un riporto

CMPM (Ay)+,(Ax)+

size: B,W,L

esempio

* Programma che utilizza la subroutine di confronto fra due stringhe COMPST

ORG $4000 Localizza il codice

ST1 DC.B 'CIAO AMICO',13

DS.W 0

ST2 DC.B 'CIAO AMICO',13

*** Subroutine COMPST ***

* Questa subroutine confronta due stringhe di caratteri terminate da un

carattere

* di ENTER ( codice ASCII 13).

* In A0 ed A1 si trovano gli indirizzi di inizio delle due stringhe da

confrontare.

* In D2 viene restituito 0 se le stringhe sono differenti altrimenti viene

restituito 1

* Il contenuto dei registri D0 e D1 viene modificato dalla subroutine.

* Per il confronto dei caratteri vengono usati i codici CMP e CMPM.

COMPST MOVE.L #1,D2 Inizializzazione di D2 al valore 1

CST1 MOVE.B (A0),D0 d0 := (a0)

MOVE.B (A1),D1 d1 := (a1)

CMP.B #13,D0 if d0 = ENTER then goto ENT1

BEQ ENT1

CMP.B #13,D1 if d1 = ENTER then goto ENT2

BEQ ENT2

CONFR CMPM (A0)+,(A1)+ if (a0)+ = (a1)+ then goto CST1

BEQ CST1

DIVERSE MOVE.L #0,D2 d2 := 0

BRA CSFINE goto CSFINE

ENT1 CMP.B #13,D1 if d1 = ENTER then goto CSFINE

BEQ CSFINE else goto DIVERSE

BNE DIVERSE

ENT2 CMP.B #13,D0 if d0 = ENTER then goto CSFINE

BEQ CSFINE else goto DIVERSE

BNE DIVERSE

CSFINE RTS Fine subroutine

MAIN LEA.L ST1,A0

LEA.L ST2,A1

JSR COMPST

END MAIN

2.69 CMPM Compare memory

1011 Rx 1 size 001 Ry

(dest)-(source)

- * * * *

N=1 se il risultato è <0

Z=1 se il risultato è 0

V=1 se si genera overflow

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

V = ¬S

m m m m m m

C=1 se si genera borrow

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

C = S

m m m m m m

X non viene modificato

CMPM (Ay)+,(Ax)+

size: B,W,L

CMPM effettua la sottrazione tra due operandi referenziati mediante il modo

di indirizzamento

indiretto con postincremento.

esempio

ORG $8000

DATI DC.W $01F4,$01B3

BEGIN LEA.L DATI,A0

LEA.L DATI+2,A1

CMPM.W (A0)+,(A1)+

END BEGIN

Dopo l’istruzione CMPM:

Z=V=0;

N=1 (risultato negativo);

C=1 (si è generato borrow);

2.70 CMPM Comparazione in memoria

Confronta <destinazione> con <sorgente> effettuando la sottrazione; il risultato non viene

memorizzato ma viene usato per modificare i bit di flag. Viene sempre usato l’indirizzamento

postincrementato, gli operandi quindi sono sempre dei registri di memoria il cui indirizzo è contenuto

nei registri indirizzo specificati nell’istruzione.

1011 Rx 1 size 001 Ry

*dest-*sorg

X,N,Z,V,C

- * * ? ?

N=1 se MSB(*dest)=1

Z=1 se *dest=0

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

V=¬S

m m m m m m

C=S ·¬D +R ·¬D +S ·R ADD <ea>,Dn

m m m m m m

CMPM (Ay)+,(Ax)+

size: B,W,L

*Esempio di CMPM

org $1000

dim equ 20

vect1 ds.w dim

vect2 ds.w dim

*Dati due vettori stabilire se sono uguali

*se lo sono settare il bit z

*L'indirizzo iniziale dei vettori deve essere posto in a0 e a1.

compv move.b #dim,d0 contatore per il ciclo

ciclo cmpm (a0)+,(a1)+

bne diversi z=0 se sono diversi

sub.b #1,d0

bne ciclo z=1 esco dal ciclo (sono uguali)

diversi rts

start move.w #$0000,sr inizializzo sr

*inserisco dati significativi nei due vettori

move.w #vect1,a0 carico indirizzo iniziale

move.w #vect2,a1 dei due vettori

jsr compv

end start

2.71 DBcc Test condition, decrement and branch

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.72 DBcc Test condition, decrement and branch

0101 Condition 11001 Register

Displacement(d)

if ¬cc then Dn-1=>Dn;if Dn<>-1 then Pc+d=>Pc

X N Z V C

- - - - -

DBcc Dn,<label>

ESEMPIO

Questa subroutine trova la prima occorenza di un dato passato in D0

in un array il cui indirizzo e' passato in A0 e la cui lunghezza e'

data in D1.

Se il dato e' trovato il flag z=1 ed A0 punta alla locazione

succesiva al dato altrimenti z=0.

ORG $8000 Indirizzo di partenza

ESDBCC BRA LAB2

LAB1 CMP.B (A0)+,D0

LAB2 DBEQ D1,LAB1

RTS

ORG $9000 Area dati

BUFFER DC.B 128,30,40,40

BUFSIZ EQU 4

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

dell'array

MOVE.L #40,D0 Carica in D0 il dato da

cercare

MOVE.L #BUFSIZ,D1 Carica in D1 la dimenzione

dell'array

JSR ESDBCC Salto a sottoprogramma

END MAIN

DB Decrementa, controlla e salta

CC Con R

e

ditio g

n i

s

t

e

r

Displacement

DBcc Dn,<label>

operazione effettuata : if ¬cc then Dn=Dn-1 ; if Dn<>-1 then PC + spiazzamento -> PC

Unico size consentito è word.

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 -

L’istruzione DBcc verifica prima il codice condizione e poi esegue decremento e salto se la

conddizione non è soddisfatta.

Nel caso in cui la condizione non è mai soddisfatta, ovvero DBF, l’assembler accetta l’istruzione

DBRA, che vuole un registro dati come sorgente e una etichetta come destinazione.

In questo caso il registro viene comunque decrementato, e quindi, alla fine del ciclo, non

conterrà un valore nullo.

Se il valore del registro è zero si esegue l’istruzione successiva, altrimenti si esegue il salto

all’etichetta specificata.

2.73 DIVS Signed divide

1101 R mode ea

dest=dest+sorg

- * * 0 0

V=overflow di divisione

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.74 DIVS Signed divide

1000 R 111 ea

dest=dest/sorg

- * * * 0

N=1 se il quoto e’ negativo. Nullo altrimenti. Indefinito se c’e’ OVERFLOW.

Z=1 se il quoto e’ nullo. Nullo altrimenti. Indefinito se c’e’ OVERFLOW.

V=1 overflow di divisione. Nullo altrimenti.

DIVS <ea>,Dn

size: W

esempio

* Esempio d'uso delle istruzioni: DIVS, MOVEQ, SUB, DIVU;

* tramite la configurazione terminal.cfg .

* Il programma esegue la divisione con segno tra due numeri interi

* immessi da tastiera, il risultato sara' mostrato sul video del terminale.

* Range valori applicabili: Numero A ----> +/- 131071

* Numero B ----> +/- 32767

* N.B.

* Per questa versione non sono previsti forme particolari

* di controllo dell'input

* pertanto bisogna porre attenzione durante l'immissione dei dati.

* Tale esempio e' usato fondamentalmente per mostrare l'uso

* della istruzione DIVS del Motorola 68000,

* ma e' anche utile notare l'uso della MOVEQ per azzerare i registri,

* operazione che eseguita tramite tale istruzione risulta molto veloce.

* Sono usate anche le operazioni DIVU e SUB, la prima si usa come

* divisore decimale mentre la seconda e' usata in modo particolare per

* trasformare una cifra ASCII in una cifra binaria, la cui differenza nella

* codifica e' che la cifra BINARIA si ottiene sottraendo un

* numero (una specie di DISPLACEMENT) dalla cifra ASCII,

* Il valore di tale numero e' proprio pari allo '0' ASCII=$30,

* e' chiaro che sottraendo $30 dalla cifra ASCII ottengo proprio

* il numero 0 BINARIO (stessa cosa per le altre 9 cifre).

* Da notare la forma usata per l’istruzione SUB:

* invece di scrivere "SUB #$30,d4" si e' preferito usare la forma

* "SUB #'0',d4" che ha lo stesso effetto, dato che rappresenta

* lo stesso valore, ma in questa forma migliora la comprensione del codice.

* Elaborazione: Gruppo 10 - 96/97.

ORG $8200

TER EQU $2000

MEM EQU $8000

MOVEQ.L #0,D2 * azzera registri *

MOVE.L D2,D4

MOVE.L D4,D5

MOVE.L D4,D6

MOVE.L D4,D7

NUMOUT DS.L 2 * definiz. zona mem per risultato in output *

* --------------------- definiz. stringhe di output -------------------------

*

NUM1 DC.B 'Immetti numero A = ',0 * ( ---- range +/- 131071 ---- )

*

NUM2 DC.B 'Immetti numero B = ',0 * ( ---- range +/- 32767 ----- )

*

TOT DC.B 'Risultato A / B = ',0

BEGIN MOVEA.L #TER,A2 * inizializzazione terminal *

MOVEA.L A2,A0

ADD.L #1,A2 * attivazione reg. controllo e stato *

MOVE.B #$30,(A2) * abilitaz. buffer tastiera ed eco *

SCELTA CMP.B #0,D6 * se d6=0 siamo all'input del primo num *

BEQ FIRST * quindi va alla first *

* altrimenti d6=1: siamo al secondo num *

LEA.L NUM2,A1 * carica ind 2' num in A1 *

BRA OUTPUT * prosegue saltando ad OUTPUT *

FIRST LEA.L NUM1,A1 * carica ind 1' num in A1 *

OUTPUT MOVE.B (A1)+,D0 * richiesta a video dei numeri su cui operare

*

CMP.B #0,D0 * controllo per fine stringa *

BEQ CONT * e' 0 ? SI: vai a cont *

MOVE.B D0,(A0) * altrimenti continua a mostrare i caratteri a video

* BCC OUTPUT * salta ad output *

CONT MOVE.B (A2),D1 * input numero da tastiera *

AND.B #$80,D1 * controlla se e' premuto il <cr> *

BEQ CONT * NO: vai a cont e continua input *

MOVEA.L #MEM,A1 * carica indirizzo di mem in a1 *

IN1 MOVE.B (A0),D0 * mette in d0 ogni cifra memorizzata nel buffer *

CMP.B #13,D0 * controlla se <cr> premuto, cioe' D0 e vuoto ? *

BEQ INMEM * Si: salta a inmem *

SWITCH CMP.B #'-',D0 * controlla se la prima cifra ascii e' il '-'

* BEQ Segno * altrimenti prosegue da switch *

* ----- inizio conversione ascii2bin -----*

MOVE.B D0,D4 * trasferisce la cifra ascii in d4 per convertirla *

SUB.B #'0',D4 * sottrae lo '0' ascii e la converte cosi' in binario

* MULS #10,D5 * moltiplica d5 per 10, aumentanto il peso decimale *

ADD.L D4,D5 * addiziona la cifra binaria a d5 *

BRA IN1 * salta a in1 *

SEGNO MOVE.B #1,D2 * il numero e' negativo, pone 1 in d2 come reminder *

BRA IN1 * prosegue da inmem *

*-------------- fine conversione -------------------*

INMEM CMP.B #1,D2 * d2=1 ? Cioe' il numero e' negativo? *

BNE VAI1 * NO: salta a vai1 *

NOT.L D5 * SI: complementa a 2 il numero in d5 (lo nega) *

ADDI #1,D5 * (e poi gli addiziona 1) *

MOVEQ #0,D2 * azzera d2, il reminder di num negativo *

VAI1 CMP.B #1,D6 * controlla se d6=1 *

BEQ CONT0 * quindi salta a cont0 *

MOVE.L D5,D7 * altrimenti carica D7 col primo numero convertito *

MOVEQ #1,D6 * pone d6=1 quindi indica che si deve passare al 2' num *

MOVEQ #0,D5 * azzera D5 che serve di nuovo per la convers ascci2bin *

BRA BEGIN * ripeti il ciclo di input a video *

* Al termine, in D5 resta il 2' numero convertito, *

* il 1' numero convertito e' in D7 *

CONT0 DIVS D5,D7 * * operazione che il programma deve eseguire * *

MOVE.W SR,D5 * sr in d5, per conservarlo prima di manipolare i bit *

MOVE.L D7,D3 * porta il numero: MSW=resto + LSW=quoto in d3 *

SWAP D3 * inverte MSW con LSW *

ANDI.L #$FFFF,D3 * cancella il quoto da d3 che ora e' il resto *

ANDI.L #$FFFF,D7 * cancella il resto da d7 che ora e' il quoto *

MOVE.W D5,SR * restituisce lo sr orig. prima di manipolarne i bit *

BPL CONV * salta a conv se il risultato non e' negativo (bit N=0) *

NOT.W D7 * complementa a 1 d7 che era negativo *

ADDI #1,D7 * addiziona 1 a d7, il numero e' ora positivo*

* pronto per essere convertito in ascii

MOVEQ #1,D2 * indica segno *

CONV LEA NUMOUT,A3 * va alla fine di numout *

move.B #$0D,(A3)+ * inserisce il carattere <cr> come fine output *

LOOP DIVU #10,D7 * divide per 10 il numero, il risultato restera' in

d7 * * ris: MSW=resto div LSW=quoziente div *

MOVE.L D7,D5 * carica in d5 il contenuto di d7 *

SWAP D5 * inverte MSW con LSW in modo che ora LSW=resto div *

ANDI.L #$FFFF,D5 * azzera l'MSW, cosi' lascia in d5 *

* solo il resto della divs *

ANDI.L #$FFFF,D7 * azzera l'MSW, cosi' lascia in d7 *

* solo il quoziente della divs *

ADD.W #'0',D5 * somma $30 a d5 cosi' conv. da BIN ad ASCII la cifra

* MOVE.B D5,(A3)+ * carica la cifra in ASCII in memoria *

CMP #0,D7 * quoziente div=0 significa: fine cifre numero bin *

BNE LOOP * salta se le cifre bin sono ancora disponibili in d7 *

CMP #1,D2 * verifica segno *

BNE POS * salta se e' positivo *

MOVE.B #'-',(A3)+ * inserisce il segno in mem *

POS LEA.L TOT,A1 * presenta a video la stringa di output *

OUT1 MOVE.B (A1)+,D0 * carica la stringa cifra per cifra *

CMP.B #0,D0 * termina quando trova lo 0 finale *

BEQ OUT2 * salta a cont *

MOVE.B D0,(A0) * continuo l'output a video del risultato *

BCC OUT1 * torna a out1 finche' chi sono caratteri nel buffer *

OUT2 MOVE.B -(A3),D0 * pone in d0 il risultato, cifra per cifra *

MOVE.B D0,(A0) * lo trasferisce a video *

CMP.B #13,D0 * finche' non trova il carattere di <cr> *

BNE OUT2 * altrimenti ripete da out2 *

STOP #$2000 * arresta il programma *

END BEGIN

2.75 DIVS Signed divide

1000 R 111 EffAddr

dest=dest/sorg

- * * ? 0

V=overflow di divisione

N= dest<0

Z= dest=0

DIVS <ea>,Dn

size: B,W,L

Esempio retta.a68

:

* Utilizzo del codice operativo: DIVS

* Programma per il calcolo dei punti appartenenti ad un segmento.

* Dati:

* punto iniziale [x1,y1]

* punto finale [x2,y2]

* Gli assi del piano vanno da [-200,200] per le x e da [-200,200] per le y

* I punti vengono calcolati attraverso la formula:

* y=[[y2-y1]*x + y1*x2-y2*x1] / [x2-x1]

* Questo programma può essere utilizzato come programma di libreria

* in un sistema operativo che gestisce il video.

* ORG $8000

X1 DC.W 2 ORDINATA DEL PRIMO PUNTO

Y1 DC.W 2 ASCISSA DEL PRIMO PUNTO

X2 DC.W 6 ORDINATA DEL SECONDO PUNTO

Y2 DC.W 9 ASCISSA DEL SECONDO PUNTO

BUFFER DS.W 800 SPAZIO IN MEMORIA RISERVATO A CONTENERE ASCISSA E

* ORDINATA DEI PUNTI CALCOLATI

START MOVE Y2,D1

SUB Y1,D1 (Y2-Y1)

MOVE X2,D2

MULS Y1,D2 (Y1)*(X2)

MOVE X1,D3

MULS Y2,D3 (Y2)*(X1)

SUB.L D3,D2 (Y1)*(X2)-(Y2)*(X1)

MOVE X2,D3

SUB X1,D3 (X2-X1)

MOVE X1,D0

MOVE.L #BUFFER,A0

MOVE.W D0,(A0)+ SALVA L'ASCISSA DEL PUNTO DATO, X1

MOVE.W Y1,(A0)+ SALVA L'ORDINATA DEL PUNTO DATO, Y1

LOOP ADDQ.B #1,D0 INCREMENTA LA X DI 1

MOVE.L D0,D5 REGISTRO DI APPOGGIO

MULS D1,D5 (Y2-Y1]*X

ADD.L D2,D5 (Y2-Y1]*X+ Y1*X2-Y2*X1

DIVS D3,D5 [[Y2-Y1]*X + Y1*X2-Y2*X1] / [X2-X1]

MOVE.W D0,(A0)+ X IN BUFFER

MOVE.W D5,(A0)+ Y IN BUFFER

CMP.W X2,D0 RIPETI IL LOOP FINO A QUANDO X=X2

BMI LOOP

STOP #$2000

END START

2.76 DIVU Unsigned divide

1101 R mode ea

dest=dest+sorg

- * * 0 0

V=overflow di divisione

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.77 DIVU Unsigned divide

1000 R 011 ea

dest/sorg-->dest

- * * * 0

N=1 se il quoziente ha il bit più significativo pari a uno

Z=1 se il quoziente è nullo

V=1 overflow di divisione

DIVU <ea>,Dn

size: W

esempio

* Il programma effettua il MCD tra due numeri, ognuno *

* contenuto in una WORD ;di conseguenza il range di valori *

* applicabili e' compreso tra 1 & 32767 *

* Elaborazione: Gruppo 10 - 96/97

ORG $8000

DD1 EQU 32765

DV2 EQU 360

* assegna il valore minimo al registro d0 *

START MOVE.W #DD1,D0 * inizializza il registro d0 *

CMP.W #DV2,D0 * confronta con l'altro valore*

BLE MIN * salta se e' minore o uguale *

MOVE.W #DV2,D0 * dv2 e' piu' piccolo *

MOVE.W #DD1,D1

BRA INIZIO

MIN MOVE.W #DV2,D1 * dv2 e' piu' grande *

INIZIO MOVE.W D1,D2 * d2 e' di appoggio *

DIVU D0,D2 * divisione unsigned *

ANDI.L #$0000FFFF,D2 * seleziona solo il quoziente *

MULU D0,D2 * moltiplicazione unsigned *

MOVE.W D1,D3 * d3 e' di appoggio *

SUB.W D2,D3 * calcolo della diff. *

CMP #0,D3 * se d3=0 dd1 e dv2 sono *

BEQ MCD * multipli di d0 *

MOVE.W D0,D1 * per iterare il calcolo

MOVE.W D3,D0 * finche' d3<>0 aggiorna i *

BRA INIZIO * registri d1 e d2 *

MCD MOVE.W D0,MCD1 * reg. il valore in memoria*

MCD1 DS.W 1

END START

2.78 DIVU Unsigned divide

1000 R 011 EffAddr

dest=dest/sorg

- * * ? 0

V=overflow di divisione

N= bit più sign. alto

Z= dest=0

DIVU <ea>,Dn

size: B,W,L

Esempio decbcd.a68

:

* Utilizzo dei codici operativi: DIVU e OR.

* Conversione binario->BCD

* Può essere utilizzato come routine per rappresentare un numero su un

* display.

* ORG $8000

DECIM EQU 5240 Numero da convertire

BASE EQU 10 Base BCD

START CLR.L D4 Azzera peso shift

MOVE.L #DECIM,D1

*Conversione mediante succesive divisioni per 10

LOOP DIVU #BASE,D1

SWAP D1 Porta il resto nella LSW

LSL.W D4,D1 Effettua lo shift a sinistra:0->unità 4-

>decine

* 8->centinaia...

OR.W D1,D2 Compone il numero finale

SWAP D1 Riporta il quoto nella LSW

AND.L #$0000FFFF,D1 Azzera il resto

ADDQ.B #4,D4 Incrementa lo shift

CMP.W #BASE,D1

BPL LOOP Il ciclo termina quando il quoto è minore di

10 LSL.W D4,D1

OR.W D1,D2 Termina la composizione del numero shiftandolo

* al peso finale

END START

2.79 EOR Exclusive or logical

1101 R mode ea

dest=dest+sorg

- * * 0 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.80 EOR Exclusive OR logical

1011 R Op-mode ea

EOR Dn TO <ea>

X, N, Z, V, C

- * * 0 0

EOR Dn,<ea>

size: B,W,L

esempio :

*** Subroutine che inverte il bit 4 del registro di controllo del device

* TERMINAL di ASIM. L’ indirizzo del registro è memorizzato in A0.

* Viene modificato il valore di D0

TTOGGL MOVE.W #%00010000,D0

EOR.W D0,(A0)

RTS

2.81 EOR Exclusive or logical

1011 R mode ea

dest=dest+sorg

- * * 0 0

X,N,Z,V,C

N=1 se MSB del risultato=1

Z=1 se il risultato=0

EOR Dn,<ea>

size: B,W,L

per <ea> sono permessi solo modi di indirizzamento

di tipo “data alterable”

esempio1

* Questo programma esegue il complemento a 256

* di un byte usando EOR

ORG $8000

BYT DC.B $F0

START MOVE.B (BYT),D0

EOR #$FF,D0 effettua l’operaz.D0=256-D0

END START

esempio2

ORG $9200

DATI DC.W $FFFF,$FFFF

BEGIN MOVE.W (DATI),D0

MOVE.W (DATI+2),D1

EOR.W D0,D1

END BEGIN

Dopo l’istruzione EOR:

N=0;

Z=1 (FFFF xor FFFF = 0)

2.82 EOR Or esclusivo logico

Or esclusivo tra <destinazione> e <sorgente>, il risultato viene posto in

<destinazione>;<sorgente> può essere solo un registro dati.

1011 R mode ea

dest<=*dest XOR *sorg

X,N,Z,V,C

- * * 0 0

N=1 se MSB(*dest)=1

Z=1 se *dest=0

EOR Dn,<ea>

size: B,W,L

* $VER: tglcase 1.0 (11-12-96)

*

* NOME

* A2D -- Converte, in una stringa, le maiuscole in minuscole e viceversa.

*

* FUNZIONE

* Questo programma converte i caratteri di una stringa, che rappresentano

* lettere, da maiuscole a minuscole e viceversa.

*

* INGRESSI

* A0 - Punta alla stringa da convertire. Peraltro la stringa e' intesa

* terminata con il carattere NULL (ASCII).

*

* RISULTATO

* A0 - Punta alla stringa convertita come spiegato in FUNZIONE.

*

* ESEMPIO

* 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.83 EORI Exclusive or immediate

1101 R mode ea

dest=dest+sorg

- * * 0 0

ADD <ea>,Dn

ADD Dn,<ea>

size: B,W,L

esempio

2.84 EORI Exclusive or immediate

00001010 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

EORI #<data>,<ea>

size: B,W,L

Modi di indirizzamento non permessi :

- diretto con registro indirizzo

- relativo

- relativo indicizzato

- immediato

esempio :

* L'esempio permette di complementare i bit delle long word di un vettore,

* fornendone così la rappresentazione per complementi diminuiti .

*

VETINI org $8000 indirizzo del primo elemento del vettore

VETTORE dc.l $ABCD1234,$EF567890,$0A0B0C0D,$12345678,$FEDCBA98

NUMEL dc.b 5 numero degli elementi del vettore

*

INIZIO org $8050

moveq.l #0,D0 D0 contiene l'indice del primo elemento

move.l #VETINI,A0

LOOP move.l D0,D1

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

move.l 0(A0,D1),D2

eori.l #$FFFFFFFF,D2 effettua la complementazione di tutti i bit

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

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

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

bne.s LOOP

*

FINE nop

END INIZIO

2.85 EXG Exchange 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.86 EXG Exchange register

1100 R 1 mode R

Rx↔Ry

X,N,Z,V,C

- - - - -

EXG Rx,Ry

size: L

esempio:

Il seguente sottoprogramma riceve in ingresso tre valori in d1,d2,d3 e li

ordina in maniera crescente a partire da d1

ordina cmp d1,d2

ble sec

exg d1,d2 d2 è più piccolo di d1

sec cmp d1,d3

ble ter

exg d1,d3 d3 è più piccolo di d1

ter cmp d2,d3

ble fine

exg d2,d3 d3 è più piccolo di d2

fine rts

2.87 EXG Exchange register

1100 Rx 1 mode Ry

dest"sorg

- - - - -

X,N,Z,V,C

EXG Rx,Ry

size: L

Se lo scambio è tra Dn e An allora Rx è sempre Dn

ed Ry è sempre An

esempio

* Il seguente programma inverte il contenuto di una

* stringa servendosi del codice EXG.

* Lo scambio dei singoli bytes costituenti i caratteri

* della stringa da invertire avviene dagli estremi al

* centro della stessa.

ORG $8000

STRIN DC.B ‘Questa stringa sarà invertita’,0

START LEA.L STRIN,A1 indirizzo stringa in A1

MOVE.L A1,A3 e in A3

LOOP1 MOVE.B (A1)+,D0 questo ciclo calcola

CMP.B #O,D0 l’indirizzo dell’ultimo

BNE LOOP1 carattere della stringa

MOVE.L A1,A4

LOOP MOVE.B (A3),D0 carica i caratteri

MOVE.B (A4),D1 nei registri-dato D0 e D1

EXG D0,D1 scambia caratteri

MOVE.B D0,(A3)+ registra i caratteri

MOVE.B D1,-(A4) in memoria

CMPA A3,A4 confronta indirizzi

* caratteri da scambiare

BGT LOOP se A4<=A3 il centro

END START stringa è raggiunto

2.88 EOR Or esclusivo logico

Or esclusivo tra <destinazione> e <sorgente>, il risultato viene posto in

<destinazione>;<sorgente> può essere solo un registro dati.

1011 R mode ea

dest<=*dest XOR *sorg

X,N,Z,V,C

- * * 0 0

N=1 se MSB(*dest)=1

Z=1 se *dest=0

EOR Dn,<ea>

size: B,W,L

* $VER: tglcase 1.0 (11-12-96)

*

* NOME

* A2D -- Converte, in una stringa, le maiuscole in minuscole e viceversa.

*

* FUNZIONE

* Questo programma converte i caratteri di una stringa, che rappresentano

* lettere, da maiuscole a minuscole e viceversa.

*

* INGRESSI

* A0 - Punta alla stringa da convertire. Peraltro la stringa e' intesa

* terminata con il carattere NULL (ASCII).

*

* RISULTATO

* A0 - Punta alla stringa convertita come spiegato in FUNZIONE.

*

* ESEMPIO

* 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


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