24
Esercizi Assembly

Esercizi Assembly

  • Upload
    marek

  • View
    93

  • Download
    1

Embed Size (px)

DESCRIPTION

Esercizi Assembly. Un programma per calcolare la media. - PowerPoint PPT Presentation

Citation preview

Page 1: Esercizi Assembly

Esercizi Assembly

Page 2: Esercizi Assembly

Un programma per calcolare la media

Dato un vettore di 32 bytes unsigned memorizzato a partire dalla locazione 0x20a0, calcolarne la media e memorizzarne il valore sovrascrivendo l’ultima posizione del vettore. Se viene rilevato un overflow in V[31] e’ posizionato il valore ff ff ff ff

0x20a0 V[0]V[1]V[2]

V[31]

V[31]=Σi=031V[i]/32

Page 3: Esercizi Assembly

Come gestire l’overflow?L’istruzione da controllare e’:

addb (R1)+, R2

Microcodice :

1. MAR<-R1

2. R1<-R1+1

3. Temp1<-[MDR] 8 //gli 8 lsbs di MDR estesi in segno vanno in T1

4. Temp2<-[R2] 8 //gli 8 lsbs di R2 estesi in segno vanno in T2

5. ALU_OUT=Temp1+Temp2

Se (Temp1 + Temp2) >232-1 il CARRY bit viene settato per segnalare l’overflow. Quindi , e’ sufficiente far seguire all’operazione di somma un salto condizionato del tipo:

jc error

Page 4: Esercizi Assembly

Il codiceorg 400hARRAY EQU 20a0h ; indirizzo base arrayDIM EQU 32 ; num.elementi arrayLOG2DIM EQU 5 ; log. base 2 di DIM

codemovl #DIM,R0movl #ARRAY,R1xorl R2,R2 ;resetta R2, risultato parziale

loop: addb (R1)+,R2 ;somma i-esimo elem. i=0..DIM-1jc error ;bit c settato =>Overflowsubl #1,R0 ;decrementa contatorejnz loop ;se contatore!=0 continua il ciclalsrb #LOG2DIM, R2;dividi per il numero di elementi,

;usiamo LSRB poichè lavoriamo con unsignedmovb R2, -(R1) ;memorizza la media in ARRAY[DIM-1]jmp fine

error: movl #DIM, R1 ;gestione overflow, calcola in R1addl #ARRAY, R1 ; R1=ARRAY+DIMsubl #1,r1xorl R3,R3notl R3,R3 ; R3=111....111movb R3,(R1) ; ARRAY[DIM]=11111111

fine: haltend

Page 5: Esercizi Assembly

Una variazione sul tema… ora, senza contatore!

Calcolare la media di 128 words memorizzate a partire dall’indirizzo 0x20ab, ma senza impiegare un registro appositamente come contatore (R0 del programma precedente) .

0x20 ab V[0]V[1]V[2]

V[127]

V[127]=Σi=0127V[i]/127

0x21a9

0x20ad

0x21 ab

NOTA: non si considera l’overflow.

Page 6: Esercizi Assembly

Il codice (funziona solo se il numero di elementi è pari a 128 words)

org 400h ; programma allocato a partire da 400hDATI EQU 20abh ;indirizzo inizio

code ;inizio istruzionimain:

xorl R2,R2 ; R2=risult.parzialemovl #DATI,R1 ; puntatore elementomovb R1,R0 ; copio lsB addr. inizio

; in R0loop: addw (R1)+, R2

cmpb R1,R0 ; lsB addr. elemento; e' = lsB addr. inizio ?

jnz looplsrw #7,R2 ; divido per 128movw R2,-(R1)halt ;serve solo per bloccare il simulatore

end ;fine della compilazione

Page 7: Esercizi Assembly

Un altro esempio: la moda

Assumiamo di avere un vettore,V, di N bytes che memorizza nella posizione i-esima l’altezza in centimetri dell’i-esimo studente.

PROBLEMA:

Trovare l’altezza piu’ frequente tra gli studenti (moda).

altezza

