Fehlermeldung: The NTVDM CPU has encountered an illegal instrction.....



  • CS:120f IP:0331 OP:63 68 65 6e 20

    Hallo an alle!

    Die obenstehende Fehlermeldung bekomme ich ausgegeben, wenn ich versuche meine exe auszuführen.
    Ignoriere ich diese Fehlermeldung funktioniert das Prog. soweit scheinbar richtig.

    Da ich ein absoluter Anfänger in ASM bin und mich schon mit der Aufgabe sehr schwer tue benötige ich dringend Hilfe und wäre echt dankbar, wenn mir jemand dabei helfen könnte.

    Ich habe meinen Projektordner auch gepackt und upgeloadet, falls sich jemand das ganze genauer ansehen möchte.
    *link entfernt*

    TITLE Projektarbeit RecSys
    SUBTTL SCANMAN.asm
    PAGE 56,86
    ;
    ;	STAPELBEREICH
    ;
    STAPEL	SEGMENT STACK
    	dw 400 DUP (?)
    STAPEL 	ENDS
    ;
    include scanequ.asm
    ;
    DATEN	SEGMENT	'DATA'
    ;
    	Infotext 	db cr,lf,"Programm zum suchen eines Strings in einer Textdatei - Info.txt $"		;
    	Textein		db cr,lf,"Bitte geben Sie ihre Suchanfrage ein! $"					;
    	Rueckmeld	db cr,lf,"Ihre Sucheingabe ist: $"							;
    	Ok		db cr,lf,"Datei wurde erfolgreich geoeffnet! $"						;
    	Fehlertext	db cr,lf,"Es ist ein Fehler aufgetreten. Das Programm wird beendet. $"			;
    	Dateiname 	db "Info.txt",0										; Infodatei, 0 maskiert das Ende
    	Umbruch		db cr,lf,"$"										;
    	Handle		dw ?											; Zwischenspeicher Dateihandle
    	Suchtext	dw ?											; Variable für Suchtext
    	Laenge		dw ?											; Länge des Suchtextes
    	Merker		db 1 DUP(0)										;
    	Ziffzaehler	db 1 DUP(0)										;
    	Puffer		db 100 DUP(0)										; Ausgabepuffer
    ;
    DATEN ENDS
    ;
            EXTRN   EIN:FAR,EINL:FAR,
    ;
    SCANMAN	SEGMENT	'CODE'
    ;
    PROG	PROC	FAR
    ;
    ;
    ;	Suchen eines Strings in einer Textdatei
    ;	Stringeingabe erfolgt im DOS-Fenster
    ;
            assume  CS:SCANMAN,DS:DATEN
            assume  ES:DATEN,SS:STAPEL
    ;
    ;
            push    ds
            mov     ax,0
            push    ax
            push    di
            mov     di,daten
            mov     ds,di
            mov     es,di 				
    
    	MOV DX,OFFSET Infotext			; Infotext
    	MOV AH, 009h				;	...
    	INT 21h					;	ausgeben
    
    	MOV DX,OFFSET Umbruch			; manueller
    	MOV AH, 009h				; 	...
    	INT 21h					;	Zeilenumbruch
    
    	MOV DX,OFFSET Textein			; Eingabeaufforderung
    	MOV AH, 009h				;	...
    	INT 21h					;	ausgeben
    
    ;	CALL EINL				; Unterprogramm aufrufen um Sucheingabe zu starten
    ;	MOV Suchtext,BX				; Eingabe..
    ;	MOV Laenge,CX				;	.. sichern
    
    ;	MOV DX,OFFSET Rueckmeld			; Sucheingabe nochmal
    ;	MOV AH, 009h				;	...
    ;	INT 21h					;	...
    ;	MOV DX,OFFSET Suchtext			;	...
    ;	MOV AH, 009h				;	...
    ;	INT 21h					;	ausgeben
    
    	MOV DX,OFFSET Umbruch			; manueller
    	MOV AH, 009h				; 	...
    	INT 21h					;	Zeilenumbruch
    
    	MOV AX, 3d00h				; Dos-Funktion Datei oeffnen, al=0 Modus read only, Dateihandle in AX
    	MOV DX, OFFSET Dateiname		; Dateinamen übergeben
    	XOR CX,CX				; Dateiattribut = normal
    	INT 21h					; Interrupt ausführen
    
    	MOV [Handle], AX			; Dateihandle abspeichern
    	JNC keinFehler				; CF=0 -> Label keinFehler
    	JMP Fehler				; 			sonst Fehlerausgabe
    
    keinFehler:
    	MOV DX,OFFSET Ok			; Ausgabe Datei
    	MOV AH, 009h				;	konnte geoeffnet
    	INT 21h					;			 werden
    
    	MOV DX,OFFSET Umbruch			; manueller
    	MOV AH, 009h				; 	...
    	INT 21h					;	Zeilenumbruch
    
    	MOV AH,3fh				; Dos-Funktion Datei lesen
    	MOV BX,[Handle]				; Datei-Handle uebergeben
    	MOV CX,200				; Anzahl zu lesender Bytes
    	MOV DX, OFFSET Puffer			;
    	INT 21h					; Interrupt ausführen, Dateilänge in AX
    
    	MOV AH,009h				; Dateiinhalt
    	MOV DX,OFFSET Puffer			; 	...
    	INT 21h					;	ausgeben
    
    	MOV DX,OFFSET Umbruch			; manueller
    	MOV AH, 009h				; 	...
    	INT 21h					;	Zeilenumbruch
    ;
    ;##########################################################################
    ;	Suchbeginn
    ;	Suchzeiger 	= SI, zeigt auf aktuelles Zeichen des Suchtextes
    ;	Pufferzeiger 	= DI, zeigt auf aktuelles Zeichen des Dateipuffers
    ;	Merker		- zählt die gefundenen Ergebnisse
    ;	Ziffernzaehler	- 
    ;##########################################################################
    ;
    SUCHE:
    	MOV Merker,0				; Merker normieren
    	MOV Ziffzaehler,0			; Ziffernzähler normieren
    	MOV SI, OFFSET Suchtext			; Zeiger auf Anfang des Suchtextes
    	MOV DI, OFFSET Puffer			; Zeiger auf Anfang des Puffers
    
    	JMP Ende				;
    
    Fehler:	MOV DX,OFFSET Fehlertext		; Fehlertext
    	MOV AH,009h				;	...
    	INT 21h					;	ausgeben
    
    Ende:	MOV AH, 3Eh				; Dos-Funktion Datei schließen
    	MOV BX,[Handle]				; Dateihandle übergeben
    	INT 21h					; Interrupt ausführen
    
    	MOV AH,4ch				; Programm
    	INT 21h					;	beenden
    ;
    PROG    ENDP
            SCANMAN	ENDS
    ;
    ;
            END
    

    Vielen Dank im Voraus



  • Zuerst moechte ich mal darauf hinweise, dass der TASM, den dein Archiv in Teilen enthaelt, keine Freeware ist. Deshalb habe ich den Link erstmal entfernt.

    Offenbar geraet dein Programm da irgendwo in einen String rein. Die in der Fehlermeldung angezeigte Bytefolge entspricht "chen "...
    Ich vermisse auch irgendwie das Start-Label in deinem Code... Wenn man die scan.exe in deinem Archiv in einen Debugger packt, landet man entsprechend zuerst auch in einem Haufen 0-Bytes (offenbar das Stack-Segment). Das macht in diesem Fall zufaellig erstmal nichts, da rauscht die CPU erstmal ohne zu meckern drueber.
    Wenn es die CPU dann jedoch in das direkt nachfolgende Datensegment mit den Text-Strings geraet, gibt es chaos - uA. die Fehlermeldung oben. In sofern wirklich erstaunlich, dass die NTVDM scheinbar bis zum wirklichen Start des Programms durchrennt. DOS-Box macht zB. vorher schlapp mit einem Triple-Fault.

    Also Loesung: Setze einen Einstiegspunkt in deinem Programm. Das ist ein einfaches Label, dessen Namen du am Ende noch mit einem Leerzeichen abgetrennt hinter "END" schreibst.



  • Klasse, danke 😉 Wieder warst du meine Rettung 😉

    Den TASM habe ich von meiner Professorin bekommen, wusste aber auch nicht, dass der nicht free ist. Danke für den Hinweis.



  • Ich habe nun ein anderes Problem, möchte dafür jedoch nicht extra einen Beitrag eröffnen.

    Und zwar sagt mir meiner Compiler in Zeile 126 - illegal memory reference

    Hier ein Auszug aus der betroffenen Stelle. Zeile 126 ist der Vergleich.
    Laenge und Zeichenzaehler sind beide als dw deklariert.

    Laenge		dw ?			; Länge des Suchtextes
    Merker		db 1 DUP(0)		; zählt Such-Übereinstimmungen
    Dateiende	db 1 DUP(0)			; Merker für Dateiende
    Zeichenzaehler	dw ?			; zählt Zeichen-Übereinstimmungen
    Puffer		db 200 DUP(0)		; Ausgabepuffer
    
    INC Zeichenzaehler			; Zeichen gefunden - Zeichenzähler erhöhen
    CMP Laenge,Zeichenzaehler		; Ende Suchtextlänge?
    JNE SCAN3				; 	nein	-> SCAN3
    INC Merker			; Suchergebnis erhöhen
    MOV SI,0				; weitere Suche Zeiger auf Anfang Suchtext
    


  • Die x86-CPU akzeptiert keine 2 Speichervariablen als Operanden.



  • Danke 😉 Wie soll man auch darauf kommen. Habe extra noch in der Befehlsreferenz nachgeschaut ob der Befehl mit Variablen arbeiten kann. Naja kann er, halt nur mit einer 😉



  • Daran solltest du dich besser gewoehnen. Ist AFAIK bei den meisten Feld-Wald-und-Wiesen-CPU so, dass Befehle mit mehreren Speicherreferenzen als Operanden wenn ueberhaupt eher die Ausnahme bilden. 🙂



  • Ok, ich werd versuchen mir das gleich mal zu merken 😉

    Jetzt habe ich ein weiteres Problem. Ich habe mein Programm soweit fertig geschrieben, kann es nun auch richtig compilieren*freu*

    Jedoch finde ich mit Hilfe des Debugers nicht wirklich den Fehler, natürlich funktioniert das ganze nicht so, wie ich es mir vorstelle....

    Ich stelle mal nachfolgend meine Daten zur Verfügung, vielleicht hat jemand soviel erbarmen und kann mich dabei unterstützen.... 😞

    Hier der Ablaufplan des Hauptprogramms, leider sind die Labels nicht gut sichtbar.
    http://click-esports.de/Hauptprogramm.png

    TITLE Projektarbeit RecSys
    SUBTTL SCANMAN.asm
    PAGE 56,86
    ;
    ;	STAPELBEREICH
    ;
    STAPEL	SEGMENT STACK
    	dw 400 DUP (?)
    STAPEL 	ENDS
    ;
    include scanequ.asm
    ;
    DATEN	SEGMENT	'DATA'
    ;
    	Infotext 	db cr,lf,"Programm zum suchen eines Strings in einer Textdatei - Info.txt $"		;
    	Textein		db cr,lf,"Bitte geben Sie ihre Suchanfrage ein! $"					;
    	Rueckmeld	db cr,lf,"Ihre Sucheingabe ist: $"							;
    	Ok		db cr,lf,"Datei wurde erfolgreich geoeffnet! $"						;
    	Fehlertext	db cr,lf,"Es ist ein Fehler aufgetreten. Das Programm wird beendet. $"			;
    	Dateiname 	db "Info.txt",0										; Infodatei, 0 maskiert das Ende
    	Ergebnis	db "Ergebnis.txt",0									; Textdatei für Ergebnissicherung
    	Umbruch		db cr,lf,"$"										;
    	Handle		dw ?											; Zwischenspeicher Dateihandle
    	Suchtext	dw ?											; Variable für Suchtext
    	Laenge		dw ?  											; Länge des Suchtextes
    	Merker		db 1 DUP(0)										; zählt Such-Übereinstimmungen
    	Dateiende	db 1 DUP(0)										; Merker für Dateiende
    	Zeichenzaehler	dw ?											; zählt Zeichen-Übereinstimmungen
    	Puffer		db 200 DUP(0)										; Ausgabepuffer
    ;
    DATEN ENDS
    ;
            EXTRN   EIN:FAR,EINL:FAR
    ;
    SCANMAN	SEGMENT	'CODE'
    ;
    PROG	PROC	FAR
    ;
    ;##########################################################################
    ;	Suchen eines Strings in einer Textdatei
    ;	Stringeingabe erfolgt im DOS-Fenster
    ;##########################################################################
    ;
            assume  CS:SCANMAN,DS:DATEN
            assume  ES:DATEN,SS:STAPEL
    ;
    ;
    main:   PUSH    DS
            MOV     AX,0
            PUSH    AX
            PUSH    DI
            MOV     DI,daten
            MOV     DS,DI
            MOV     ES,DI 				
    ;
    	MOV DX,OFFSET Infotext			; Infotext
    	MOV AH, 009h				;	...
    	INT 21h					;	ausgeben
    	MOV DX,OFFSET Umbruch			; manueller
    	MOV AH, 009h				; 	...
    	INT 21h					;	Zeilenumbruch
    ;
    	MOV DX,OFFSET Textein			; Eingabeaufforderung
    	MOV AH, 009h				;	...
    	INT 21h					;	ausgeben
    ;
    	CALL EINL				; Unterprogramm aufrufen um Sucheingabe zu starten
    	MOV Suchtext,BX				; Eingabe..
    	MOV Laenge,CX				;	.. sichern
    ;
    	MOV DX,OFFSET Umbruch			; manueller
    	MOV AH, 009h				; 	...
    	INT 21h					;	Zeilenumbruch
    ;
    Open:	MOV AX, 3d00h				; Dos-Funktion Datei oeffnen, al=0 Modus read only, Dateihandle in AX
    	MOV DX, OFFSET Dateiname		; Dateinamen übergeben
    	XOR CX,CX				; Dateiattribut = normal
    	INT 21h					; Interrupt ausführen
    ;
    	MOV [Handle], AX			; Dateihandle abspeichern
    	JNC keinFehler				; CF=0 -> Label keinFehler
    	JMP Fehler				; 			sonst Fehlerausgabe
    ;
    keinFehler:
    	MOV DX,OFFSET Ok			; Ausgabe Datei
    	MOV AH, 009h				;	konnte geoeffnet
    	INT 21h					;			 werden
    ;
    ;##########################################################################
    ;	AX		- nach SCAN enthält AX die Anzahl gelesener Zeichen
    ;			  damit auch die max. relevante Pufferlänge
    ;	Suchzeiger 	= SI, zeigt auf aktuelles Zeichen des Suchtextes
    ;	Pufferzeiger 	= DI, zeigt auf aktuelles Zeichen des Dateipuffers
    ;	Merker		- zählt die gefundenen Ergebnisse
    ;	Dateiende	- gibt an, ob das Dateiende erreicht wurde
    ;	Ziffernzaehler	- zählt Zeichen Übereinstimmungen 
    ;			  bis komplettes Suchwort gefunden wurde oder nicht mehr 
    ;			  übereinstimmt
    ;##########################################################################
    ;
    	MOV SI,OFFSET Suchtext			; Zeiger Suchtext auf Anfang
    	MOV Zeichenzaehler,0			; Zeichenzähler normieren
    	MOV Merker,0				; Merker normieren
    ;
    SCAN:	
    	MOV DI,OFFSET Puffer			; Zeiger auf Pufferanfang
    	MOV AH,3fh				; Dos-Funktion Datei lesen
    	MOV BX,[Handle]				; Datei-Handle uebergeben
    	MOV CX,200				; Anzahl zu lesender Bytes
    	LEA DX,Puffer				;
    	INT 21h					; Interrupt ausführen, gelesene Zeichen in AX
    ;
    	JC Fehler				; wenn CF=0 Aufruf erfolgreich, sonst Fehler aufgetreten
    ;
    	CMP CX,AX				; Dateiende erreicht?
    	JL SCAN1				; 	nein 	-> SCAN1
    	MOV Dateiende,1				; 	ja	-> Merker setzen
    ;
    SCAN1:
    	MOV BL,[SI]				; Suchzeichen laden
    	MOV BH,[DI]				; Pufferzeichen laden
    	CMP BL,BH				; Zeichen vergleichen
    	JNE SCAN2				; wenn nicht gleich springe SCAN2
    ;
    	INC Zeichenzaehler			; Zeichen gefunden - Zeichenzähler erhöhen
    	MOV BX,Zeichenzaehler			;
    	CMP Laenge,BX				; Ende Suchtextlänge?
    	JNE SCAN3				; 	nein	-> SCAN3
    	INC Merker				; Suchergebnis erhöhen
    	MOV SI,0				; für weitere Suche Zeiger auf Anfang Suchtext
    ;
    SCAN2: 
    	MOV Zeichenzaehler,0			; Zeichenzähler rücksetzen
    ;
    SCAN4:
    	INC DI					; Pufferzeiger erhöhen
    	CMP AX,DI				; Pufferende?
    	JNL SCAN1				;	nein	-> SCAN1
    	CMP Dateiende,1				; 	ja	-> Vergleich auf Dateiende
    	JNE SCAN				; Dateiende noch nicht erreicht -> SCAN
    ;
    	JMP SAVE				; Ergebnis noch sichern
    ;
    SCAN3:
    	INC SI					; Zeiger Suchtext erhöhen
    	JMP SCAN4				; springe SCAN4
    ;
    SAVE:
    	PUSH Handle				; aktuelles Handle sichern
    	MOV AX, 3d00h				; Dos-Funktion Datei oeffnen, al=0 Modus read only, Dateihandle in AX
    	LEA DX, Ergebnis			; Dateinamen übergeben
    	XOR CX,CX				; Dateiattribut = normal
    	INT 21h					; Interrupt ausführen
    ;
    	MOV [Handle], AX			; Dateihandle abspeichern
    	JC  Ende				; CF=1 -> Fehler -> springe ENDE
    ;
    	MOV AH,40h				; Dos-Funktion Datei beschreiben
    	MOV BX,[Handle]				; 
    	MOV CX,500				; Anzahl zu schreibender Bytes
    	LEA DX,Suchtext				; Suchtext schreiben
    	INT 21h
    ;	
    	MOV AH,40h				; Dos-Funktion Datei beschreiben
    	LEA DX,Umbruch				; umbruch schreiben
    	INT 21h
    ;
    	MOV AH,40h				; Dos-Funktion Datei beschreiben
    	LEA DX,Merker				; Ergebnis schreiben
    	INT 21h
    ;
    	MOV AH, 3Eh				; Dos-Funktion Datei schließen
    	MOV BX,[Handle]				; Dateihandle übergeben
    	INT 21h					; Interrupt ausführen	
    ;
    	POP Handle				; Handle wiederholen
    	JMP ENDE				; Programm beenden
    ;
    Fehler:	MOV DX,AX				; Fehlercode
    	MOV AH,009h				;	...
    	INT 21h					;	ausgeben
    
    	LEA DX,Fehlertext			; Fehlertext
    	MOV AH,009h				;	...
    	INT 21h					;	ausgeben
    ;
    ENDE:	MOV AH, 3Eh				; Dos-Funktion Datei schließen
    	MOV BX,[Handle]				; Dateihandle übergeben
    	INT 21h					; Interrupt ausführen
    ;
    ;	MOV AH,4ch				; Programm
    ;	INT 21h					;	beenden
    ;
    PROG    ENDP
    ;
            SCANMAN	ENDS
    ;
    ;
            END main
    
    TITLE Unterprogramme 
    SUBTTL SCANUPS.asm
    PAGE 56,86
    ;
    include scanequ.asm
    ;
    	PUBLIC EIN, EINL, 
    ;
    SCANUPS	SEGMENT PUBLIC 'CODE'
    ;
    ;
    
    	ASSUME CS:SCANUPS
    ;
    ;##########################################################################
    ;       LESEN ZEICHEN NACH AL MIT ECHO
    ;##########################################################################
    EIN     PROC    FAR
            PUSH    BX
            MOV     BH,AH
            MOV     AH,1
            INT     21H
            MOV     AH,BH
            POP     BX
            RET
    EIN     ENDP
    ;
    ;##########################################################################
    ;       LESEN NATšRLICHE ZAHL NACH <BX>
    ;       ANZAHL ZEICHEN IN CX
    ;       MAXIMALE LŽNGE = LEN1
    ;##########################################################################	
    ;
    EINL	PROC    FAR		;	ausgeben
            PUSH    AX	
    
            XOR     CX,CX           ; ZŽHLER=0
    EINL1:  CALL    EIN
            CMP     AL,CR           ; ENDE DER EINGABE?
            JE      EINL2          	; JA
    ;        CMP     AL,'0'
    ;        JB      EZFEH          ; FEHLER
    ;        CMP     AL,'9'
    ;        JA     EZFEH           ; FEHLER
            CMP     CX,LEN1-1
            JG      EZFEH
            INC     CX
            MOV     [BX],AL
            INC     BX
            JMP     EINL1
    EINL2:  CMP     CX,0
            JZ      EZFEH           ; LEERE EINGABE
            CLC
            POP     AX
            RET
    EZFEH:  STC
            POP     AX
    	RET
    EINL	ENDP
    ;
    ;##########################################################################
    ;       automatischer Zeilenumbruch
    ;##########################################################################
    ;
    ;UMB	PROC	FAR
    ;	MOV DX, 
    ;	MOV AH, Umbruch
    ;	INT 21h
    ;	RET
    ;UMB ENDP
    ;
    SCANUPS	ENDS
    ;
    ;
    END
    
    LEN1    EQU     10                 ; Laenge vom Suchtext
    CR      EQU     0DH                ; carriage return 
    LF      EQU     0AH                ; line feed
    


  • Da stimmt wirklich noch so Einiges nicht.
    Also erstmal zu dem Diagramm: War das eine Arbeitsvorgabe des Lehrers? Dort wird nicht explizit auf den Fall eingegangen, dass beim letzten Einlesen mit Erreichen des Dateiendes sehr wahrscheinlich nicht der gesamte Puffer mit gueltigen Daten gefuellt wird, dh. das "Pufferende" angepasst werden muss. Praktisch wird das evtl. vielleicht oftmals egal sein, es kann aber auch vorkommen, dass so zufaellig ein zusaetzlicher Fund nach Dateiende zustande kommt.

    Ansonsten: Wo hakt es denn genau beim Debuggen? Wie gesagt, "logische" Fehler sind offensichtlich schon noch welche drin, zB. das Zuruecksetzen des "such"-Zeigers als "MOV SI,0" in Zeile 130 wird so bestimmt nicht das machen, was du eigentlich wolltest, um mal einen zu nennen, der mir direkt ins Auge gesprungen ist.

    BTW: weshalb schreibst du in Zeile 110 auf einmal "LEA DX,Puffer" zum Laden des Offsets in dx? Ist so ziemlich ueberfluessig, diese Kombo, weshalb der TASM das beim Assemblieren auch von sich aus stattdessen als "mov dx, offset Puffer" umsetzt.



  • Nobuo T schrieb:

    Da stimmt wirklich noch so Einiges nicht.
    Also erstmal zu dem Diagramm: War das eine Arbeitsvorgabe des Lehrers? Dort wird nicht explizit auf den Fall eingegangen, dass beim letzten Einlesen mit Erreichen des Dateiendes sehr wahrscheinlich nicht der gesamte Puffer mit gueltigen Daten gefuellt wird, dh. das "Pufferende" angepasst werden muss. Praktisch wird das evtl. vielleicht oftmals egal sein, es kann aber auch vorkommen, dass so zufaellig ein zusaetzlicher Fund nach Dateiende zustande kommt.

    Da hast du Recht, den Fall habe ich tatsächlich nicht betrachtet. Wird denke ich aber auch für die Bearbeitung der Aufgabe weniger wichtig sein.

    Ansonsten: Wo hakt es denn genau beim Debuggen? Wie gesagt, "logische" Fehler sind offensichtlich schon noch welche drin, zB. das Zuruecksetzen des "such"-Zeigers als "MOV SI,0" in Zeile 130 wird so bestimmt nicht das machen, was du eigentlich wolltest, um mal einen zu nennen, der mir direkt ins Auge gesprungen ist.

    Wieso wird das mit dem Zeiger nicht funktionieren? Ich dachte, wenn ich den Zeiger die Adresse 0 gebe, geht er wieder zum Anfang? Ich verändere hier ja nicht den Inhalt.

    Beim debuggen hakt es schon alleine daran, dass ich damit weni Erfahrungen habe. Nach der ersten Textausgabe(Infotext) springt der Debugger beim Tracen schon ganz woanders hin, so dass ich schwer einzelne Schritte beobachten kann.

    BTW: weshalb schreibst du in Zeile 110 auf einmal "LEA DX,Puffer" zum Laden des Offsets in dx? Ist so ziemlich ueberfluessig, diese Kombo, weshalb der TASM das beim Assemblieren auch von sich aus stattdessen als "mov dx, offset Puffer" umsetzt.

    Am Anfang hatte ich alles mit OFFSET geschrieben, dann habe ich jedoch gelesen, das der Befehl LEA besser sei. Wenn dem nicht so ist, werde ich es wieder ändern.

    Danke Nubuo T



  • gamefreak schrieb:

    Da hast du Recht, den Fall habe ich tatsächlich nicht betrachtet. Wird denke ich aber auch für die Bearbeitung der Aufgabe weniger wichtig sein.

    Wenn du meinst... IMHO ist das ein nicht zu vernachlaessigender Fehler.

    gamefreak schrieb:

    Wieso wird das mit dem Zeiger nicht funktionieren? Ich dachte, wenn ich den Zeiger die Adresse 0 gebe, geht er wieder zum Anfang? Ich verändere hier ja nicht den Inhalt.

    Liegt der Anfang deines Puffers denn bei DS:0? Ich denke mal nicht. 😉
    War es uebrigens nicht Sinn des Programms, einen String in einer Datei zu finden und irgendwie einen Fund anzuzeigen? Ich vermisse schon allein die Stelle, wo ueberhaupt ein Suchstring irgendwo gegeben wird.

    gamefreak schrieb:

    Beim debuggen hakt es schon alleine daran, dass ich damit weni Erfahrungen habe. Nach der ersten Textausgabe(Infotext) springt der Debugger beim Tracen schon ganz woanders hin, so dass ich schwer einzelne Schritte beobachten kann.

    Tja, ich wuerde aber mal meinen, der Umgang mit einem Debugger ist essenziell wichtig. Sogar irgendwo wichtiger, als selbst mal irgendeinen Schmu zusammengehakt zu haben (solange man dann ueberhaupt weiss, was man da tut 😉 ).

    Also welchen Debugger benutzt du? Den TurboDebugger vom TASM?

    gamefreak schrieb:

    Am Anfang hatte ich alles mit OFFSET geschrieben, dann habe ich jedoch gelesen, das der Befehl LEA besser sei. Wenn dem nicht so ist, werde ich es wieder ändern.

    Waere IMHO in jeder Hinsicht besser. 🙂



  • Für mich beginnt der Zeiger bei 0 😃
    Hier ist auch mein großes Manko, mir fehlt das Verständnis für Adressen/Aufbau/Stack-,Segmentbereich.
    Die Initialisierungen hierzu habe ich mir aus Unterlagen zusammen "gebaut" 🙂 Da steckt kein Gedankengut meinerseits dahinter, das gebe ich mal zu 😉

    Ja, es ist richtig, in einer Textdatei soll gesucht werden.
    Den Suchstring wollte ich ja einlesen mit dem Unterprogramm EINL , Zeile 67
    ( Das stammt aus den Unterlagen meiner Professorin und ich sollte es verwenden und nichts neues schreiben. Ich habe hier lediglich die Einschränung auskommentiert, dass man nur Zahlen einlesen kann.)

    Es sollen alle Übereinstimmungen gesucht werden und am Ende soll das Ergebnis dann wieder abgespeichert werden. Dies hat sie mir leider auch erst später mitgeteilt 😉

    ja, als Debugger nutze ich den TASM, bzw. versuche es 🙄



  • gamefreak schrieb:

    Für mich beginnt der Zeiger bei 0 😃
    Hier ist auch mein großes Manko, mir fehlt das Verständnis für Adressen/Aufbau/Stack-,Segmentbereich.
    Die Initialisierungen hierzu habe ich mir aus Unterlagen zusammen "gebaut" 🙂 Da steckt kein Gedankengut meinerseits dahinter, das gebe ich mal zu 😉

    Hm, gar nicht gut. Vielleicht solltest du dir das erstmal kurz klar machen (ka, ob du entsprechende Unterlagen hast, sonst einfach mal eines der Anfaengertuts in den FAQ durchgehen), bevor du wild drauf losbastelst. So kompliziert ist das eigentlich ja nun nicht und damit die Muehe bestimmt wert.

    gamefreak schrieb:

    Ja, es ist richtig, in einer Textdatei soll gesucht werden.
    Den Suchstring wollte ich ja einlesen mit dem Unterprogramm EINL , Zeile 67
    ( Das stammt aus den Unterlagen meiner Professorin und ich sollte es verwenden und nichts neues schreiben. Ich habe hier lediglich die Einschränung auskommentiert, dass man nur Zahlen einlesen kann.)

    Ah, I see. 💡 Offenbar hast du diese Prozedur so geaendert, dass eingelesene Zeichen an einen Puffer bei bx geschrieben werden. Das funktioniert aber natuerlich nur, wenn du der Prozedur vor Aufruf einen gueltigen Pointer auf einen Puffer in bx uebergibst. 😉
    Sonst landet dein schoener String im Datennirvana, im Zweifelsfall sogar in deinem Programmcode und dann beschwert sich nachher wieder die NTVDM. 😃

    Vor dem Hintergrund solltest du das ganze Gebastel um die Variable "Suchtext" und die damit verbundenen Pointer so oder so nochmal von Grund auf ueberdenken.

    gamefreak schrieb:

    ja, als Debugger nutze ich den TASM, bzw. versuche es 🙄

    Also den TD...? Der Traced aber nicht in Interrupts und ist eigentlich auch so sehr schoen und uebersichtlich. Also muesste er beim Step oder Trace auf dem int 21h einfach zum naechsten Befehl springen. ... oder wo genau gibt es den Ausraster und was passiert dabei im Einzelnen?



  • Also den Zeiger von SI habe ich nun mit Push/Pop wieder auf den Anfang gesetzt.
    Aber was meinst du mit dem Pointer für das BX Register?



  • gamefreak schrieb:

    Also den Zeiger von SI habe ich nun mit Push/Pop wieder auf den Anfang gesetzt.

    Das klingt irgendwie bestenfalls nach einer viel zu komplizierten Loesung. Der "Anfang" des (Such-)Puffers, auf den si zurueckgesetzt werden muss, ist doch bekannt. Also kannst du einfach per mov dessen offset wieder nach si schreiben.

    gamefreak schrieb:

    Aber was meinst du mit dem Pointer für das BX Register?

    Ok... Frag dich erstmal selbst:
    Wo landet beim Aufrufen von "EINL" der eingegebene Text allgemein?
    Wo landet er im konkreten Fall deines Programms?
    Genauer: Wohin zeigt in diesem Fall BX und wo im Speicher landet dementsprechend in folgender Zeile AL?

    MOV     [BX],AL
    

    (scanups.asm; Zeile 48; Proc "EINL")

    Zumindest die Antwort auf die 1. Frage steht ja praktisch schon da: EINL schreibt alle eingelesenen Zeichen hintereinander in einen Puffer, auf den das Register BX beim Aufruf der Prozedur zeigt.
    Die Antwort auf die 2. (und 3.) Frage ist bei kurzer Betrachtung des Codes in SCANMAN.ASM bis Zeile 67, in der EINL aufgerufen wird, auch einfach zu beantworten: Bis dahin fasst du das Register BX ueberhaupt nicht an, folglich ist der Wert in BX undefiniert und damit auch die Stelle im Speicher, an der die Zeichen landen, die EINL einliest.

    Wenn man ueber den Stand der Dinge nun mal einen Augenblick sinniert, wird wohl klar, dass du BX vor aufrufen von EINL so initialisieren musst, dass das Register das Offset eines ausreichend langen Puffers im Speicher enthaelt.
    Bisher hast du jedoch auch noch keinen solchen Puffer in deinem Programm definiert. Einen Statischen, mit 0 initialisierten Puffer kannst du in TASM wie folgt reservieren:

    Suchtext db LEN1 dup (0)
    

    Das waere dann also der Puffer mit deinem Suchtext, die Laenge ist in diesem Fall LEN1 Bytes (also 10 Bytes). Die alte Definition von "Suchtext" in deinem Code musst du nat. entfernen.

    ...Ich hoffe das reicht als Anstoss, denn sehr viel deutlicher kann ich kaum noch werden, ohne dir dabei praktisch gleich den ganzen Code im Detail zu korrigieren. 😃



  • Ich habe es nun fertig 🙂
    Das Programm läuft endlich, der Algorithmus funktioniert, supi!!!

    Wollte mich daher noch mal bedanken - Nobuo T!



  • NP. Freut mich, wenn ich dir hilfreiche Hinweise geben konnte. 🙂


Anmelden zum Antworten