TITLE udhcount.asm: dal compito 17/06/2022 comment * simulazione del contatore mod 3 con modalita' di funzionamento up/down/hold progettato per l'esercizio del compito 17/06/2022. Generazione di una delle 720 possibili sequenze di 6 triplette di suoni ottenibili permutando i tre suoni "abc". Data ultima modifica: 15 giugno 2022. * ;----------------------------------------------------------------- ; Definizione costanti CR EQU 13 ; carriage return LF EQU 10 ; line feed DOLLAR EQU '$' u equ 0 ; codifica degli input della macchina M1 d equ 1 h equ 2 ;----------------------------------------------------------------- ; M A C R O ;----------------------------------------------------------------- display macro xxxx ; N.B. ogni stringa deve terminare con '$' push dx push ax mov dx,offset xxxx mov ah,9 int 21h pop ax pop dx endm ;----------------------------------------------------------------- ; PILA SEGMENT STACK 'STACK' ; definizione del segmento di stack DB 16 DUP('STACK') ; lo stack e' riempito con la stringa 'stack' ; per identificarlo meglio in fase di debug PILA ENDS ;----------------------------------------------------------------- ; DATI SEGMENT PUBLIC 'DATA' ; definizione del segmento dati n equ 21 ; lunghezza del vettore di input = numero di colpi di clock usati per la simulazione ;inputs label byte ; con l'etichetta "inputs" posta qui, si usa il vettore di input "ups" ups db n dup (u) ; vettore di tutti 0: con questo input, la macchina deve avere un'uscita periodica "abcabc..." ;inputs label byte ; con l'etichetta "inputs" posta qui, si usa il vettore di input "downs" downs db n dup (d) ; vettore di tutti 1: con questo input, la macchina deve avere un'uscita periodica "acbacb..." ;inputs label byte ; con l'etichetta "inputs" posta qui, si usa il vettore di input "holds" holds db n dup (h) ; vettore di tutti 2: con questo input, la macchina deve avere un'uscita periodica "ppppp..." (con 'p' = campana corrispondente allo stato di inizializzazione) inputs db u,u,d,d,d,h,u,u,u,d,d,u,u,u,h,d,d,d,u,u,d ; input di test riportato nel compito "A": l'uscita corrispondente dev'essere "abcbaccabcbabcaacbabc" ;inputs db u,u,h,d,d,d,u,u,d,d,d,h,u,u,u,d,d,u,u,u,h ; input di test riportato nel compito "B": l'uscita corrispondente dev'essere "abccbacabacbbcabacabc" ;inputs db u,u,d,u,u,d,u,u,d,d,d,h,d,d,h,d,d,h,u,u,d ; input che deve generare la macchina M2 del compito "A" per ottenere l'uscita desiderata "abcbcacabacbbaccbaabc" ;inputs db u,u,h,u,u,h,u,u,h,d,d,u,d,d,u,d,d,u,u,u,h ; input che deve generare la macchina M2 del compito "B" per ottenere l'uscita desiderata "abccabbcaacbcbabacabc" initialization_state db 0 ; la macchina parte da questo stato ; realizzazione in memoria della tabella dello stato futuro (in funzione di stati presente e dell'ingresso) table_pointers dw 3 dup(?) ; vettore dei puntatori (N.B. ciascuno di 2 byte!) ai tre vettori degli stati futuri ; vettori degli stati futuri (ce n'e' uno per ciascuno stato presente; come indice all'interno del vettore si usera' l'ingresso) future_states_from_0 db 1,2,0 future_states_from_1 db 2,0,1 ; si legge cosi': "nello stato 1, se l'ingresso e' 0 allora lo stato futuro e' 2, se e' 1 lo s.f. e' 0, se e' 2 lo s.f. e' 1" future_states_from_2 db 0,1,2 ;Look-up table usata per convertire i valori numerici 0,1,2 degli inputs nei caratteri ASCII 'u','d','h' LUTin DB 'u','d','h' ; all'offset 0 corrisponde il carattere ASCII 'u', etc. ; N.B. look-up table che associa ogni stato presente alla campana da suonare corrispondente output_from_present_state db 'a','b','c' ; lookup table che associa un valore ASCII di uscita a ciascuno stato presente ;(come indice all'interno del vettore si usera' lo stato presente) IN_msg db "Sequenza d'ingresso: ",DOLLAR ; stringhe contenenti messaggi di output a video SP_msg db "Stati attraversati: ",DOLLAR OUT_msg db "Campane suonate: ",DOLLAR asciinputs db n dup (?),DOLLAR ; stringa ASCII degli ingressi forniti alla macchina (convertita dalla stringa binaria "inputs" dal programma e alla fine stampata a video) prestates db n dup (?),DOLLAR ; stringa ASCII degli stati (presenti) attraversati dalla macchina (riempita dal programma e alla fine stampata a video) outputs db n dup (?),DOLLAR ; stringa ASCII delle uscite calcolate dalla macchina (riempita dal programma e alla fine stampata a video) CRLF db CR,LF,DOLLAR ; per formattazione output DATI ENDS ;================================================================= CSEG SEGMENT PUBLIC 'CODE' MAIN proc far ASSUME CS:CSEG,DS:DATI,SS:PILA,ES:NOTHING; MOV AX,DATI MOV DS,AX display crlf inizializzazione: mov bx,offset future_states_from_0 mov table_pointers[0],bx add bx,3 ; N.B. il numero di stati futuri (e dunque anche la lunghezza del vettore future_states_from_0) e' 3 mov table_pointers[2],bx ; qui bx contiene l'offset di future_states_from_1; N.B. table_pointers va incrementato di due byte, perche' e' un vettore di words add bx,3 mov table_pointers[4],bx ; qui bx contiene l'offset di future_states_from_2 xor ah,ah ; siccome sia gli ingressi che stati possibili sono solo 0,1, o 2, xor bh,bh ; per rappresentarli bastebbe la parte bassa dei registri (8 bit), ma i registri xor dh,dh ; dovranno essere usati anche interi (16 bit), e per questo si fa l'estensione di segno mov bl,initialization_state xor si,si ; inizializzazione dell'indice all'interno delle stringhe (inputs,states,outputs) mov cx,n ; inizializzazione del contatore con il numero di iterazioni da eseguire funzionamento: ; INGRESSO mov al,inputs[si] ; lettura del valore di input: al contiene qui l'ingresso in formato binario: 0 per u, 1 per d, 2 per h mov di,ax ; si copia la versione estesa a 16 bit di al in di, in modo da utilizzare quest'ultimo registro come indice nella look-up table mov dl, LUTin[di] ; si converte l'ingresso al (=0,1, o 2) nel carattere ASCII corrispondente (='u','d' o 'h), ponendolo in dl mov asciinputs[si],dl ; salvataggio dell'ingresso (formato ASCII) nella stringa "asciinputs" ; STATO PRESENTE mov dl,bl ; dl contiene qui lo stato presente in formato binario add dl, '0' ; dl contiene qui lo stato presente in formato ASCII mov prestates[si],dl ; salvataggio dell'uscita (formato ASCII) nella stringa "prestates" ; USCITA (N.B. nel caso del contatore, la funzione di uscita e' l'identita' e dunque le uscite sono uguali agli stati presenti) mov dl,output_from_present_state[bx] ; bx contiene qui lo stato presente, dl l'uscita (formato ASCII) mov outputs[si],dl ; salvataggio dell'uscita nella stringa "outputs" ; STATO FUTURO shl bx,1 ; lo stato presente, che e' in bx, viene raddoppiato perche' usato nell'istruzione successiva come indice nel vettore di words mov di,table_pointers[bx] ; di contiene qui l'offset del vettore degli stati futuri dallo stato presente add di,ax ; il puntatore e' posizionato sul giusto stato futuro, servendosi dell'input in ax come indice (di <- di+ax) mov dl,[di] ; lettura dello stato futuro, che alla prossima iterazione sara' in bl (e, nella versione a 16 bit, in bx) aggiornamento: mov bx,dx inc si dec cx jnz funzionamento stampa_a_video: display IN_msg display asciinputs display crlf display SP_msg display prestates display crlf display OUT_msg display outputs display crlf exit: MOV AH,4CH ; ritorno al DOS INT 21H main endp cseg ends END MAIN ; il programma comincia all'indirizzo di MAIN