id-studente

Page 8: Esercizi Assembly

Prima soluzione: vettore di frequenze

Vogliamo calcolare la moda, costruendo innanzitutto un vettore di frequenze, F, di 255 longwords, che associ in posizione j, il numero di ricorrenze dell’altezza j nel vettore di partenza V.

Probabilmente: F[j]=0 se i<50 o i>220

Osservazione:

Noto il vettore delle frequenze F, il calcolo della moda si riconduce a determinare per quale i, F[i]=max{F}

num.studenti

cm.

Page 9: Esercizi Assembly

L’algoritmo per il calcolo delle frequenze

Possiamo costruire F in 2 passi.

1) Inizializziamo l’array F, di 255 longwords, con tutti 0.

for (i=0;i<256;i++) { array2[i]=0;}

2) Memorizziamo le frequenze in F scandendo una sola volta V e incrementando di volta in volta l’elemento di F in posizione V(i) di 1.

for (i=0;i<N;i++) { index=array1[i];

array2[index]++; }

Page 10: Esercizi Assembly

Codiceorg 1400harray1 equ 800h ; V, vettore originalearray2 equ 1500h ; F, vettore frequenzedim equ 30code

;inizializzo array2 con tutti 0; for (i=0;i<256;i++) {; array2[i]=0;; };

MOVL #array2,R5 ;R2 base dell'arraymovl #0,r4

clean: movl #0, (R5)+addl #1,r4cmpl #0ffh,r4jc clean

; memorizzo frequenze in array2; for (i=0;i<N;i++) {; index=array1[i];; array2[index]++;; }

MOVL #dim,R2 ;R2 dimensione di array1XORL R3,R3 ;R3=0, contatore e offset per array1;

count: xorl r4,r4 ; r4 è inizializzato a zero perchè la successiva mvlb ; si aspetta i 3 bytes + significativi di R4 uguali a 0

mvlb array1(R3),R4 ;R4=V[i]=array1[R3] ;NOTA: MVLB non estende il segno

aslw #2,R4 ;offset_array2=R4*4;Moltiplicando per 4 il contenuto ;del lsb di R4 possiamo avere trabocchi, ;quindi usiamo aslw per operare con 2

bytemovl array2(R4),r5 ;r5=array2[offset_array2]

addl #1,r5 ; r5=array2[offset_array2]+1addl #array2,r4 ; prima r4 era = offset_array2, ora

;r4=offset_array2+base_add_array2movl r5,(r4) ;array2[offset_array2]=array2[offset_array2]+1addl #1,R3 ; i=i+1

cmpl #R2,R3jnz count

haltend

Page 11: Esercizi Assembly

Prima soluzione:determiniamo il max su F

Ora che abbiamo il vettore delle frequenze, il calcolo della moda si riconduce a determinare per quale i, F[i]=max{F}

num.studenti

cm.170=moda

Page 12: Esercizi Assembly

Codiceorg 1400harray2 equ 1500h

codeMOVL #255,R1 ;copia il lsb byte in R1ASLL #2,R1ADDL #array2,R1 ; in R1 c’è l’indirizzo dell 256° elemento di Array2MOVL #array2,R2 ;R2 puntatore all'arrayXORL R3,R3 ;R3=0;MOVL #1,R4 ;R4=1

loop:MOVL (R2)+,R5CMPB R5,R3JNC skip ; se R3>=R5 salta a skipMOVL -(R2),R3 ; in R3 c'è il massimo temp.MOVL R2,R4 ; in R4 c'è l'indice corrisp.all'elemento massimoADDL #4,R2

skip: CMPB R2,R1

jnz loop ; condizione di uscita dal cicloSUBL #ARRAY2,R4 ; R4=[OFFSET_MAX_FREQUENZA*4]ASRL #2,R4 ; R4 / 4=OFFSET_MAX_FREQUENZAhalt

end

Page 13: Esercizi Assembly

Ancora Moda… evitiamo il calcolo del vettore delle frequenze

Dato un vettore di DIM dati da un byte, rappresentati come unsigned trovare:

