Salve a tutti. Sono alle prese con la prese con la tesina di Calcolatori. Una bellissima materia per quanto mi riguarda ma vedo che l'Assembly

(TASM) è alquanto ostico per un neofita come me. Ma vediamo comunque di riuscire a farcela. Dati due numeri A e B devo contare il numero di volte

che si presenta la sequenza '0110' dei numeri compresi tra A e B. Per adesso ho svolto il codice per trovare la sequeza in solo numero, sviluppando

i seguenti passi:

1) Aquisisco il numero come stringa di caratteri
2) Lo converto in word
3) Lo converto in binario
4) Controllo la il numero di volte che si presenta '0110'
5) Stampo il risultato

Di problemi ne ho incontrati strada facendo ma grazie all'aiuto del debug sono riuscito a risorverli. Solo che adesso, nel debug, in corrispodenza

della procedura STAMPA_BIN compaiono delle istruzioni che non riesco a capire e che mi portano ad avere come risultato sempre zero. Nello

specifico in corrispondenza di

SHL DX,01h
ADC AL,AL
MOV CS:[SI],AL
INC SI
DEC CL

corrispondono

XOR DH,[3232]
XOR AL,00
ADD AL,46
DEC CL

e non mi so spiegare il perché. Spero che qualcuno mi possa aiutare. Grazie


codice:
;Definizione costanti
PAGINA    	EQU   	00h
HT  		EQU   	09h
LF   		EQU   	0Ah
CR		EQU   	0Dh
;
BIOS_VIDEO	EQU	10H
SET_VIDEO_MODE 	EQU	00h 	;in AH
MODO_TESTO	EQU	03H	;in AL
;
SET_CURSOR	EQU	02h 	;in AH
W_CHR_TTY	EQU	0Eh  	;in AH
;
DOS		EQU	21H
R_KEY_CHR 	EQU	01H
PRINT_STRING	EQU	09H
R_KEY_CHR_NE 	EQU	07h 


DSEG              SEGMENT PARA PUBLIC 'DATA'
TITOLO            DB    'CORSO di CALCOLATORI ELETTRONICI$'
ISTRUZIONE_1        DB    CR,LF,LF,HT,'Digita il primo numero (max 5 cifre): $'
BIN_MESS           DB    CR,LF,HT,HT,'Rappresentazione Binaria: $'
TERMINE            DB    CR,LF,LF,HT,'Un''altra iterazione? [S/N]$'
MSG_ERRORE     DB    CR,LF,LF,HT,'Sono permessi solo caratteri numerici! Pertanto...$'
MSG_EMPTY       DB CR,LF,LF,HT,'Non hai scritto nessun numero$'
RIS                     DB CR,LF,LF,HT,'IL RISULTATO E $' 
NUM_1               DB 5 DUP(?)
NUM_B               Db 16 DUP (?)
DSEG              ENDS


STACKM            SEGMENT PARA STACK 'STACK'  ;Viene allocata una zona di
                  DB      64 DUP('12345678')  ; memoria per lo Stack: in
STACKM            ENDS                        ; tutto 64*8 bytes.


                  ASSUME CS:CSEG,DS: DSEG,SS:STACKM
CSEG              SEGMENT PARA PUBLIC 'CODE'


;---------------------------------------------------------------------;
;                   Corpo principale del programma                    ;
;---------------------------------------------------------------------;

MAIN              PROC  FAR
                  PUSH  DS              ;Istruzioni da lasciare SEMPRE
                  MOV   AX,00h          ; al principio dei programmi!
                  PUSH  AX              ;
                  CALL  INIZIALIZZAZIONE
CICLO_PRINCIPALE: CALL  PROMPT
                  CALL ACQUISIZIONE_1
                  CALL CONVERSIONE
                  CALL STAMPA_BIN
                  CALL CONTROLLO
                  CALL STAMPA_RIS
                  CALL  TEST_FINALE
                  JNZ   CICLO_PRINCIPALE
                  RET                   ;Ritorno al Sistema Operativo
MAIN              ENDP



