|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jan 2003
Città: Parma
Messaggi: 61
|
[ASSEMBLY/x86] Contare sequenza numeri
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 Ultima modifica di aedesy : 29-06-2013 alle 00:03. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
|
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 06:39.