1) l’elemento con il massimo numero di ricorrenze (moda)

2) il corrispondente numero di ricorrenze

L’ALGORITMO

MAX_NUM=0; //memorizza la modaMAX_RIC=0; //memorizza il numero di ricorrenze della modaFOR INT I=0 TO DIM-1 {

IF ((I==0) || ( (I!=0) && (A[I]!=MAX_NUM) ) ) {// Conta il numero di ricorrenze dell’elemento i-esimo se e solo se I=0, oppure// I!=0 e l’elemento A[I] non è già la moda

TEMP_RIC=0;FOR INT J=I TO DIM-1

{ IF A[J]=A[I] TEMP_RIC++; }IF (TEMP_RIC>MAX_RIC) {MAX_RIC=TEMP_RIC;

MAX_NUM=A[I];}}

Page 14: Esercizi Assembly

CodiceORG 400H

ARRAY EQU 1000HDIMEQU 10MAXNUM EQU 950HMAXRIC EQU 951H

CODE

XORL R0,R0 ; MAXNUM=0XORL R1,R1 ; MAXRIC=0XORL R2,R2 ; I=0

FOR1: MOVB ARRAY(R2),R5; R5=A[I]=ARRAY(R2)

CMPL #0,R2JZ DOIT ; IF (I==0) JMP DOITCMPB R5,R0 ; ELSE IF A[I]== MAXNUMJZ NOMAX ; JMP NOMAX (SKIP INNER CICLE)

DOIT:MOVL R2,R3 ;J=IXORL R4,R4 ;TEMPRIC=0

FOR2: CMPB ARRAY(R3), R5 ; IF A[I]!=A[J]

JNZ NOADD ; SKIP ADDADDL #1,R4 ; TEMPRIC++

NOADD:ADDL #1,R3 ; J++CMPL #DIM,R3 ; IF (J!=N) GOTO FOR2JNZ FOR2CMPL R4,R1 ; IF MAXRIC>TEMPRIC

JNC NOMAX ; SKIP UPDATING MAXMOVL R4,R1 ; MAXRIC=TEMPRICMOVB ARRAY(R2),R0; MAXNUM=A[I]

NOMAX: ADDL #1,R2 ; I++

CMPL #DIM,R2 ; IF (R2!=DIM) JNZ FOR1 ; GOTO FOR1

MOVB R0, MAXNUMMOVL R1, MAXRICHALT

END

Page 15: Esercizi Assembly

Inversione di un array Dato un array di 10 elementi, memorizzato a partire

da 250h, rimpiazzarlo con l’array inverso (senza usare un altro vettore di appoggio).

12152

134893

11prima

984

1325

211

11

3dopo

250h254h258h25Ch260h264h268h26Ch270h274h

250h254h258h25Ch260h264h268h26Ch270h274h

Page 16: Esercizi Assembly

Il primo passo di esecuzione

12152

134893

11 R1

R2

12152

134893

111

2152

13489

11

3R1

R2

R3=10/2=5 R3=R3-1=4scambia (R1) con (R2)

Page 17: Esercizi Assembly

Rappresentazione dell’informazione

12152

134893

11250h254h258h25Ch260h264h268h26Ch270h274h

336 (dec)340344348352356360364368372

00010101000000000000000000000000

258h259h25ah25bh

344345346347

Base_Addr(Array) +(DIM-1)*size_of(elem) =Addr(Array[DIM-1])

336 +9 * 4 =372

9*4=36 (OFFSET)

Page 18: Esercizi Assembly

ORG 400HDIM EQU 10ARRAY EQU 250H

CODEMOVL #ARRAY,R2 MOVL #DIM,R4SUBL #1,R4ASLL #2,R4 ; offset da sommare alla base dell'array per ottenere l'ultimo elementoADDL R4,R2 ; in R2 c'è l'indirizzo dell'ultimo elemento dell'array MOVL #ARRAY,R1 ; R1 <-indirizzo arrayMOVL #DIM,R3 ; R3<-10 (000... 00001010)ASRL #1,R3 ; R3=R3/2=5 (000... 000000101)