INIZIALIZZAZIONE  PROC  NEAR
                  MOV   AX,DSEG         ;Inizializzazione segmento dati
                  MOV   DS,AX           ; tramite il registro AX.

                  MOV   AH,SET_VIDEO_MODE  ;Servizio BIOS 'Set Video Mode':
                  MOV   AL,MODO_TESTO  	; modo testo 80 x 25, colori
                  INT   BIOS_VIDEO            ;

                  MOV   DX,0315h        ;Imposta riga (DH) e colonna (DL)
                  CALL  SPOSTA_CURSORE  ;Muove il cursore nella pos scelta

                  MOV   DX,OFFSET TITOLO 
                  CALL  STAMPA_STRINGA  ; e la stampa.

                  MOV   DX,0606h        ;Imposta riga (DH) e colonna (DL)
                  CALL  SPOSTA_CURSORE  ;Muove il cursore nella pos scelta
                  RET                   ;Ritorno alla procedura chiamante
INIZIALIZZAZIONE  ENDP


;---------------------------------------------------------------------;
;              Procedura per stampare il messaggio iniziale           ;
;                                                                     ;
; REGISTRI UTILIZZATI: DX, AH                                         ;
;---------------------------------------------------------------------;

PROMPT            PROC  NEAR
                  MOV   DX,OFFSET ISTRUZIONE_1 
                  CALL  STAMPA_STRINGA  ; e la stampa.
                  RET                   ;Ritorno alla procedura chiamante
PROMPT            ENDP

;------------------------------------------------------------------------;
;  Procedura per l'acquisione del primo numero;
;------------------------------------------------------------------------;

ACQUISIZIONE_1 PROC NEAR
   INIZIO_1: LEA SI,NUM_1
                    MOV CL,05d
                    MOV CH,0
  CICLO_1:  MOV AH,R_KEY_CHR
                    INT DOS
                    CMP AL,CR
                    JE FINE_1
                    CMP AL,'9'
                    JG ERRORE_1
                    CMP AL,'0'
                    JL ERRORE_1
                    MOV CS:[SI],AL
                    INC SI
                    LOOP CICLO_1
                    JMP FINE_1
 ERRORE_1: LEA DX,MSG_ERRORE
                   CALL STAMPA_STRINGA
                   LEA DX,ISTRUZIONE_1
                   CALL STAMPA_STRINGA
                   JMP INIZIO_1
     FINE_1: MOV AL,00H
                   MOV CS:[SI],AL
                   RET
ACQUISIZIONE_1 ENDP                  
                   
;-----------------------------------------------------------------;
CONVERSIONE PROC NEAR
                   LEA SI,NUM_1  
                   PUSH BX
                   PUSH CX
                   PUSH BP
                   PUSH SI 
                                   
                  MOV CX,0000H
    START:   MOV AL,CS:[SI]
                   CMP AL,00H
                   JE EMPTY
                   INC CX
                   INC SI
                   JMP START
    EMPTY:   POP SI
                   MOV AX,0000H
                   CMP CX,0000H
                   JE W1
                   
                   MOV AX,5
                   SUB AX,CX
                   MOV CX,AX
                   CMP CX,0000H
                   JE W5
             W2:   PUSH CX
                   MOV BX,5
                   MOV CX,5
           W3:    MOV AL,CS:[SI+BX-1]
                   MOV CS:[SI+BX],AL
                   DEC BX
                   LOOP W3
                   MOV AL,'0'
                   MOV CS:[SI+BX],AL
                   POP CX
                   LOOP W2
                   
                             
         W5:    MOV BP,0000H
                   MOV CX,5
                   MOV BX,10000
          W4:   MOV AL,CS:[SI]
                   SUB AL,'0'
                   MOV AH,00H
                   MUL BX
                   INC SI
                   ADD BP,AX
                   MOV AX,BX
                   MOV BX,10
                   DIV BX
                   MOV BX,AX
                   LOOP W4
                 
                   MOV AX,BP
                   JMP FINE_CONV
                
  W1:      LEA DX,MSG_EMPTY
                  CALL STAMPA_STRINGA
                  JMP FINE_CONV
 
 FINE_CONV:  POP BP
                      
                      POP CX
                      POP BX
                      RET
CONVERSIONE ENDP

;---------------------------------------------------------------;

STAMPA_BIN PROC NEAR

                            LEA SI,NUM_B
                              MOV DX,AX
                              MOV CL,10H
 CICLO_BINARIO:    XOR   AL,AL           ;Azzera il registro AL
                  SHL   DX,01h          ;Shift Logico a Sinistra
                  ADC   AL,AL           ;In AL si pone il CARRY
                  MOV CS:[SI],AL
                  INC  SI
                  DEC   CL              ;Decrementa il contatore del ciclo
                  JNZ   CICLO_BINARIO   ;Se non e' 0 itera un'altra volta
                  RET                   ;Ritorno alla procedura chiamante
                  
