1. ;SISTEMI A MICROPROCESSORE
;Scrittura del valore 85 (55h) in AX
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
.CODE
.STARTUP
MOV AX, 85
.EXIT
END
-1-
2. ;SISTEMI A MICROPROCESSORE
;Scrittura del valore 3 (3h) in memoria
;e da qui in AX
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
VAR DW ?
.CODE
.STARTUP
MOV VAR, 3
MOV AX, VAR
.EXIT
END
-2-
3. ;SISTEMI A MICROPROCESSORE
;Pulizia del registro AX (con modifica di ZF)
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
.CODE
.STARTUP
MOV AX, 0Ah
XOR AX, AX
.EXIT
END
-3-
4. ;SISTEMI A MICROPROCESSORE
;Scrivere un programma assembler che esegua la somma
;di 2 numeri (su 8 bit) che si trovano nelle locazioni
;di memoria OP1 e OP2, e ponga il risultato
;nella locazione RIS
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
OP1 DB 9
OP2 DB 6
RIS DB ?
.CODE
.STARTUP
MOV AL, OP1 ;SPOSTO IL 1° OPERANDO IN AL
ADD AL, OP2 ;ESEGUO LA SOMMA
MOV RIS, AL ;MEMORIZZO IL RISULTATO
.EXIT
END
-4-
5. ;SISTEMI A MICROPROCESSORE
;Scrivere un programma assembler che esegua la differenza
;fra 2 numeri (su 16 bit) che si trovano nelle locazioni
;di memoria SOT1 e SOT2, e ponga il risultato nella
;locazione RIS
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
SOT1 DW 0A1h
SOT2 DW 42h
RIS DW ?
.CODE
.STARTUP
MOV AX, SOT1 ;SPOSTO IL 1° OPERANDO IN AX
SUB AX, SOT2 ;ESEGUO L'OPERAZIONE AX-SOT2
MOV RIS, AX ;COPIO IL VALORE DI AX IN RIS
.EXIT
END
-5-
6. ;SISTEMI A MICROPROCESSORE
;Scrivere un programma assembler che calcoli l'espressione
;W=X-2Y+3Z. Si supponga che X,Y,Z e W siano numeri su 16 bit
;X=100 (64h), Y=45 (2Dh), Z=15 (Fh)
;Risultato: W=55 (37h)
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
X DW 64h
Y DW 2Dh
Z DW 0Fh
W DW ?
.CODE
.STARTUP
MOV AX, X
SUB AX, Y
SUB AX, Y
ADD AX, Z
ADD AX, Z
ADD AX, Z
MOV W, AX
.EXIT
END
-6-
7. ;SISTEMI A MICROPROCESSORE
;Si scriva un programma Assembler che calcoli il valore
;della funzione Y=4X^3-3X^2+2X+7
;PS: si faccia l'ipotesi semplificatrice che il risultato
;sia rappresentabile su 16 bit.
;X=23 (17h)
;Risultato: Y=47134 (B81Eh)
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
ICS DW 23
.CODE
.STARTUP
MOV AX, ICS ;COPIO IN AX IL VALORE DI ICS
PUSH AX ;TRASFERISCO UNA WORD NELLO STACK *
MOV BX, AX ;COPIO IN BX IL VALORE DI AX
MUL AX ;MOLTIPLICO AX PER IL CONTENUTO DI AX E PONGO
;IL RISULTATO IN AX **
PUSH AX ;TRASFERISCO UNA WORD NELLO STACK
MUL BX ;MOLTIPLICO BX PER IL CONTENUTO DI AX E PONGO
;IL RISULTATO IN AX **
MOV CL, 2 ;PREDISPONGO IL REGISTRO CL
SHL AX, CL ;ESEGUO IN AX LO SHIFT LOGICO A SINISTRA DI 2
;(MOLT. X4)
POP BX ;TRASFERISCO L'ULTIMA WORD DELLO STACK IN BX
MOV CX, BX ;COPIO IN CX IL VALORE DI BX
SHL CX, 1 ;ESEGUO IN CX UNO SHIFT LOGICO A SINISTRA
;(MOLT. X2)
ADD CX, BX ;SOMMO A CX IL CONTENUTO DI BX (2X^2+X^2)
SUB AX, CX ;SOTTRAGGO AD AX IL CONTENUTO DI CX
POP CX ;TRASFERISCO LA PRIMA WORD DELLO STACK IN CX ***
SHL CX, 1 ;ESEGUO IN CX UNO SHIFT LOGICO A SINISTRA
;(MOLT. X2)
ADD AX, CX ;SOMMO AD AX IL CONTENUTO DI CX
ADD AX, 7 ;SOMMO AD AX IL VALORE 7
.EXIT
END
;* Assembler 8086 2° Ed. - Pagina 95
; Dispensa "ASSEMBLER 8086: CARATTERISTICHE E ISTRUZIONI
; FONDAMENTALI" - Pagina 22 - Slide 43
;** Assembler 8086 2° Ed. - Pagina 130
; Dispensa "ASSEMBLER 8086: CARATTERISTICHE E ISTRUZIONI
; FONDAMENTALI" - Pagina 7 - Slide 13
;*** Assembler 8086 2° Ed. - Pagina 94
; Dispensa "ASSEMBLER 8086: CARATTERISTICHE E ISTRUZIONI
; FONDAMENTALI" - Pagina 22 - Slide 43
-7-
8. ;SISTEMI A MICROPROCESSORE
;Si scriva un programma Assembler che calcoli la
;distanza di Hamming tra 2 dati memorizzati su 16 bit.
;Si ricorda che la distanza di Hamming tra
;2 parole è pari al numero di bit diversi.
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
VAR1 DW 3
VAR2 DW 13
.CODE
.STARTUP
MOV AX, 0 ;AZZERO AX
MOV BX, VAR1 ;COPIO IN BX IL VALORE DI VAR1
XOR BX, VAR2 ;EFFETTUO LA XOR TRA BX E VAR2 E PONGO
;IL RISULTATO IN BX *
MOV CX, 16 ;PREDISPONGO CX
CICLO:
SHR BX, 1 ;ESEGUO UNO SHIFT LOGICO A DESTRA DI BX
JNC FINE_CICLO ;SE CF=0 SALTO A "FINE_CICLO" ALTRIMENTI PROSEGUO
;CON LA RIGA SUCCESSIVA **
INC AX ;INCREMENTO AX
FINE_CICLO:
LOOP CICLO ;DECREMENTO CX ED ESEGUO IL LOOP SE ESSO È DIVERSO
;DA 0
.EXIT
END
;* Assembler 8086 2° Ed. - Pagina 150
; Dispensa "ASSEMBLER 8086: CARATTERISTICHE E ISTRUZIONI
; FONDAMENTALI" - Pagina 9 - Slide 17
; Tabella di verità XOR
;** Assembler 8086 2° Ed. - Pagina 101
; Dispensa "ASSEMBLER 8086: CARATTERISTICHE E ISTRUZIONI
; FONDAMENTALI" - Pagina 15 - Slide 29
-8-
9. ;SISTEMI A MICROPROCESSORE
;Si scriva un programma Assembler che calcoli
;la parità di una parola. Una parola è considerata
;di parità dispari se il numero di bit a 1 è dispari.
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
VAR DB 7
.CODE
.STARTUP
MOV BL, 0 ;AZZERO BL
MOV AL, VAR ;COPIO IN AL IL VALORE DI VAR
MOV CX, 8 ;PREDISPONGO CX
CICLO:
SHR AL, 1 ;ESEGUO UNO SHIFT LOGICO A DESTRA DI AL
JNC SALTA ;SALTO A "SALTA" SE CF=0 ALTRIMENTI PROSEGUO
INC BL ;INCREMENTO BL
SALTA:
LOOP CICLO ;DECREMENTO CX ED ESEGUO IL LOOP SE ESSO È DIVERSO
;DA 0
MOV AL, 0 ;PARITÀ PARI
SHR BL, 1
JNC FINE
MOV AL, 1 ;PARITÀ DISPARI
FINE:
.EXIT
END
-9-
10. ;SISTEMI A MICROPROCESSORE
;Programma che controlla la parità di una parola
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
VAR DB 2
.CODE
.STARTUP
MOV BL, 0
ADD BL, VAR
MOV AL, 0 ;PARITÀ PARI
JP FINE ;SALTA SE PF=0 (PARITÀ PARI)
MOV AL, 1 ;PARITÀ DISPARI
FINE: .EXIT
END
- 10 -
11. ;SISTEMI A MICROPROCESSORE
;Scrittura di un valore in memoria
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
VAR DW ?
.CODE
.STARTUP
MOV VAR, 0
.EXIT
END
- 11 -
12. ;SISTEMI A MICROPROCESSORE
;Somma di due valori
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
OPD1 DW 10
OPD2 DW 24
RESULT DW ?
.CODE
.STARTUP
MOV AX, OPD1
ADD AX, OPD2
MOV RESULT, AX
.EXIT
END
- 12 -
13. ;SISTEMI A MICROPROCESSORE
;Somma degli elementi di un vettore (I)
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
VETT DW 5, 7, 3, 4, 3
RESULT DW ?
.CODE
.STARTUP
MOV AX, 0
ADD AX, VETT
ADD AX, VETT+2
ADD AX, VETT+4
ADD AX, VETT+6
ADD AX, VETT+8
MOV RESULT, AX
.EXIT
END
- 13 -
14. ;SISTEMI A MICROPROCESSORE
;Somma degli elementi di un vettore (II)
;Autore: Sergio Porcu
DIM EQU 5
.MODEL SMALL
.STACK
.DATA
VETT DW 2, 5, 16, 12, 34
RESULT DW ?
.CODE
.STARTUP
MOV AX, 0
MOV CX, DIM
MOV DI, 0
SOMMA:
ADD AX, VETT[DI]
ADD DI, 2
DEC CX
CMP CX, 0
JNZ SOMMA
MOV RESULT, AX
.EXIT
END
- 14 -
15. ;SISTEMI A MICROPROCESSORE
;Somma degli elementi di un vettore (III)
;Autore: Sergio Porcu
DIM EQU 5
.MODEL SMALL
.STACK
.DATA
VETT DW 2, 5, 16, 12, 34
RESULT DW ?
.CODE
.STARTUP
MOV AX, 0
MOV CX, DIM
MOV DI, 0
SOMMA:
ADD AX, VETT[DI]
ADD DI, 2
LOOP SOMMA
MOV RESULT, AX
.EXIT
END
- 15 -
16. ;SISTEMI A MICROPROCESSORE
;Lettura e visualizzazione di un vettore di caratteri
;Autore: Sergio Porcu
DIM EQU 5
.MODEL SMALL
.STACK
.DATA
VETT DB DIM DUP(?)
.CODE
.STARTUP
MOV CX, DIM
MOV DI, 0
MOV AH, 1
LAB1: INT 21h
MOV VETT[DI], AL
INC DI
DEC CX
CMP CX, 0
JNZ LAB1
MOV CX, DIM
MOV AH, 2
LAB2: DEC DI
MOV DL, VETT[DI]
INT 21h
DEC CX
CMP CX, 0
JNZ LAB2
.EXIT
END
- 16 -
17. ;SISTEMI A MICROPROCESSORE
;Lettura e visualizzazione di un vettore di caratteri
;Versione con CR e LF
;Autore: Sergio Porcu
CR EQU 13
LF EQU 10
DIM EQU 5
.MODEL SMALL
.STACK
.DATA
VETT DB DIM DUP(?)
.CODE
.STARTUP
MOV CX, DIM
MOV DI, 0
MOV AH, 1
LAB1: INT 21h
MOV VETT[DI], AL
INC DI
LOOP LAB1
MOV CX, DIM
MOV AH, 2
MOV DL, CR
INT 21h
MOV DL, LF
INT 21h
MOV DI, 0
LAB2: MOV DL, VETT[DI]
INT 21h
INC DI
LOOP LAB2
.EXIT
END
- 17 -
18. ;SISTEMI A MICROPROCESSORE
;Ricerca del carattere minimo
;Autore: Sergio Porcu
CR EQU 13
LF EQU 10
.MODEL SMALL
.STACK
DIM EQU 5
.DATA
TABLE DB DIM DUP(?)
.CODE
.STARTUP
MOV CX, DIM
LEA DI, TABLE
MOV AH, 1
LAB1: INT 21h
MOV [DI], AL
INC DI
LOOP LAB1
MOV CL, 0FFH
MOV DI, 0
CICLO:
CMP CL, TABLE[DI]
JB DOPO
MOV CL, TABLE[DI]
DOPO:
INC DI
CMP DI, DIM
JB CICLO
OUTPUT:
MOV AH, 2
MOV DL, CR
INT 21h
MOV DL, LF
INT 21h
MOV DL, CL
INT 21h
.EXIT
END
- 18 -
19. ;SISTEMI A MICROPROCESSORE
;Programma che simula il lancio di una moneta
;TESTA=1 CROCE=0
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
TESTA DB "TESTA",0Dh,0Ah,"$"
CROCE DB "CROCE",0Dh,0Ah,"$"
.CODE
.STARTUP
MOV AH, 2Ch ;LEGGE L'ORA DEL SISTEMA *
INT 21h ;LETTURA IN DX DEL TIMER
TEST DL, 1 ;AND LOGICO TRA IL LSB DI DL E 1 **
JNZ LAB_T ;SALTA SE ZF=0
LEA DX, CROCE ;ALTRIMENTI COPIA IN DX L'OFFSET DI CROCE
JMP VIDEO
LAB_T:
LEA DX, TESTA ;COPIA IN DX L'OFFSET DI TESTA
VIDEO:
MOV AH, 9h ;***
INT 21h
.EXIT
END
;* Assembler 8086 2° Ed. - Pagina 205
; Il problema di generare un numero casuale è stato
; risolto leggendo il timer di sistema attraverso la
; funcion call 2ch. Tale funzione restituisce in CH le
; ore (0-23), in CL i minuti (0-59), in DH i secondi (0-59)
; e in DL i 100/secondo (0-99)
;** Assembler 8086 2° Ed. - Pagina 152
; NOTA BENE: l'istruzione TEST non modifica il contenuto
; degli operandi, bensì aggiorna opportunamente il valore
; di tutti i flag di stato
;*** Stampa a video il messaggio TESTA o il messaggio CROCE a
; seconda del valore contenuto nel LSB del numero generato
; dal timer di sistema
- 19 -
20. ;SISTEMI A MICROPROCESSORE
;Il seguente programma verifica se la stringa
;inserita da tastiera è palindroma
;Autore: Sergio Porcu
DIM EQU 50
LF EQU 10
CR EQU 13
.MODEL SMALL
.STACK
.DATA
VET DB DIM DUP (?)
MESINS DB "INSERISCI LA FRASE (MAX 50 CARATTERI): $"
EQUAL DB "LA FRASE E' PALINDROMA$"
NEQUAL DB "LA FRASE NON E' PALINDROMA$"
UNO DB "HAI INSERITO UN SOLO CARATTERE!!!$"
.CODE
ACAPO PROC ;PROCEDURA PER TORNARE ACCAPO
PUSH AX
PUSH DX
MOV AH, 2
MOV DL, CR
INT 21h
MOV DL, LF
INT 21h
POP DX
POP AX
RET
ACAPO ENDP
.STARTUP
INSER:
LEA DX, MESINS ;VISUALIZZAZIONE MESSAGGIO INSERIMENTO
MOV AH, 9
INT 21h
CALL ACAPO
MOV CX, DIM
MOV DI, 0
MOV AH, 1
STRING:
INT 21h ;INSERIMENTO DELLA STRINGA
MOV VET[DI], AL
CMP AL, CR
JE INIZ
INC DI
LOOP STRING
INIZ: DEC DI
CMP DI, 0
JE UNCAR
MOV SI, DI
MOV DI, 0
CONFR:
MOV AH, VET[DI] ;CONFRONTO NELLA STRINGA
- 20 -
21. CMP AH, VET[SI]
JNE NOTEQ
CMP DI, SI
JA YESEQ
INC DI
DEC SI
LOOP CONFR
NOTEQ:
CALL ACAPO ;LA STRINGA È PALINDROMA
LEA DX, NEQUAL
MOV AH, 9
INT 21h
JMP GATE
YESEQ:
CALL ACAPO ;LA STRINGA NON È PALINDROMA
LEA DX, EQUAL
MOV AH, 9
INT 21h
JMP GATE
UNCAR:
CALL ACAPO ;UN SOLO CARATTERE INSERITO
LEA DX, UNO
MOV AH, 9
INT 21h
GATE: .EXIT ;USCITA DAL PROGRAMMA
END
- 21 -
22. ;SISTEMI A MICROPROCESSORE
;Programma che legge da tastiera un carattere e
;lo sostituisce con un * se non è alfanumerico,
;stampando il risultato a video
;Autore: Sergio Porcu
LF EQU 10
CR EQU 13
.MODEL SMALL
.STACK
.DATA
.CODE
.STARTUP
MOV AH, 1 ;PREPARO AH PER LA LETTURA
INT 21h ;LEGGO UN CARATTERE E LO METTO IN AL
MOV DH, AL ;METTO IL CARATTERE IN DH
CMP DH, '0' ;SE DH < '0'
JB STAR ;LO SOSTITUISCO CON '*'
CMP DH, '9' ;SE DH <= '9'
JBE VIS ;È UNA CIFRA
CMP DH, 'A' ;SE DH < 'A'
JB STAR ;LO SOSTITUISCO CON '*'
CMP DH, 'Z' ;SE DH <= 'Z'
JBE VIS ;È UNA LETTERA MAIUSCOLA
CMP DH, 'A' ;SE DH < 'A'
JB STAR ;LO SOSTITUISCO CON '*'
CMP DH, 'Z' ;SE DH <= 'Z'
JBE VIS ;È UNA LETTERA MINUSCOLA
STAR: MOV DH, '*' ;SOSTITUISCO IL CARATTERE CON '*'
VIS: MOV AH, 2 ;PREPARO AH PER LA STAMPA
MOV DL, CR
INT 21h ;STAMPO UN CARRIAGE RETURN
MOV DL, LF
INT 21h ;STAMPO UN LINE FEED
MOV DL, DH
INT 21h ;STAMPO IL CARATTERE
.EXIT
END
- 22 -
23. ;SISTEMI A MICROPROCESSORE
;Somma di una serie di numeri inseriti da tastiera
;Autore: Sergio Porcu
CR EQU 13
LF EQU 10
.MODEL SMALL
PUBLIC INPUT
.STACK
.DATA
INTESTA DB "SOMMA DI UNA SERIE DI NUMERI INSERITI DA
TASTIERA",0DH,0AH,"$"
QUERY DB "QUANTI NUMERI VUOI SOMMARE? : $"
LINEA DB "INSERISCI IL $"
NUMERO DB "^ NUMERO : $"
RISUL DB "IL RISULTATO FINALE E': $"
ERR_MESS DB 0DH,0AH, "NUMERO TROPPO GRANDE O NON
CORRETTO",0DH,0AH,"$"
NUM DW ?
VAR DW ?
PNT DW ?
CBUF DB 5 DUP(0)
.CODE
INPUT PROC FAR
PUSH AX
PUSH BX
LAB0: XOR DX, DX
LAB1: MOV BX, 10
MOV AH, 1
INT 21h
CMP AL, CR
JE FINE
CMP AL, '0'
JB I_ERR
CMP AL, '9'
JA I_ERR
SUB AL, '0'
XCHG AX, BX
XOR BH, BH
MUL DX
CMP DX, 0
JNE I_ERR
MOV DX, AX
ADD DX, BX
JC I_ERR
JMP LAB1
I_ERR:
LEA DX, ERR_MESS
MOV AH, 9
INT 21h
MOV AL, 00h
MOV AH, 4Ch
- 23 -
24. INT 21h
FINE: POP BX
POP AX
RET
INPUT ENDP
OUTPUT PROC FAR
PUSH DI
PUSH AX
PUSH BX
PUSH DX
XOR DI, DI ;AZZERAMENTO DI
MOV AX, DX
CONV:
XOR DX, DX ;AZZERAMENTO DI DX
MOV BX, 10
CICLO:
DIV BX
ADD DL, '0' ;TRASFORMAZIONE DEL RESTO IN CODICE ASCII
MOV CBUF[DI], DL ;MEMORIZZAZIONE NEL BUFFER
INC DI
XOR DX, DX
CMP AX, 0
JNE CICLO
LAB: DEC DI
MOV DL, CBUF[DI]
MOV AH, 2
INT 21h ;VISUALIZZAZIONE DI UNA CIFRA
CMP DI, 0
JNE LAB
POP DX
POP BX
POP AX
POP DI
RET
OUTPUT ENDP ;FINE PROCEDURA OUTPUT
.STARTUP
MOV DX, OFFSET INTESTA
MOV AX, SEG INTESTA
MOV DS, AX
MOV AH, 9
INT 21h
MOV DX, OFFSET QUERY
MOV AX, SEG QUERY
MOV DS, AX
MOV AH, 9
INT 21h
CALL INPUT
MOV NUM, DX ;MEMORIZZAZIONE DELLA QUANTITÀ DI NUMERI
;DA INSERIRE
CALL ACAPO
MOV DI, 0
- 24 -
25. MOV PNT, 0 ;VARIABILE CONTENENTE IL NUMERO PROGRESSIVO
;DA INSERIRE
SOMMA:
MOV DX, OFFSET LINEA
MOV AX, SEG LINEA
MOV DS, AX
MOV AH, 9
INT 21h
INC PNT ;INCREMENTO DELLA VARIABILE
MOV DX, PNT ;COPIA DI PNT IN DX PER
CALL OUTPUT ;LA VISUALIZZAZIONE
MOV DX, OFFSET NUMERO
MOV AX, SEG NUMERO
MOV DS, AX
MOV AH, 9
INT 21h
CALL INPUT
ADD VAR,DX ;SOMMA DI DX IN VAR (CALCOLO)
CALL ACAPO ;STAMPA UN CARRIAGE RETURN
INC DI ;INCREMENTO CONTATORE
CMP DI, NUM ;CONFRONTO TRA DI E IL TOTALE DEI NUMERI DA
;INSERIRE
JNE SOMMA ;SE DI = NUM PROSEGUE ALTRIMENTI SALTA A
;SOMMA
MOV DX, OFFSET RISUL
MOV AX, SEG RISUL
MOV DS, AX
MOV AH, 9
INT 21h
MOV DX, VAR ;COPIA IL RISULTATO DEL CALCOLO IN DX
CALL OUTPUT
.EXIT
ACAPO PROC ;PROCEDURA PER ANDARE A CAPO
PUSH AX
PUSH DX
MOV AH, 2
MOV DL, CR
INT 21h
MOV DL, LF
INT 21h
POP DX
POP AX
RET
ACAPO ENDP
END
- 25 -
26. ;Programma che legge da tastiera due numeri tra
;0 e 9, li moltiplica tra di loro e stampa sul
;video il risultato della moltiplicazione
;Autore: Sergio Porcu
DIM EQU 2
LF EQU 10
CR EQU 13
.MODEL SMALL
.STACK
.DATA
DATI DB DIM DUP (?)
.CODE
.STARTUP
MOV SI, 0 ;SI PUNTA ALLA CASELLA CORRENTE DI DATI
NEXT:
MOV AH, 1 ;PREPARO AH PER LA LETTURA
INT 21h ;LEGGO UN NUMERO
MOV DATI[SI], AL ;E POI LO SALVO IN DATI[SI]
MOV AH, 2 ;PREPARO AH PER LA SCRITTURA
MOV DL, LF ;VADO ALLA PROSSIMA RIGA
INT 21h
MOV DL, CR ;VADO A CAPO
INT 21h
INC SI ;INCREMENTO SI
CMP SI, DIM ;SE SI != DIM
JNE NEXT ;SALTO A NEXT
MOV AL, DATI ;METTO IL PRIMO DATO IN AL
CMP AL, '0' ;SE AL < '0'
JB ERRINP ;NON E' UNA CIFRA, SALTO A ERRINP
CMP AL, '9' ;SE AL > '9'
JA ERRINP ;NON E' UNA CIFRA, SALTO A ERRINP
MOV BL, DATI+1 ;METTO IL SECONDO DATO IN BL
CMP BL, '0' ;SE BL < '0'
JB ERRINP ;NON E' UNA CIFRA, SALTO A ERRINP
CMP BL, '9' ;SE BL > '9'
JA ERRINP ;NON E' UNA CIFRA, SALTO A ERRINP
SUB AL, '0' ;CONVERTO IL PRIMO DATO IN NUMERO
CBW ;ESTENDO AL AD AX PER LA MOLTIPLICAZIONE
SUB BL, '0' ;CONVERTO IL SECONDO DATO IN BINARIO
MUL BL ;IN AX ORA C'E' BL*AL
MOV BL, AL ;SALVO IN BL IL RISULTATO (PARTE BASSA), AH = 0
CMP AX, 10 ;IL RISULTATO E' SU DUE CIFRE ?
JB UNA ;SE NO, SALTO A UNA
MOV BH, 10 ;PREPARO BH PER DIVISIONE
DIV BH ;DIVIDO IL RISULTATO PER 10
MOV BL, AH ;SPOSTO IL RESTO IN BL
MOV AH, 2 ;PREPARO AH PER LA STAMPA
MOV DL, AL ;METTO LE DECINE IN DL
ADD DL, '0' ;CONVERTO IN ASCII LE DECINE
INT 21h ;STAMPO LE DECINE
UNA: MOV AH, 2 ;PREPARO AH PER LA STAMPA
- 26 -
27. MOV DL, BL ;METTO IL RESTO IN DL
ADD DL, '0' ;CONVERTI IN ASCII LE UNITA'
INT 21h ;STAMPO LE UNITA'
JMP FINE
ERRINP:
MOV AH, 2 ;PREPARO AH PER LA STAMPA
MOV DL, '*' ;METTO '*' IN DL
INT 21h ;STAMPO
JMP FINE
FINE: MOV DL, LF ;VADO ALLA PROSSIMA RIGA
INT 21h ;STAMPO
MOV DL, CR ;VADO A CAPO
INT 21h ;STAMPO
.EXIT
END
- 27 -
28. ;Programma che legge da tastiera due numeri
;interi positivi su due cifre (tra 00 e 99),
;e ne stampa su video il MCD
;Autore: Sergio Porcu
LF EQU 10
CR EQU 13
.MODEL SMALL
.STACK
.DATA
DATI DB 2 DUP (?)
.CODE
.STARTUP
MOV SI, 0 ;SI PUNTA ALLA CASELLA CORRENTE DI DATI
NEXT: MOV AH, 1 ;PREPARO AH PER LA LETTURA
INT 21h ;LEGGO LA PRIMA CIFRA
SUB AL, '0' ;CONVERTO DA ASCII A NUMERO
MOV BH, 10 ;PREPARO BH PER LA MOLTIPLICAZIONE
MUL BH ;IN AX ORA C'E' BH*AL
MOV DATI[SI], AL ;METTO AL IN DATI[SI] (DECINE), AH TUTTI ZERI
MOV AH, 1 ;PREPARO AH PER LA LETTURA
INT 21h ;LEGGO LA SECONDA CIFRA
SUB AL, '0' ;CONVERTO
ADD DATI[SI], AL ;COMPLETO LA CONVERSIONE
MOV AH, 2 ;PREPARO AH PER LA SCRITTURA
MOV DL, LF ;VADO ALLA PROSSIMA RIGA
INT 21h
MOV DL, CR ;VADO A CAPO
INT 21h
INC SI ;INCREMENTO SI
CMP SI, 2 ;HO CARICATO TUTTO IL VETTORE ?
JNE NEXT ;SE NO, SALTO A NEXT
MOV AL, DATI ;AL CONTIENE IL PRIMO DATO
CBW ;CONVERTO IL PRIMO DATO IN WORD (IN AX)
MOV BL, DATI+1 ;BL CONTIENE IL SECONDO DATO
CMP BL, 0 ;SE IL SECONDO DATO E' ZERO
JE FINITO ;HO FINITO (MCD = 0)
DIV BL ;DIVIDO IL PRIMO DATO PER IL SECONDO
CICLO:
CMP AH, 0 ;IL RESTO E' IN AH
JE FINITO ;SE IL RESTO E' 0 HO FINITO (MCD = SECONDO
;DATO)
MOV AL, BL ;AGGIORNO AL
MOV BL, AH ;AGGIORNO BL
CBW ;CONVERTO IN WORD (IN AX)
DIV BL ;RICALCOLO IL RESTO (IN AH)
JMP CICLO ;SALTO A CICLO
FINITO:
MOV AL, BL ;METTO MCD IN AL
CBW ;CONVERTO IN WORD (IN AX)
CMP AX, 10 ;IL RISULTATO E' SU DUE CIFRE ?
JB UNA ;SE NO SALTO A UNA
- 28 -
29. MOV BH, 10 ;PREPARO BH PER DIVISIONE
DIV BH ;DIVIDO IL NUOVO AX PER 10
MOV BL, AH ;SPOSTO IL RESTO IN BL
MOV AH, 2 ;PREPARO AH PER LA STAMPA
MOV DL, AL ;METTO LE DECINE IN DL
ADD DL, '0' ;CONVERTO IN ASCII LE DECINE
INT 21h ;STAMPO LE DECINE
UNA: MOV AH, 2 ;PREPARO AH PER LA STAMPA
MOV DL, BL ;METTO IL RESTO IN DL
ADD DL, '0' ;CONVERTO IN ASCII LE UNITA'
INT 21h ;STAMPO LE UNITA'
MOV DL, LF ;VADO SULLA PROSSIMA RIGA
INT 21h ;STAMPO
MOV DL, CR ;VADO A CAPO
INT 21h ;STAMPO
.EXIT
END
- 29 -
30. ;Programma che calcola i primi 20 numeri della
;serie di Fibonacci
;Autore: Sergio Porcu
NUM EQU 20
.MODEL SMALL
.STACK
.DATA
FIB DW NUM DUP (?)
.CODE
.STARTUP
MOV DI, 0 ;DI PUNTA AL PRIMO ELEMENTO DEL VETTORE
MOV FIB[DI], 1 ;PRIMO NUMERO DELLA SERIE
ADD DI, 2
MOV FIB[DI], 1 ;SECONDO NUMERO DELLA SERIE
ADD DI, 2
MOV CX, NUM-2 ;CX TIENE CONTO DI QUANTI NUMERI DEVONO
;ANCORA ESSERE CALCOLATI
MOV AX, FIB[0]
CICLO:
ADD AX, FIB[DI-4] ;A PARTIRE DAL TERZO OGNI NUMERO E'
MOV FIB[DI], AX ;CALCOLATO COME SOMMA DEI DUE PRECEDENTI
ADD DI, 2 ;AGGIORNO DI
LOOP CICLO
.EXIT
END
- 30 -
31. ;SISTEMI A MICROPROCESSORE
;Ingresso e uscita a controllo di programma
;Autore: Sergio Porcu
;La procedura in_byte preleva un byte da un'interfaccia
;di ingresso e lo pone in AL.
;L'interfaccia in oggetto e' caratterizzata dalla presenza
;dei registri RBR e STR (con il flag FI corrispondente al
;bit n. 0 di STR), e' montata nello spazio di I/O ed e'
;posizionata agli indirizzi 63E0h (RBR) e 63E1h (STR)
_RBR EQU 63E0h
_STR EQU 63E1h
.MODEL SMALL
.STACK
.DATA
.CODE
.STARTUP
CALL IN_BYTE
.EXIT
IN_BYTE PROC FAR
PUSH DX
MOV DX, _STR
TEST_FI:
IN AL, DX ;TRASFERIMENTO IN AL DEL CONTENUTO
TEST AL, 01h ;DI STR, ESAME DEL FLAG FI E
JZ TEST_FI ;RIPETIZIONE DEL CICLO SE FI=0
MOV DX, _RBR ;TRASFERIMENTO DI UN BYTE DA RBR
IN AL, DX ;IN AL
POP DX
RET
IN_BYTE ENDP
END
;..........................................................................................
;Un'interfaccia di ingresso serve a trasferire dati da un
;dispositivo esterno al processore: nel caso piu' semplice,
;essa possiede un buffer di ingresso RBR (Receiver Buffer
;Register) e un registro di stato STR (STatus Register)
;contenente il flag FI che specifica se e' o meno in corso
;un trasferimento dati.
;Il trasferimento di un byte da un dispositivo esterno al
;processore comporta il trasferimento del byte stesso prima
;dal dispositivo al registro RBR e successivamente dal
;registro RBR al processore. Il primo trasferimento avviene
;via hardware ad opera dell'interfaccia stessa. Il secondo
;trasferimento avviene invece via software mediante la
;esecuzione di opportune istruzioni. Piu' precisamente, il
;flag FI, quando vale 1, specifica che un nuovo byte e'
;stato trasferito dal dispositivo all'interfaccia e che
;il programmatore puo' correttamente prelevarlo dal registro
;RBR. Quando tale prelievo avviene, l'interfaccia pone
- 31 -
32. ;automaticamente a 0 il flag FI ed inizia un nuovo
;trasferimento dal dispositivo esterno. La gestione di una
;operazione di ingresso a controllo di programma comporta
;la verifica, per ogni byte da trasferire, dello stato
;del flag FI.
- 32 -
33. ;SISTEMI A MICROPROCESSORE
;Ingresso e uscita a controllo di programma
;Autore: Sergio Porcu
;La procedura ot_byte trasferisce all'interfaccia di uscita
;il byte contenuto in AL.
;L'interfaccia in oggetto e' caratterizzata dalla presenza
;dei registri TBR e STR (con il flag FO corrispondente al
;bit n. 1 di STR), e' montata nello spazio di I/O ed e'
;posizionata agli indirizzi 63E2h (TBR) e 63E3h (STR)
_TBR EQU 63E2h
_STR EQU 63E3h
.MODEL SMALL
.STACK
.DATA
.CODE
.STARTUP
CALL OT_BYTE
.EXIT
OT_BYTE PROC FAR
PUSH DX
PUSH AX
MOV DX, _STR
TEST_FO:
IN AL, DX ;TRASFERIMENTO IN AL DEL CONTENUTO
TEST AL, 02h ;DI STR, ESAME DEL FLAG FO E
JZ TEST_FO ;RIPETIZIONE DEL CICLO SE FO=0
POP AX
MOV DX, _TBR ;TRASFERIMENTO DI UN BYTE DA AL
OUT DX, AL ;IN TBR
POP DX
RET
OT_BYTE ENDP
END
;..........................................................................................
;Un'interfaccia di uscita serve a trasferire dati dal
;processore ad un dispositivo esterno: nel caso piu'
;semplice, essa possiede un buffer di uscita TBR
;(Transmitter Buffer Register) ed eventualmente un registro
;di stato STR (STatus Register). Il trasferimento di un
;byte dal processore ad un dispositivo esterno comporta il
;trasferimento del byte stesso prima dal processore al
;registro TBR e successivamente dal registro TBR al
;dispositivo esterno. Il primo trasferimento avviene via
;software mediante l'esecuzione di opportune istruzioni.
;Il secondo trasferimento avviene invece via hardware, ad
;opera dell'interfaccia stessa e comporta la presenza di
;un flag FO nel registro di stato STR. Il flag FO, quando
;vale 1, specifica che e' terminato il trasferimento di un
;byte dall'interfaccia al dispositivo e che il
- 33 -
34. ;programmatore puo' correttamente immettere un nuovo dato
;nel registro TBR. Quando tale immissione avviene, la
;interfaccia pone automaticamente a 0 il flag FO ed inizia
;un nuovo trasferimento verso il dispositivo esterno. La
;gestione di una operazione di uscita a controllo di
;programma comporta la verifica, per ogni byte da
;trasferire, dello stato del flaf FO.
- 34 -
35. ;SISTEMI A MICROPROCESSORE
;Procedura di inizializzazione dell'interfaccia 8250 con
;riferimento alla configurazione COM1
;Parametri della configurazione:
;- bit-rate: 9600 bit/s
;- bit per carattere: 8
;- parita': disabilitata
;- bit di stop: 1
;- richieste di interruzione: tutte disabilitate
;Autore: Sergio Porcu
RBR EQU 03F8h
DLR_LSB EQU 03F8h
DLR_MSB EQU 03F9h
LCR EQU 03FBh
IER EQU 03F9h
.MODEL SMALL
.STACK
.DATA
.CODE
INI_COM PROC NEAR ;INIZIO PROCEDURA
PUSH AX ;SALVATAGGIO NELLO STACK DEI
PUSH DX ;VALORI CONTENUTI IN AX E DX
MOV DX, LCR ;COPIA IN DX IL VALORE CONTENUTO IN LCR
IN AL, DX ;LETTURA DEL CONTENUTO DI LCR
OR AL, 80h ;SET DLAB=1
OUT DX, AL ;SCRITTURA IN LCR
MOV AX, 000Ch ;BIT-RATE: 9600
MOV DX, DLR_LSB ;COPIA IN DX IL VALORE
;DI DLR_LSB
OUT DX, AL ;TRASF. REGISTRO -> DISP. PERIF.
MOV AL, AH ;COPIA IL VALORE DI AH IN AL
INC DX ;IN DX IL VALORE 03F9h
;03F8h + 1h (DLR_MSB)
OUT DX, AL ;TRASF. REGISTRO -> DISP. PERIF.
MOV AL, 03h ;1 BIT DI STOP, 8 BIT/CARATTERE,
;PARITA' DISABILITATA
MOV DX, LCR ;DLAB = 0
OUT DX, AL ;TRASF. REGISTRO -> DISP. PERIF.
MOV AL, 00h ;DISABILITAZIONE DELLE
MOV DX, IER ;RICHIESTE DI INTERRUZIONE
OUT DX, AL ;TRASF. REGISTRO -> DISP. PERIF.
MOV DX, RBR ;INGRESSO A VUOTO PER
IN AL, DX ;SVUOTARE RBR
POP DX ;ESTRAZIONE DEI VALORI CONTENUTI
POP AX ;NELLO STACK
RET ;RITORNO AL MAIN
INI_COM ENDP ;FINE PROCEDURA
.STARTUP ;MAIN
CALL INI_COM ;CHIAMATA A PROCEDURA
.EXIT ;RITORNO AL S.O.
END ;FINE PROGRAMMA
- 35 -
36. ;SISTEMI A MICROPROCESSORE
;Inizializzare un 8250 su COM2 con i seguenti parametri
;- 2400 bps
;- 5 bit per carattere inviato
;- 1,5 bit di stop
;- parita' dispari
;- richieste di interrupt abilitate per errori e ricezione
;Inviare infine il dato contenuto nella variabile VAR definita byte
;Autore: Sergio Porcu
CONTROL_LCR EQU 00001100b ;5 BIT CARATTERE, 1.5 BIT STOP,
;PARITA' DISPARI
SET_IER EQU 00000101b
COSTANTE_DLR EQU 0030h
DLR-LSB EQU 02F8h
THR EQU 02F8h
DLR-MSB EQU 02F9h
IER EQU 02F9h
LCR EQU 02FBh
LSR EQU 02FDh ;LSR CONTIENE LE INFORMAZIONI
;RELATIVE ALLO STATO DELLA
;INTERFACCIA
.MODEL SMALL
.STACK
.DATA
VAR DB ?
.CODE
.STARTUP
CALL INIT_PROC
CALL INVIA_PROC
.EXIT
INIT_PROC PROC
PUSH AX
PUSH DX
MOV DX, LCR
IN AL, DX
OR AL, 10000000b
OUT DX, AL
MOV DX, DLR-LSB
MOV AX, COSTANTE_DLR
OUT DX, AL
MOV DX, DLR-MSB
XCHG AL, AH
OUT DX, AL
MOV DX, LCR
MOV AL, CONTROL_LCR
OUT DX, AL
MOV DX, IER
MOV AL, SET_IER
OUT DX, AL
POP DX
POP AX
- 36 -
37. RET
INIT_PROC ENDP
INVIA_PROC PROC
PUSH AX
PUSH DX
MOV DX, LSR
CICLO:
IN AL, DX
TEST AL, 00100000b ;EO=1 (BIT 6 DI LSR) -> IL DATO
;CONTENUTO NEL REGISTRO THR E'
;STATO TRASMESSO
JZ CICLO
MOV DX, THR
MOV AL, VAR
OUT DX, AL
POP DX
POP AX
RET
INVIA_PROC ENDP
END
- 37 -
38. ;SISTEMI A MICROPROCESSORE
;Configurare il sistema in modo che i 50 valori ricevuti dall’interfaccia seriale siano
;memorizzati in una variabile vet. L’interfaccia 8250 alla porta COM1 e’ inizializzata
;come segue:
;- 9600 bps
;- 8 bit per carattere inviato
;- 1 bit di stop
;- parita’ pari
;Autore: Sergio Porcu
ICW1_8259 EQU 00010011b
ICW2_8259 EQU 00100000b
ICW4_8259 EQU 00000001b
OCW2_8259 EQU 00100000b
LCR_8250 EQU 00011011b
DLR_8250 EQU 000Ch
IER_8250 EQU 00000001b
RBR EQU 03F8h
DLR_LSB EQU 03F8h
DLR_MSB EQU 03F9h
IER EQU 03F9h
IIR EQU 03FAh
LCR EQU 03FBh
.MODEL SMALL
.STACK
.DATA
VET DB 50 DUP (?)
.CODE
.STARTUP
CLI ;DISABILITA GLI INTERRUPT
CALL INIT_INTER
CALL INIT_8259
CALL INIT_8250
STI ;ABILITA NUOVAMENTE GLI INTERRUPT
MOV DI, 0
LEA SI, VET
ANCORA:
CMP DI, 50
JNE ANCORA
CLI ;DISABILITA GLI INTERRUPT
LEA SI, VET
CALL MEDIA
CALL SPEDISCI_8250
.EXIT
INIT_INTER PROC
PUSH DS
PUSH AX
PUSH BX
XOR AX, AX
MOV DS, AX
MOV BX, 32
- 38 -
39. MOV CL, 2
SHL BX, CL
MOV AX, OFFSET INTER_EVENT
MOV DS:[BX], AX
MOV AX, SEG INTER_EVENT
MOV DS:[BX+2], AX
POP BX
POP AX
POP DS
RET
INIT_INTER ENDP
INIT_8259 PROC
MOV DX, 40h
MOV AL, ICW1
OUT DX, AL
MOV DX, 41h
MOV AL, ICW2_8259
OUT DX, AL
MOV AL, ICW4_8259
OUT DX, AL
RET
INIT_8259 ENDP
INIT_8250 PROC
PUSH AX
PUSH DX
MOV DX, LCR
IN AL, DX
OR AL, 10000000b
OUT DX, AL
MOV DX, DLR_LSB
MOV AX, 000Ch
OUT DX, AL
MOV DX, DLR_MSB
XCHG AL, AH
OUT DX, AL
MOV DX, LCR
MOV AL, LCR_8250
OUT DX, AL
MOV DX, IER
MOV AL, IER_8250
OUT DX, AL
POP DX
POP AX
RET
INIT_8250 ENDP
MEDIA PROC
PUSH DI
PUSH SI
MOV DI, 0
XOR AX, AX
SOMMA:
ADD AL, [SI]
JNC NEW
- 39 -
40. INC AH
NEW: INC SI
INC DI
CMP DI, 50
JNE SOMMA
MOV BL, 50
DIV BL
POP SI
POP DI
RET
MEDIA ENDP
SPEDISCI_8250 PROC
PUSH AX
PUSH DX
PUSH BX
MOV BX, AX
MOV DX, LSR
CICLO1:
IN AL, DX
TEST AL, 00100000b
JZ CICLO1
MOV DX, THR
MOV AL, BL
OUT DX, AL
MOV DX, LSR
CICLO2:
IN AL, DX
TEST AL, 00100000b
JZ CICLO2
MOV DX, THR
MOV AL, BH
OUT DX, AL
POP BX
POP DX
POP AX
RET
SPEDISCI_8250 ENDP
INTER_EVENT PROC
PUSH AX
PUSH DX
MOV DX, IIR
IN AL, DX
CMP AL, 00000100b
JNE END
MOV DX, RBR
IN AL, DX
MOV [SI], AL
INC SI
INC DI
END: MOV DX, 40h
MOV AL, OCW2_8259
OUT DX, AL
IRET
- 40 -
42. ;SISTEMI A MICROPROCESSORE
;Si programmi un 8253 in modo da generare un ritardo di 5 msec.
;Si supponga di avere a disposizione un clock da 1 Mhz.
;Autore: Sergio Porcu
;SOLUZIONE (PARZIALE):
;IL PERIODO DEL CLOCK È DI 1 MICROSECONDO. PER OTTENERE UN TEMPO DI
;5 MSEC SONO NECESSARI 5000 PERIODI DEL CLOCK.
;...
MOV AL, 01100001b ;CONTATORE 1, MODO 0, BCD *
OUT 43h, AL ;PROGRAMMAZIONE CONTATORE #1
MOV AL, 50h ;BYTE PIÙ SIGNIFICATIVO
OUT 41h, AL ;CARICAMENTO MSB CONTATORE #1
;...
;* READ/LOAD MSB ONLY
- 42 -
43. ;SISTEMI A MICROPROCESSORE
;Si voglia generare un segnale che ogni 4 secondi scateni
;una richiesta di interruzione.
;Si supponga di disporre di un clock con frequenza 2 Mhz.
;Autore: Sergio Porcu
;SOLUZIONE (PARZIALE):
;IL NUMERO DI IMPULSI CHE DEVONO ESSERE CONTATI È PARI A
;8.000.000. TALE CIFRA NON È RAPPRESENTABILE SU 16 BIT E
;QUINDI OCCORRE UTILIZZARE DUE CONTATORI IN CASCATA.
;...
MOV DX, 43h ;CARICAMENTO IN DX DELL'INDIRIZZO DEL REGISTRO DI
;CONTROLLO
MOV AL, 34h ;CARICAMENTO IN AL DELLA PRIMA PAROLA DI CONTROLLO
;CONTATORE 0, MODO 2, BINARIO
OUT DX, AL ;PROGRAMMAZIONE CONTATORE #0
MOV AL, 64h ;CARICAMENTO IN AL DELLA SECONDA PAROLA DI CONTROLLO
;CONTATORE 1, MODO 2, BINARIO
OUT DX, AL ;PROGRAMMAZIONE CONTATORE #1
MOV DX, 40h ;CARICAMENTO IN DX DELL'INDIRIZZO DEL CONTATORE #0
MOV AX, 50000 ;8,000,000 / 160
OUT DX, AL ;LSB CONTATORE #0
MOV AL, AH
OUT DX, AL ;MSB CONTATORE #0
INC DX ;CARICAMENTO IN DX DELL'INDIRIZZO DEL CONTATORE #1
MOV AL, 160
OUT DX, AL ;MSB CONTATORE #1
;...
- 43 -
44. ;SISTEMI A MICROPROCESSORE
;Lettura al volo 8253
;Autore: Sergio Porcu
CW0 EQU 00110000b ;30h
CW1 EQU 01100101b ;65h
CW2 EQU 10111000b ;B8h
.MODEL SMALL
.STACK
.DATA
.CODE
INI_8253 PROC NEAR
MOV AL, CW0 ;CARICAMENTO IN AL DELLA PRIMA PAROLA DI CONTROLLO
OUT 43h, AL ;PROGRAMMAZIONE CONTATORE #0
MOV AL, CW1 ;CARICAMENTO IN AL DELLA SECONDA PAROLA DI
;CONTROLLO
OUT 43h, AL ;PROGRAMMAZIONE CONTATORE #1
MOV AL, CW2 ;CARICAMENTO IN AL DELLA TERZA PAROLA DI CONTROLLO
OUT 43h, AL ;PROGRAMMAZIONE CONTATORE #2
MOV AL, 34h
OUT 40h, AL ;CARICAMENTO LSB CONTATORE 0
MOV AL, 12h
OUT 40h, AL ;CARICAMENTO MSB CONTATORE 0
MOV AL, 01h
OUT 41h, AL ;CARICAMENTO MSB CONTATORE 1
MOV AL, 0FFh
OUT 42h, AL ;CARICAMENTO LSB CONTATORE 2
MOV AL, 1Fh
OUT 42h, AL ;CARICAMENTO MSB CONTATORE 2
RET
INI_8253 ENDP
.STARTUP
CALL INI_8253
MOV AL, 80h ;CARICAMENTO IN AL DELLA PAROLA DI CONTROLLO
OUT 43h, AL ;PREDISPOSIZIONE CONTATORE 2 ALLA LETTURA AL VOLO
IN AL, 42h ;LETTURA DEL LSB
MOV AH, AL ;COPIA IL VALORE DI AL IN AH
IN AL, 42h ;LETTURA DEL MSB
XCHG AL, AH ;SCAMBIO TRA AH E AL
;(RICOSTRUZIONE DEL VALORE)
.EXIT
END
- 44 -
45. ;SISTEMI A MICROPROCESSORE
;Programma che gestisce il funzionamento dello speaker del PC
;Connessioni:
;La porta B dell'8255 ha il bit 0 connesso al segnale di GATE2 dell'8253 ed il bit 1
;in ingresso ad una porta di AND. Il secondo ingresso della porta AND e' il segnale
;OUT del contatore 2 dell'8253. L'uscita della porta AND pilota uno speaker acustico.
;Indirizzi:
;8255 (Porta B) -> 61h
;8253 -> 40h, 41h, 42h, 43h
;Autore: Sergio Porcu
CR EQU 13 ;CARRIAGE RETURN
LF EQU 10 ;LINE FEED
PS_8255 EQU 61h ;PORTA B DELL'8255 *
C2_8253 EQU 42h ;CONTATORE 2 DELL'8253
RC_8253 EQU 43h ;REGISTRO DI CONTROLLO DELL'8253
P2_8253 EQU 0B6h ;PAROLA DI CONTROLLO CONTATORE #2 **
.MODEL SMALL
.STACK
.DATA
APP DW ?
.CODE
;LA PROCEDURA BEEP RICEVE IN DI LA FREQUENZA IN HZ, ED IN BX LA DURATA IN
;CENTESIMI DI SECONDO DEL SUONO DESIDERATO
BEEP PROC NEAR
PUSH AX ;SALVATAGGIO NELLO STACK DEI
PUSH BX ;REGISTRI AX, BX, CX, DX
PUSH CX
PUSH DX
MOV AL, P2_8253 ;PAROLA DI CONTROLLO CONTATORE #2
OUT RC_8253, AL ;PROGRAMMAZIONE CONTATORE #2
MOV DX, 14h ;144F38h = 1331000 -> FREQ. CLOCK
MOV AX, 4F38h ;IN DX 14h, IN AX 4F38h
DIV DI
OUT C2_8253, AL ;FREQUENZA (LSB)
MOV AL, AH
OUT C2_8253, AL ;FREQUENZA (MSB)
IN AL, PS_8255 ;RILEVAMENTO VALORE CORRENTE DELLO SPEAKER
;DI SISTEMA
MOV AH, AL
OR AL, 03h ;IMPOSTAZIONE DEI DUE BIT MENO SIGNIFICATIVI
;A 1
OUT PS_8255, AL ;ABILITAZIONE BEEPER
L1: MOV CX, 2942 ;***
L2: LOOP L2
DEC BX ;DECREMENTO DEI CENTESIMI
JNZ L1 ;SE BX=0 PROSEGUE, ALTRIMENTI
;SI SALTA A L1
MOV AL, AH
OUT PS_8255,AL ;DISABILITAZIONE BEEPER
POP DX
POP CX
- 45 -
46. POP BX
POP AX
RET
BEEP ENDP
ACAPO PROC NEAR ;INIZIO PROCEDURA ACAPO
PUSH AX ;SALVA NELLO STACK IL VALORE DI AX
PUSH DX ;E DX
MOV AH, 2 ;PREDISPOSIZIONE DI AH ALLA VISUALIZZAZIONE
MOV DL, CR ;COPIA IL 'CARRIAGE RETURN' IN DL
INT 21h ;STAMPA CARATTERE A VIDEO
MOV DL, LF ;COPIA IL 'LINE FEED' IN DL
INT 21h ;STAMPA CARATTERE A VIDEO
POP DX ;COPIA L'ULTIMO VALORE DELLO STACK IN DX
POP AX ;COPIA L'ULTIMO VALORE DELLO STACK IN AX
RET ;RITORNO AL PROGRAMMA PRINCIPALE
ACAPO ENDP ;FINE PROCEDURA ACAPO
.STARTUP
;PROGRAMMA PRINCIPALE: SUONA PER 3 VOLTE UNA SCALA CHE VA DA 100 A 2000
;HZ E VISUALIZZA IL CONTO ALLA ROVESCIA DEI CICLI
MOV CX, 3
MOV AH, 2
CICLO:
MOV DI, 100
MOV BX, 150
AGAIN:
CALL BEEP
ADD DI, 20
CMP DI, 2000
JB AGAIN
MOV APP, CX
ADD APP, 30h
MOV DL, BYTE PTR APP
INT 21h
CALL ACAPO
LOOP CICLO
.EXIT
END
;* L'altoparlante del sistema e' indirizzabile alla porta 61h
;** 0B6h -> 10110110b -> cont. 2, prima LSB poi MSB, modo 3, bin
;*** Quanto deve valere n affinche' il ciclo duri 10 msec?
; Durata LOOP:
; - 17 colpi di clock se ripete
; - 5 colpi di clock se non ripete
; Durata MOV:
; - 4 colpi di clock.
; Deve quindi essere: [17(n-1)+5+4]T = 0.01 sec
; T e' il periodo del processore. Se il clock ha frequenza 5 Mhz, si ha n = 2941
- 46 -
47. ;SISTEMI A MICROPROCESSORE
;Programma che gestisce il funzionamento dello speaker di sistema.
;Emissione delle note della scala musicale
;Autore: Sergio Porcu
.MODEL SMALL
.STACK
.DATA
TEMP DW ?
SCALA DB 10,13,"DO RE MI FA SOL LA SI (ESCAPE PER USCIRE)$"
NOTE DB 10,13,"1 2 3 4 5 6 7 $"
.CODE
EMETTI_SUONO PROC NEAR ;PROCEDURA PER L'EMISSIONE DEL SUONO
TEMP1:
CMP AL,1 ;CONFRONTA AL CON 1
JNE TEMP2 ;SE NON SONO UGUALI SALTA A TEMP2
MOV AX, 9121 ;ALTRIMENTI ASSEGNA LA FREQUENZA SELEZIONATA
;(E COSI' DI SEGUITO)
JMP FINE_TEMP
TEMP2:
CMP AL,2
JNE TEMP3
MOV AX, 8126
JMP FINE_TEMP
TEMP3:
CMP AL,3
JNE TEMP4
MOV AX, 7240
JMP FINE_TEMP
TEMP4:
CMP AL,4
JNE TEMP5
MOV AX, 6833
JMP FINE_TEMP
TEMP5:
CMP AL,5
JNE TEMP6
MOV AX, 6088
JMP FINE_TEMP
TEMP6:
CMP AL,6
JNE TEMP7
MOV AX, 5424
JMP FINE_TEMP
TEMP7:
CMP AL,7
JNE FINE_TEMP
MOV AX, 4832
FINE_TEMP:
;PROGRAMMAZIONE DEL TIMER
MOV TEMP, AX ;SALVATAGGIO DEL VALORE DI TEMPORIZZAZIONE
;IN UNA APPOSITA VARIABILE
- 47 -
48. MOV AL, 0B6h ;COPIA IN AL IL VALORE 10110110 (VEDERE
;PROGRAMMA PRECEDENTE)
OUT 43h, AL ;IMPOSTAZIONE DEL TIMER PER LA
;CONFIGURAZIONE PREVISTA
MOV AX, TEMP ;IMPOSTAZIONE DI AX CON IL VALORE DI
;TEMPORIZZAZIONE
OUT 42h, AL ;IMPOSTAZIONE DEL CONTATORE (BYTE MENO
;SIGNIFICATIVO) ASSOCIATO AL CANALE 2
MOV AL, AH ;IMPOSTAZIONE DEL REGISTRO AL PER IL
;TRASFERIMENTO DEL BYTE PIU' SIGNIFICATIVO DEL
;CONTATORE
OUT 42h, AL ;IMPOSTAZIONE DEL CONTATORE (BYTE PIU'
;SIGNIFICATIVO) ASSOCIATO AL CANALE 2
;COLLEGAMENTO TIMER - SPEAKER
IN AL, 61h
OR AL, 03h
OUT 61h, AL
;Questo ciclo tiene impegnata la CPU per un tempo pari a quello necessario ad
;eseguire l'algoritmo che permette al suono di essere ascoltato per tutto il tempo di
;esecuzione del ciclo. Il tempo si puo' impostare indirettamente indicando quante
;volte deve essere eseguito il ciclo. Per impostare questo valore si deve
;necessariamente assegnare al registro BX un valore prima della chiamata a questa
;procedura. Tempi accettabili sono quelli tra 100 e 300, valori testati empiricamente.
;BX rappresenta, percio', un parametro da passare alla procedura prima di essere
;chiamata.
MOV AX, BX
CICLO:
MOV CX, 65535
TEMPO:
SUB CX, 1
JNZ TEMPO
SUB AX, 1
CMP AX, 0
JA CICLO
;INTERRUZIONE DELLO SPEAKER
IN AL, 61h
SUB AL, 03h
OUT 61h, AL
RET ;RITORNO AL PROGRAMMA PRINCIPALE
EMETTI_SUONO ENDP ;FINE DELLA PROCEDURA
PREMI_NOTA PROC NEAR ;INIZIO DELLA PROCEDURE PER L'INPUT DI UNA
;SEQUENZA DI CARATTERI ASSOCIATI ALLE NOTE
MOV AH, 09 ;OUTPUT DI UNA STRINGA
MOV DX, OFFSET SCALA
INT 21h
MOV AH, 09 ;OUTPUT DI UNA STRINGA
MOV DX, OFFSET NOTE
INT 21h
INSER:
MOV AH, 07h ;FUNZIONE DI SISTEMA CHE LEGGE UN CARATTERE
;DA TASTIERA SENZA ESEGUIRE L'ECO SU VIDEO
INT 21h
CMP AL, 27 ;VALORE DEL CARATTERE IN ASCII ESCAPE
- 48 -
49. JE FINE_INS ;SE IL CARATTERE E' UGUALE AD ESC SALTA ALLA
;FINE
CMP AL, 37h ;SE IL CARATTERE E' MAGGIORE DI 7 ASCII
JA INSER ;ALLORA SALTA ALL'INSERIMENTO
CMP AL, 31h ;SE IL CARATTERE E' MINORE DI 1 ASCII
JB INSER ;ALLORA TORNA ALL'INSERIMENTO
SUB AL, 30h ;TRASFORMAZIONE ASCII -> BIN
MOV BX, 1000 ;IMPOSTAZIONE DEL TEMPO A CENTO CICLI
CALL EMETTI_SUONO ;CHIAMATA ALLA PROCEDURA DI EMISSIONE DEL
;SUONO
JMP INSER ;SALTA AD "INSER"
FINE_INS:
RET ;FINE DELLA PROCEDURA
PREMI_NOTA ENDP
.STARTUP
MOV BX, 50
CALL PREMI_NOTA
.EXIT
END
- 49 -
50. ;SISTEMI A MICROPROCESSORE
;Programma che stampa su LPT1 la stringa "Ciao a tutti"
;Autore: Sergio Porcu
PRDATA EQU 0378h ;INDIRIZZO LPT1
PRSTAT EQU PRDATA+1 ;PORTA B (0379h)
PRCTRL EQU PRDATA+2 ;PORTA C (037Ah)
DELAY EQU 100 ;RITARDO
;STATO DELLA STAMPANTE (PORTA B)
SERR EQU 08h ;ATTIVO BASSO (00001000b) -> PB3
SSEL EQU 10h ;ATTIVO ALTO (00010000b) -> PB4
SPE EQU 20h ;ATTIVO ALTO (00100000b) -> PB5
SACK EQU 40h ;ATTIVO BASSO (01000000b) -> PB6
SBUSY EQU 80h ;ATTIVO BASSO (10000000b) -> PB7
;CONTROLLO DELLA STAMPANTE (PORTA C)
CSTB EQU 01h ;ATTIVO ALTO (00000001b) -> PC0
CAUTO EQU 02h ;ATTIVO ALTO (00000010b) -> PC1
CINIT EQU 04h ;ATTIVO BASSO (00000100b) -> PC2
CSEL EQU 08h ;ATTIVO ALTO (00001000b) -> PC3
.MODEL SMALL
.STACK
.DATA
MSG DB 'CIAO A TUTTI',0Dh,0Ah,0
.CODE
PR_AL PROC NEAR
PUSH DX
PUSH AX
MOV AH, AL ;SALVA AL IN AH
MOV DX, PRSTAT ;CARICA LO STATO DELLA STAMPANTE
PR_N_READY:
IN AL, DX ;LEGGE LO STATO DELLA STAMPANTE
TEST AL, SERR
JZ PR_ERROR ;SE ZF=1 -> ERRORE
TEST AL, SBUSY
JZ PR_N_READY ;SE ZF=1 -> BUSY
TEST AL, SSEL
JZ PR_N_READY ;SE ZF=0 -> ON LINE
MOV AL, AH
MOV DX, PRDATA ;CARICA L'INDIRIZZO DI LPT1
OUT DX, AL ;INVIA IL DATO
MOV CX, DELAY
CICLO1:
LOOP CICLO1
MOV DX, PRCTRL ;CARICA IL CONTROLLO DELLA STAMPANTE
IN AL, DX
OR AL, CSTB ;SETTA IL BIT DI STROBE *
;(IMPULSO TRASFERIMENTO DEI DATI)
OUT DX, AL
MOV CX, 2*DELAY
CICLO2:
LOOP CICLO2
AND AL, NOT CSTB ;RESETTA LO STROBE **
- 50 -
51. OUT DX, AL
MOV CX, DELAY
CICLO3:
LOOP CICLO3
PR_DONE:
POP AX
POP DX
RET
PR_ERROR:
JMP PR_DONE
PR_AL ENDP
.STARTUP
MOV BX, OFFSET MSG
XOR SI, SI
NEXT: MOV AL, [BX] [SI]
CMP AL, 0
JE DONE
CALL PR_AL ;STAMPA UN CARATTERE
INC SI
JMP NEXT
DONE:
.EXIT
END
;* STROBE: un impulso basso di durata superiore ad 1 microsecondo scrive sulla
; stampante un byte di dati
;** L'operazione NOT esegue l'operazione logica di complementazione bit a bit del
; contenuto di un operando
- 51 -