;
; Esame del 2007-12-04
;
; Utilizzando il linguaggio Assembler 8086 e l'insieme di interrupt disponibili sui processori compatibili x86, si realizzi il programma che faccia quanto segue:
; 1.	chiede all'utente di digitare da tastiera un numero compreso tra 01 e 19 (due cifre codificate ASCII) (2pt);
; 2.	memorizza tale numero all'interno di una variabile avente nome simbolico N, ampia 1 byte (1pt); 
; 3.	dati due vettori VETT1 e VETT2 di 20 elementi ciascuno, considera i primi N elementi di ciascuno, e per ognuno di essi calcola e stampa a video ogni volta su una linea diversa:
;	a.	l'indice dell'elemento considerato seguito dal carattere ':' (1pt);
;	b.	quanti bit sono a 1 nell'elemento considerato di VETT1 (1pt),
;	c.	quanti bit sono a 0 nell'elemento considerato di VETT2  (1pt),
;	d.	quale è il valore numerico decimale codificato ASCII dell'elemento considerato di VETT1 interpretato come numero binario naturale (2pt),
;	e.	quale è il valore numerico decimale codificato ASCII dell'elemento considerato di VETT2 interpretato come numero binario naturale (2pt),
;	f.	quale è la media intera troncata tra i gli elementi corrispondenti di VETT1 e VETT2 interpretati come numeri binari naturali (1pt);
; 4.	scambia il contenuto dell'elemento i-esimo di VETT1 con quello N-i esimo di VETT2 (2pt);
; 5.	ripete il punto 3 per i vettori così trasformati (1pt). 
;
; Esempio di output.
; Inserire numero: 02
; 1: 3 7 5 1 3
; 2: 2 5 3 10 6
; 1: 3 7 10 3 6
; 2: 1 5 1 5 3


.MODEL small

.data
    N         db 0
    msgInsNum db "Inserire numero [01-19]: $"
    VETT1     db 5,3,90,12,34,76,36,7,30,24,95,203,4,140,24,205,201,20,6,7
    VETT2     db 1,10,15,24,12,8,7,32,45,127,9,0,13,14,15,16,17,18,19,20
    pkey      db 0Dh, 0Ah, "press any key...$"

.stack

.code
start:
	; set data segment register
    mov ax,@data
    mov ds, ax
    
    ; 1. 
    lea dx, msgInsNum   ; Stampa il messaggio che chiede all'utente di
    call stampaStringa  ; inserire un numero
cifraD:
    call input  ; Attende in ingresso la cifra delle decine
    cmp al, '0' ; e controlla che la sua codifica ASCII sia compresa tra '0'
    jb cifraD
    cmp al, '1' ; '1'
    ja cifraD
    call output
    sub al, 30h ; Converte la codifica ASCII in binario naturale
    mov ah, 0
    mov bl, 10  ; quindi la moltiplica per 10 per ottenere le decine
    mul bl      ; AX = AL * BL
    mov N, al   ; N <- decine
    
