Visualizzazione dei risultati da 1 a 4 su 4
  1. #1

    [ASM] LA cpu NTVDM ha inontaro un istruzione non valida

    salve a tutti, posto qui per chiedere aiuto...da diversi giorni ho questo problema sul mio codice cioè compilo faccio il linking ma quando vado ad eseguire mi dice: LA cpu NTVDM ha inontaro un istruzione non valida! Tutto ha avuto inizio quando ho iniziato ad usare i registri eax e edx e a porre all'inizio del file il .386 difatti se elimino questi il tutto gira perfettamente però nn posso fare a meno di utlizzare i registri eax e edx per una funzione ke stò facendo...posto il codice con la speranza ke qualcuno di voi sappia dirmi cosa sbaglio...

    TITLE - Esercitazione di Calcolatori Elettronici

    ;.386
    ;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
    MODE_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
    PRE_LEN EQU 10

    DSEG SEGMENT PARA PUBLIC 'DATA'

    SEGNO DB ?
    NUM DW 0
    NUM_A2 DW 0
    NUM_QUADR DD 0
    DIVD DW ?
    ERR_MESS DB CR,LF,LF,CR,'Valore non ammesso.Inserire un nuovo numero compreso tra -999 e 999:',0DH,0AH,'$'

    TITOLO DB 'CORSO di CALCOLATORI ELETTRONICI$'
    ISTRUZIONI DB CR,LF,LF,CR,'Inserire un numero compreso tra -999 e 999:$'
    BIN_MESS DB CR,LF,HT,HT,'Rappresentazione Binaria:$'
    A2_MESS DB CR,LF,HT,HT,'Rappresentazione Binaria in complemento A2:$'

    DEC_MESS DB CR,LF,HT,HT,'Rappresentazione Decimale del quadrato del numero:$'
    TERMINE DB CR,LF,LF,HT,'Un altra iterazione? [S/N]$'
    CODICE_TASTO DB ?
    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,DSSEG,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 LETTURA_DATI


    CALL STAMPA_BIN
    CALL COMP_A2
    CALL STAMPA_A2
    CALL QUADR
    CALL STAMPA_DEC
    CALL TEST_FINALE
    JNZ CICLO_PRINCIPALE
    RET ;Ritorno al Sistema Operativo
    MAIN ENDP


    ;----------------------------------------------------------------------------------;
    ; Procedura di inizializzazione ;
    ;----------------------------------------------------------------------------------;

    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,MODE_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 nel pos scelta

    MOV DX,OFFSET TITOLO ;Sceglie la stringa (DSX)
    CALL STAMPA_STRINGA ;e la stampa.

    MOV DX,0400h ;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
    ;-----------------------------------------------------------------------------------;

    PROMPT PROC NEAR
    MOV DX,OFFSET ISTRUZIONI ;Sceglie la stringa (DSX)
    CALL STAMPA_STRINGA ; e la stampa.
    RET ;Ritorna alla procedura chiamante
    PROMPT ENDP

    ;-----------------------------------------------------------------------------------;
    ; Procedura per stampare un numero in formato binario
    ;-----------------------------------------------------------------------------------;

    STAMPA_BIN PROC NEAR
    MOV DX,OFFSET BIN_MESS ;Sceglie la stringa (DSX)
    CALL STAMPA_STRINGA ;e la stampa.
    MOV DX,[NUM] ;Carica il numero inserito
    MOV BL,10h ;Contatore di bits
    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
    CALL STAMPA_NUMERO ;Stampa cifra binaria
    DEC BL ;Decrementa il contatore del ciclo
    JNZ CICLO_BINARIO ;Se non é 0 itera un altra volta
    RET ;Ritorno alla procedura chiamante
    STAMPA_BIN ENDP

    ;-----------------------------------------------------------------------------------;
    ; Procedura per stampare in formato binario il numero in complemento a2 ;

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

    STAMPA_A2 PROC NEAR
    MOV DX,OFFSET A2_MESS ;Sceglie la stringa (DSX)
    CALL STAMPA_STRINGA ;e la stampa.
    CALL COMP_A2 ;Vado a complementare il numero
    MOV DX,[NUM_A2] ;Carica il numero inserito
    MOV BL,10h ;Contatore di bits
    CICLO_BINARIO1: XOR AL,AL ;Azzera il registro AL
    SHL DX,01h ;shift logico a Sinistra
    ADC AL,AL ;In AL si pone il CARRY
    CALL STAMPA_NUMERO ;Stampa cifra binaria
    DEC BL ;Decrementa il contatore del ciclo
    JNZ CICLO_BINARIO1 ;Se non é 0 itera un altra volta
    RET ;Ritorno alla procedura chiamante
    STAMPA_A2 ENDP


    ;-----------------------------------------------------------------------------------;
    ; Procedura per stampare un numero in formato decimale
    ;-----------------------------------------------------------------------------------;

    STAMPA_DEC PROC NEAR
    ;...

    RET ;ritorno alla procedura chiamante
    STAMPA_DEC ENDP

    ;-----------------------------------------------------------------------------------;
    ; Procedura per fare il complemento A2 del numero inserito
    ;-----------------------------------------------------------------------------------;

    COMP_A2 PROC NEAR
    MOV SEGNO,0; azzero il flag del segno
    MOV DX,[NUM];carico il numero inserito
    NOT DX; ne faccio il complemento a1
    ADD DX,1B;aggiungo 1 per fare il complemento a2
    MOV NUM_A2,DX;

    RET
    COMP_A2 ENDP


    ;-----------------------------------------------------------------------------------;
    ; Procedura per fare il quadrato del numero inserito
    ;-----------------------------------------------------------------------------------;
    QUADR PROC NEAR
    MOV AX,NUM
    MUL NUM; risultato della moltiplicazione in DX:AX
    SHL EDX,16
    MOV DX,AX
    MOV NUM_QUADR,EDX

    RET
    QUADR ENDP



    ;------------------------------------------------------------------------------------;
    ; Procedura per determinare se occorre un'altra iterazione ;
    ; ;
    ; REGISTRI UTILIZZATI: AX, DX ;
    ; CODICE DI RITORNO: ;
    ; Zero flag = 0 -> un'altra iterazione ;
    ; Zero flag = 1 -> esci dal programma ;
    ;------------------------------------------------------------------------------------;

    TEST_FINALE PROC NEAR
    MOV DX,OFFSET TERMINE ;Sceglie la strinaga (DSX)
    CALL STAMPA_STRINGA ;e la stampa.
    CALL LETTURA_SN ;legge la stringa senza echo.
    CMP AL,'n' ;modifica il FLAG 'Z'
    RET ;Ritorno alla procedura chiamante
    TEST_FINALE ENDP


    ;************************************************* ***********************************;
    ;* Procedura di basso livello di interfaccia *;
    ;************************************************* ***********************************;

    ;------------------------------------------------------------------------------------;
    ; Procedura per stampare un numero da 0 a 9 ;
    ;------------------------------------------------------------------------------------;

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


    ;-----------------------------------------------------------------------------------;
    ; Procedura per leggere il numero immesso e memorizzarlo in BUFFER
    ;-----------------------------------------------------------------------------------;

    LETTURA_DATI PROC NEAR

    LAB0: XOR DX,DX
    LAB1: MOV BX,10
    MOV AH,08H ;legge un carattere senza echo
    INT 21H
    CMP AL,CR ;controlla è un invio?
    JE FINE
    CMP AL,'-'
    JE MOD_SEGNO
    CONTINUA: CMP AL,'0'
    JB LAB1
    CMP AL,'9'
    JA LAB1
    PUSH DX
    MOV DL,AL
    MOV AH,02H ;se ho premuto un numero lo stampo a video
    INT 21H
    POP DX
    SUB AL,'0';sottrae la codifica di zero
    XCHG AX,BX
    XOR BH,BH
    MUL DX;moltiplica per 10
    MOV DX,AX
    ADD DX,BX;somma la cifra letta
    MOV NUM,DX
    CMP NUM,999
    JA I_ERR
    JMP LAB1
    I_ERR: LEA DX, ERR_MESS
    MOV AH,9
    INT 21H
    JMP LAB0
    MOD_SEGNO: MOV SEGNO,1
    PUSH DX
    MOV DL,AL
    MOV AH,02H ;stampo il segno '-'
    INT 21H
    POP DX
    JMP CONTINUA
    COMPLEMENTA: MOV SEGNO,0
    NOT NUM
    ADD NUM,1B
    JMP FINE
    FINE: CMP SEGNO,1
    JE COMPLEMENTA
    RET


    LETTURA_DATI ENDP



    ;------------------------------------------------------------------------------------;
    ; Procedura per leggere da tastiera uno dei tasti 'S' o 'N'
    ;------------------------------------------------------------------------------------;

    LETTURA_SN PROC NEAR
    NUOVA_LETTURA: MOV AH,R_KEY_CHR_NE ;Servizio DOS 'Read keyboard char'
    INT DOS ;Whitout echo
    OR AL,00100000b ;Converte in minuscolo
    CMP AL,'n' ;Se il tasto premuto é 'N' esce
    JZ FINE_LETTURA ;dalla procedura
    CMP AL,'s' ;Se non é 's', ne legge
    JNZ NUOVA_LETTURA ;un altro
    FINE_LETTURA: RET
    LETTURA_SN ENDP



    ;-----------------------------------------------------------------------------------;
    ; Procedura per spostare il cursore
    ;-----------------------------------------------------------------------------------;

    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


    ;-----------------------------------------------------------------------------------;
    ; Procedura per stampare una stringa ;
    ; ;
    ; PARAMETRI: l'indirizzo della stringa é memorizzato in DSX ;
    ; REGISTRI UTILIZZATI: AH, DX ;
    ;-----------------------------------------------------------------------------------;

    STAMPA_STRINGA PROC NEAR
    MOV AH,PRINT_STRING ;Servizio DOS 'Print String'; la
    INT DOS ;stringa é puntata da DSX.
    RET ;Ritorno alla procedura chiamante
    STAMPA_STRINGA ENDP


    CSEG ENDS
    END MAIN

  2. #2
    Nessuno ha idea di cosa sbaglio?!HELP ME!!!

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [ASM] LA cpu NTVDM ha inontaro un istruzione non valida

    Originariamente inviato da faster589
    LA cpu NTVDM ha inontaro un istruzione non valida! Tutto ha avuto inizio quando ho iniziato ad usare i registri eax e edx e a porre all'inizio del file il .386 difatti se elimino questi il tutto gira perfettamente però nn posso fare a meno di utlizzare i registri eax e edx per una funzione ke stò facendo...posto il codice con la speranza ke qualcuno di voi sappia dirmi cosa sbaglio...
    Il fatto è che se metti .386, per default i segmenti diventano a 32 bit.

    Metti:
    .386

    DSEG SEGMENT PARA PUBLIC USE16 'DATA'

    ecc.... lo stesso USE16 anche per gli altri segmenti
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  4. #4
    Grazie 1000 funziona!!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.