REPEAT:MOVL (R1),R0; R0 registro d'appoggio per lo scambioMOVL (R2),(R1); Copia memoria memoria dell'"ultimo" elemento sul "primo"MOVL R0,(R2); recupera il valore del primo elemento da R0 e copialo in codaADDL #4,R1; avanza di 4 byte il valore dell'offset sul vettore originale SUBL #4,R2; decrementa di 4 byte il valore dell'offset sul vettore invertitoSUBL #1,R3; decrementa il contatoreJNZ REPEAT; fino a 0

HALTEND

Il codice

Page 19: Esercizi Assembly

Un algoritmo per la moltiplicazione

Il set di istruzioni del PD32 non prevede istruzioni per effettuare la moltiplicazione tra due operandi.

La moltiplicazione puo’ essere realizzata banalmente sommando al moltiplicando se stesso, un numero di volte pari al valore del moltiplicatore. 5*3=5+5+5=15.

Tale algoritmo ha complessità computazionale pari a O(N), dove N è il valore del moltiplicatore.

Vogliamo proporre un algoritmo per la moltiplicazione la cui complessità sia pari a O(log2N).

Page 20: Esercizi Assembly

Moltiplicazione: primo approccio

00110 x00101 =

00110 00000 00110 0000000000000011110

sommeparziali

00000 + 00110 00110 + 00000 000110 + 00110 0011110 + 00000 00011110 +00000000011110

somma parziale

“prodotto parziale”

Risultatofinale

Page 21: Esercizi Assembly

In altre parole...

Traslo a destra il moltiplicatore di una posizione per verificare se il suo lsb vale 1. Il suo lsb finisce in C.

Sommo il moltiplicando alla somma parziale.

C=1C=0

Traslo a destra la somma parziale, copiando il bit fuoriuscito (lsb della somma parziale) nel msb del moltiplicatore (che diventa passo dopo passo la parte meno significativa del risultato)

Page 22: Esercizi Assembly

L’algoritmo (precondizioni)

0 00 1 1 0

0 0 0 0 0

A C

0 0 1 0 1 DB

moltiplicando, A=6 moltiplicatore,D=5

• Ripeti i seguenti passi tante volte quanti sono i bit di D.1. Azzero C2. Trasla a destra D3. Se C=1 somma A e B4. Trasla a destra B5. Se C=1 inverto il bit più significativo di D

Page 23: Esercizi Assembly

L’algoritmo (postcondizione)

0 00 1 1 0

0 0 0 0 0

A C

1 1 1 1 0 DB

moltiplicando, A=6

Il risultato della moltiplicazione necessita di un numero di bits doppio per poter essere rappresentato. Per semplicità moltiplicando e moltiplicatore hanno 5 bits nel nostro esempio=> risultato scritto in 10 bits. I 5 MSB sono scritti in B, i 5 LSB sovrascrivono il moltiplicatore.

Risultato=30

Page 24: Esercizi Assembly

Il codice

ORG 400Hrls EQU 2000h ;addr.parte meno sig.del risult.rms EQU 2004h ;addr.parte + sig.del risult. A DL 6 ; variabile contenente il moltiplicandoD DL 5 ; variabile contente il moltiplicatore

CODEMOVL A,R0 ; carico il moltiplicando in R0MOVL D,R3 ; carico il moltiplicatore in R3XORL R2,R2 ; azzero R2 (B)MOVL #32,R1; R1 è il contatore: inizializzo a

; 32, #bits moltiplicatoremult: CLRC

LSRL #1, R3JNC dopo

ADDL R0,R2dopo: LSRL #1,R2

JNC poiXORL #80000000h, R3 ;inverto il bit + significativo di R3 (d)

poi: SUBL #1, R1JNZ multMOVL R3, rls ; la parte meno significativa

; contenuta in R3 viene caricata ; nella longword di memoria

; di indirzzo rlsMOVL R2,rms ; la parte più significativa in rms

END