cifraU:
    call input  ; Attende in ingresso la cifra delle unita'
    cmp al, '0' ; e controlla che la sua codifica ASCII sia compresa tra '0'
    jb cifraU
    cmp al, '9' ; e '9'
    ja cifraU
    call output
    sub al, 30h ; Converte la codifica ASCII in binario naturale
    
    ; 2.
    add N, al   ; N = N + AL (unita')
    jz  fine
    
    ; 3.
    call punto3 ; Chiama la procedura specificata al punto 3.

    ; 4.
    mov ch,0    ; CX <- N (contatore del ciclo)
    mov cl,N
    mov si,0    ; SI <- 0 (indice di VETT1)
    mov di,cx
    dec di      ; DI <- N-1 (indice di VETT2)
ciclo4:                 ; Scambio tra VETT1[SI] e VETT2[DI]
    mov al, VETT1[si]   ; AL <- VETT1[SI]
    mov ah, VETT2[di]   ; AH <- VETT2[DI]
    mov VETT1[si], ah   ; VETT1[SI] <- AH
    mov VETT2[di], al   ; VETT2[DI] <- AL
    inc si      ; Incrementa l'indice di VETT1
    dec di      ; Decrementa l'indice di VETT2
    dec cl      ; Decrementa il contatore del ciclo
    jnz ciclo4  ; e se non e' zero torna al ciclo4.
    
    ; 5.
    call punto3 ; Chiama nuovamente la procedura specificata al punto 3.
    
    ; Fine esercizio
fine:
    lea dx, pkey  ; output string at ds:dx
    mov ah, 9
    int 21h       
    mov ah, 1     ; wait for any key....
    int 21h
    mov ax, 4c00h ; exit to operating system.
    int 21h    
    
    
punto3 proc
    push ax
    push bx
    push cx
    push si
    mov cl, N   ; Inizializza il ciclo di elaborazione dei vettori
    mov si, 0   ; Azzera SI, indice del vettore VETT1
ciclo3:
    ; 3.a.
    call newline
    mov ax, si      ; AX <- SI
    call bin2AAA    ; Converte AX (contenente l'indice del vettore) in
                    ; 3 caratteri ASCII
    mov al, ':' ; Stampa il carattere ':'
    call output ;
    mov al, ' ' ; Stampa uno spazio (di separazione)
    call output ;  
    ; 3.b.
    mov al, VETT1[si]   ; AL <- VETT[SI] si-esimo elemento di VETT1
    mov bh, 0   ; in bh memorizza il numero di bit a 1
    mov bl, 8   ; in bl memorizza le iterazioni necessarie per shiftare
                ; il byte considerato
ciclo3b:
    shl al, 1
    jc bit1
    jmp testciclo3b
bit1:
    inc bh      ; incrementa bx (tiene conto del numero di bit a 1)    
testciclo3b:    
    dec bl      ; Decrementa bl (contatore del ciclo3b),
    jnz ciclo3b ; se bl non e' zero torna all'inizio del ciclo.
    mov al, bh  ; AL <- BH
    add al, 30h ; Conversione da binario (compreso tra 0 e 8) a codifica ASCII
    call output
    mov al, ' ' ; Stampa uno spazio (di separazione)
    call output ;  

    ; 3.c.
    mov al, VETT2[si]   ; AL <- VETT[SI] si-esimo elemento di VETT2
    mov bh, 0   ; in bh memorizza il numero di bit a 0
    mov bl, 8   ; in bl memorizza le iterazioni necessarie per shiftare
                ; il byte considerato
ciclo3c:
    shl al, 1
    jnc bit0
    jmp testciclo3c
bit0:
    inc bh      ; incrementa bx (tiene conto del numero di bit a 1)    
testciclo3c:    
    dec bl      ; Decrementa bl (contatore del ciclo3b),
    jnz ciclo3c ; se bl non e' zero torna all'inizio del ciclo.
    mov al, bh  ; AL <- BH
    add al, 30h ; Conversione da binario (compreso tra 0 e 8) a codifica ASCII
    call output
    mov al, ' ' ; Stampa uno spazio (di separazione)
    call output ;  
    
    ; 3.d.
    mov al, VETT1[SI]   ; Converte VETT1[SI] in decimale
    call bin2AAA        ; codificato ASCII
    mov al, ' ' ; Stampa uno spazio (di separazione)
    call output ;  
    
    ; 3.e.
    mov al, VETT2[SI]   ; Converte VETT2[SI] in decimale
    call bin2AAA        ; codificato ASCII
    mov al, ' ' ; Stampa uno spazio (di separazione)
    call output ;  
    
    ; 3.f.
    mov ah, 0
    mov al, VETT1[SI]   ; AX <- VETT1[SI]
    mov bh, 0
    mov bl, VETT2[SI]   ; BX <- VETT2[SI]
    add ax,bx           ; AX = AX + BX = VETT1[SI] + VETT2[SI]
    shr ax, 1           ; AX = AX / 2 (= AL , AH=0)
    call bin2AAA        ; Converte AL in decimale codificato ASCII
    mov al, ' ' ; Stampa uno spazio (di separazione)
    call output ;  
    
    ; fine ciclo3
    inc si      ; Incremento indice vettore
    dec cl      ; Decremento contatore ciclo:
    jnz ciclo3  ; se non e' zero continuo il ciclo.
    pop si
    pop cx
    pop bx
    pop ax
    ret
punto3 endp

; input - Procedura per prelevare un carattere da tastiera    
;   Il carattere letto e' restituito in AL.
input proc 
   	mov ah, 7
	int 21h
    ret
input endp

; output - Stampa il carattere contenuto in AL
output proc
    push ax
    push dx
    mov ah, 2
	mov dl, AL
	int 21h       ; output character.
	pop dx
	pop ax
    ret
output endp

; stampaStringa - Stampa una stringa terminata da $ indirizzata dal registro DX
stampaStringa proc
    push ax
    mov ah, 9
    int 21h
    pop ax
    ret
stampaStringa endp

;
; Procedura bin2AAA
; Stampa un numero binario naturale su 8 bit (0..255) in un numero codificato ASCII.
; input: AL = numero da convertire
;
bin2AAA proc
    PUSH AX
    PUSH BX
    MOV AH, 0
    MOV BL, 100    ; BL <- 100
    DIV BL         ; AL = AX / operando (byte) = 0 - 9
                   ; AH = resto                = 0 - 99
    ADD AL, 30h    ; codifica ASCII del quoziente
    CALL output
    MOV AL, AH     ; AL <- AH = 0 - 99
    MOV AH, 0      ; AH <- 0  => AX = 0 - 99
    MOV BL, 10     ; BL <- 10
    DIV BL         ; AL = AX / operando (byte) = 0 - 9
                   ; AH = resto                = 0 - 9
    ADD AL, 30h    ; codifica ASCII del quoziente
    CALL output
    MOV AL, AH     ; AL <- AH = resto
    ADD AL, 30h    ; codifica ASCII del resto
    CALL output
    POP BX
    POP AX
    RET
bin2AAA endp

; newline - Stampa il newline
newline proc
    push ax
    mov al, 0Ah
    call output
    mov al, 0Dh
    call output
    pop ax
    ret
newline endp

end start ; set entry point and stop the assembler.