STAMPA_BIN  ENDP


CONTROLLO PROC NEAR
MOV BX,0000H
MOV CL,00H
LEA SI,NUM_B

 BO_0: MOV AL,CS:[SI]
 BO_X: CMP CL,16
            JE FINE_CO
 BO_Z: CMP AL,0
          JE BO_1
          INC SI
          INC CL
          JMP BO_0
 
 BO_1: INC SI
          INC CL
          CMP CL,16
          JE FINE_CO
          MOV AL,CS:[SI]
          CMP AL,1
          JE BO_2
          JMP BO_0
          
  BO_2: INC SI 
           INC CL
           CMP CL,16
           JE FINE_CO
           MOV AL,CS:[SI]
           CMP AL,1
           JE BO_3
           JMP BO_0
           
  BO_3: INC SI
           INC CL
           MOV AL,CS:[SI]
           CMP AL,0
           JE CO5
           JMP BO_X
           
  CO5: INC BX
           CMP CL,16
           JE FINE_CO
           JMP BO_Z  
           
 FINE_CO: RET 
CONTROLLO ENDP



STAMPA_RIS PROC NEAR
  MOV DX,OFFSET RIS
  CALL STAMPA_STRINGA
             MOV AX,BX
             CMP AX,10000
             JC SRW_0
             MOV DX,0000H
             MOV BX,10000
             DIV BX
             CALL STAMPA_NUMERO
             MOV AX,DX
             JMP SRW_1
  SRW_0: CMP AX,1000
             JC SRB_0
  SRW_1: MOV DX,0000H
            MOV BX,1000
            DIV BX
            CALL STAMPA_NUMERO
            MOV AX,DX
            JMP SRB_1
            
    SRB_0: CMP AX,100
                 JC SRB_2
    SRB_1: MOV BL,100
                DIV BL
                CALL STAMPA_NUMERO
                MOV AL,AH
                MOV AH,00H
                JMP SRB_3
     SRB_2: CMP AX,10
                 JC SRB_4
      SRB_3: MOV BL,10
                 DIV BL
                 CALL STAMPA_NUMERO
                 MOV AL,AH
      SRB_4: CALL STAMPA_NUMERO           
  
 RET
STAMPA_RIS ENDP

TEST_FINALE       PROC  NEAR
                  MOV   DX,OFFSET TERMINE 
                  CALL  STAMPA_STRINGA  ; e la stampa.
                  CALL  LETTURA_SN      ;Legge da tastiera senza echo.
                  CMP   AL,'n'          ;Modifica il FLAG 'Z'
                  RET                   ;Ritorno alla procedura chiamante
TEST_FINALE       ENDP


STAMPA_NUMERO     PROC  NEAR
                  ADD   AL,'0'          ;La base da cui partire e' '0'
                  MOV   AH,W_CHR_TTY	;Servizio BIOS 'Write Char in TTY'
                  INT   BIOS_VIDEO
                  RET                   ;Ritorno alla procedura chiamante
STAMPA_NUMERO     ENDP

LETTURA_SN        PROC  NEAR
NUOVA_LETTURA:    MOV   AH,R_KEY_CHR_NE	;Servizio DOS 'Read Keyboard Char
                  INT   DOS             ; Without Echo'
                  OR    AL,00100000b    ;Converte in minuscolo
                  CMP   AL,'n'          ;Se il tasto premuto e' 'N' esce
                  JZ    FINE_LETTURA    ; dalla procedura
                  CMP   AL,'s'          ;Se non e' 'S', ne legge
                  JNZ   NUOVA_LETTURA   ; un altro
FINE_LETTURA:     RET                   ;Ritorno alla procedura chiamante
LETTURA_SN        ENDP

SPOSTA_CURSORE    PROC  NEAR   
                  MOV   BH,PAGINA       ;Pagina video attiva.
                  MOV   AH,SET_CURSOR	;Servizio BIOS 'Set Cursor
                  INT   BIOS_VIDEO      ; Position'
                  RET                   ;Ritorno alla procedura chiamante
SPOSTA_CURSORE    ENDP


STAMPA_STRINGA    PROC  NEAR 
                  MOV   AH,PRINT_STRING ;Servizio DOS 'Print String'; la
                  INT   DOS             
                  RET                   ;Ritorno alla procedura chiamante
STAMPA_STRINGA    ENDP


CSEG              ENDS
                  END  MAIN