;
; Esame 2005-12-02
;
; Si realizzi il programma in linguaggio Assembler 8086 che faccia quanto segue:
; 1. attenda che l'utente digiti una numero N compreso tra 1 e 5 attraverso la tastiera
; 2. si depositi questo numero nella locazione ampia un byte avente nome simbolico N;
; 3. per N volte:
;    a. si attenda che l'utente digiti due cifre comprese tra 0 e 9 seguite dal tasto ‘a’;
;    b. interpretando la stringa di caratteri digitati come un numero in base dieci, si memorizzi
;       tale numero nella posizione i-esima del vettore collocato a partire dalla locazione
;       VETT (VETT ha 5 elementi di un byte ciascuno).
; 4. si memorizzi nella locazione ampia due byte avente nome simbolico RISU, la somma degli
;    elementi del vettore VETT;
; 5. si invii sull'interfaccia di uscita i caratteri ASCII necessari a stampare il valore di RISU.
;
.MODEL	small
.stack	100h

.data
    insNum	db "Inserisci un numero compreso tra 1 e 5: $"
    insDDa	db "Inserisci due numeri compresi tra 0 e 9 seguiti dal carattera 'a': $"
    pkey	db "press any key...$"
    N		db 0                
    VETT	db 5 DUP (0)
    RISU	dw 0
    msg_risultato DB "Risultato somma: $"

.code
start:
	; set segment registers:
    mov ax, @data
    mov ds, ax

    ; Inizio esercizio
    call insNumero
    mov N, al   ; copia in N il numero binario ritornato dalla procedura

    mov cl, N   ; inizializza il registro CL al valore N
    mov si, 0   ; il registro SI contiene l'indice del vettore
ciclo:
    call getDDa ; inserimento di due cifre e lettera 'a'
    mov VETT[SI],al ; copia il valore letto nella SI-esima posizione di VETT
    mov ah, 0   ; azzera AH affinche' il valore di AX coincida con quello di AL
    add RISU, ax    ; somma AX a RISU
    inc si      ; incrementa SI al successivo elemento del vettore 
    dec cl      ; decrementa CL
    jnz ciclo   ; e salta a 'ciclo' fino a che CL non vale 0

    lea dx, msg_risultato
    mov ah, 9      
    int 21h     ; stampa la stringa del risultato
    
    mov ax, RISU    ; copia RISU in AX
    mov bl, 100     ; inizializza BL a 100
    div bl          ; divide AX per BL, ossia RISU per 100
    ; l'operazione di divisone pone:
    ; al = quoziente
    ; ah = modulo
    call outB2A     ; stampa la cifra delle centinaia
    mov al, ah      ; salva il valore del modulo in AL
    mov ah, 0       ; azzera AH in modo che il valore di AX coincida con quello di AL
    mov bl, 10      ; inizializza BL a 10
    div bl          ; divide AX per BL, ossia RISU per 100
    ; l'operazione di divisone pone:
    ; al = quoziente
    ; ah = modulo 
    call outB2A     ; stampa la cifra delle decine
    mov al, ah      ; copia il resto in AL
    call outB2A     ; stampa la cifra delle unita'
    call newline    ; stampa il ritorno carrello

	; Fine esercizio
    lea dx, pkey  
    mov ah, 9
    int 21h         ; output string at ds:dx
    mov ah, 1		; wait for any key....
    int 21h
    mov ax, 4c00h   ; exit to operating system.
    int 21h
    
insNumero proc
    lea dx, insNum
    mov ah, 9
    int 21h

inASCII:
    mov ah, 7   ; input di un carattere da tastiera
	int 21h
   	and al, 7Fh
	cmp al, '1' ; controlla che sia maggiore di 1
	jb  inASCII
	cmp al, '5' ; controlla che sia minore di 5
	ja  inASCII
	mov ah, 2   ; fa l'eco del carattere ricevuto in ingresso
	mov dl, al
	int 21h 
 	sub al, 30h ; trasforma il carattere ASCII in numero binario
	call newline    ; va a capo
	ret 
insNumero endp

getDDa proc
    push bx ; salva BX
    lea dx, insDDa
    mov ah, 9
    int 21h

inASCII1:
    mov ah, 7   ; input prima cifra
	int 21h
   	and al, 7Fh
	cmp al, '0' ; controlla che sia maggiore di 0
	jb  inASCII1
	cmp al, '9' ; controlla che sia minore di 9
	ja  inASCII1
	mov ah, 2   ; echo prima cifra
	mov dl, al
	int 21h
	mov ah, 0   ; azzera AH 
	sub al, 30h ; trasforma il carattere ASCII in numero binario
	mov bl, 10  ; inizializza BL a 10
	mul bl      ; moltiplica AL per BL e lascia il risultato in AX
	push ax     ; salvataggio prima cifra

inASCII2:	
    mov ah, 7   ; input seconda cifra
	int 21h
   	and al, 7Fh ; controlla che sia maggiore di 0
	cmp al, '0'
	jb  inASCII2
	cmp al, '9' ; controlla che sia minore di 9
	ja  inASCII2
	mov ah, 2   ; echo seconda cifra
	mov dl, al
	int 21h	
    mov bx, 0   ; azzera BX
    sub al, 30h ; trasforma il carattere ASCII in numero binario
    mov bl, al  ; copia AL in bl
    pop ax      ; recupera il valore della prima cifra in AX
    add al, bl  ; somma AL a BL e lascia il risultato in AL
    push ax     ; salva il risultato della somma nello stack

ina:	
    mov ah, 7   ; input carattere senza eco
	int 21h
   	and al, 7Fh ; controllo che sia la lettera 'a'
	cmp al, 'a'
	jne ina
    call newline    ; va a capo
    pop ax  ; recupera il risultato della somma in AX    
    pop bx  ; ripristina BX
    ret
getDDa endp

outB2A proc
    push ax     ; salva il contenuto di AX
    add al, 30h ; somma al parametro AL, 30h
    mov ah, 2   ; e fa l'eco a video
    mov dl, al
    int 21h
    pop ax      ; ripristina il contenuto di AX
    ret
outB2A endp

newline proc
    push ax
    push dx
    mov ah, 2
	mov dl, 0Dh
	int 21h
    mov dl, 0Ah
	int 21h
	pop dx
	pop ax
	ret
newline endp

end start ; set entry point and stop the assembler.