progamm läuft nur im debugger???
-
habe ein merkwürdiges problem:
hab ein keines programm geschrieben(dos,realmode) das eine datei liesst (max. 500byte) und den inhalt dann in den bootsektor einer diskette schreibt. außerdem testet das programm vorher die dateigrosse und bricht mit einer fehlermeldung ab, wenn das programm >510 byte ist. das programm funktioniert allerdings nicht wenn ich es so starte sondern NUR wenn ich es im debugger (td) schrittweise ablaufen lasse(habs mit einem hexeditor nachgeprüft). also erkennt er die korrekte dateigroesse nur im debug-modus richtig???. ich ermittle die dateigroesse über funktion 42h, int21h (0 bytes vom dateiende positionieren). hab einen p3,500- ist der etwa zu schnell für dos-aufrufe?
was zum geier ist das für ein müll???????????tenim
-
Jo, das passiert ab und an. Da muss irgendwo in deinem Code noch ein Fehler sein... Ein P3, 500 ist auf keinen Fall zu schnell fuer DOS-Aufrufe, denn auf meinem AMD 1Ghz laeuft DOS auch noch
Eine weitere moegliche Fehlerquelle koennte das OS sein, in dem du dein Programm laufen laesst...
Poste doch mal code und OS und dann mal schaun
-
also mein os ist win98 im dos-modus. emm386 ist deaktiviert.
der code:;erstellt einen bootsektor mit loader (boot.com)
;die dateigroesse des loaders "boot.com" muss <=510 Byte sein !;============================================================================
DATA SEGMENT BYTE PRIVATEloader_pfad DB 'd:\tasm\projekte\os\boot\loader\boot.com$'
dateihandle DW ?
dateigroesse DW ?
puffer DB 512 DUP(?)fehler_1 DB 'boot.com ist zu gross (max. 510 Byte)$'
DATA ENDS
;============================================================================;============================================================================
STAPEL SEGMENT BYTE STACKDW 100 DUP(?)
STAPEL ENDS
;============================================================================;============================================================================
CODE SEGMENT BYTE PRIVATE
ASSUME CS:CODE, DS:DATA, SS:STAPELstart:
mov dx,DATA
mov ds,dx;---zuerst den bootloader im bootsektor installieren--------------------
mov ah,3Dh
mov dx,OFFSET loader_pfad
mov al,0
int 21h ;datei mit loader (boot.com) oeffnen
mov dateihandle,axmov ah,42h
mov al,2
mov bx,dateihandle
int 21h ;dateigroesse ermitteln
mov dateigroesse,axcmp dx,0
ja zu_gross
cmp ax,510
ja zu_gross
jmp ist_okzu_gross:
mov ah,9
mov dx,OFFSET fehler_1
int 21h ;boot.com zu gross, fehlermeldung ausgeben
jmp endeist_ok:
mov ah,42h
mov al,0
mov bx,dateihandle
int 21h ;dateizeiger wieder auf anfang stellenmov bx,OFFSET puffer
mov [bx],WORD PTR 2
mov dx,bx
add dx,2 ;den wert 2 zum pufferoffset addierenmov ah,3Fh
mov bx,dateihandle
mov cx,dateigroesse
int 21h ;boot.com in einlesenmov ah,3Eh
mov bx,dateihandle
int 21h ;datei schliessenmov al,0
mov cx,1
mov dx,0
mov bx,OFFSET puffer
int 26h ;ersten sektor der diskette schreiben
add sp,2 ;stackpointer korrigieren;-----------------------------------------------------------------------
ende:
mov ah,4Ch
int 21h ;programm beendenCODE ENDS
;============================================================================END start
tenim
[ Dieser Beitrag wurde am 22.06.2002 um 16:19 Uhr von tenim editiert. ]
-
Problem scheint folgendes zu sein:
Die Datei kann nicht geoeffnet werden, da der String mit dem Dateinamen mit 0 terminiert werden muss und nicht mit "$"
Warum das im Debugger ueberhaupt funktioniert ist mir nicht so ganz klar
Da ich das jetzt aber schonmal zerlegt habe, hab ich da gleich noch ein paar andere Verbesserungsvorschlaege:
Du solltest in .exe-Dateien uninitialisierte Daten (Variablen mit dem Wert "?")immer ganz ans Ende stellen...Also:
Code segment
...
Code besteht aus initialisierten Daten
...
Code endsData segment
...
InitialisierteDaten db 'BLA'
...
UninitialisierteDaten db ?
...
Data endsAb hier sollten keine initialisierten Daten mehr folgen.
Stapel segment stack
UninitialisierterStack db ... dup (?)
Stapel endsSo stehen in der .exe wirklich nur die initialisierten Daten, waehrend bei deinem Code in der .exe-Datei alle uninitialisierten Variablen in 0-Bytes umgewandelt wurden...
Konkret: Deine exe wird 1,35KB gross und die abgespeckte Version nur 674BytesWeiter:
Was sollen diese Zeilen bringen?:
mov bx,OFFSET puffer
mov [bx],WORD PTR 2
Die Ausfuehrung des Codes im Bootsektor beginnt am Anfang des Bootsectors. Genau da hin schreibt dein Programm: 02 00
Das ist der Opcode fuer "add al,[bx+si]" was soll das bringen?
-
ich dachte die ersten 2 byte im bootsektor geben die zieladresse eines near-jumps an den das bios ausführt um zur adresse des bootloaders zu kommen. also hab ich ab offset 0 den wert 2 eingetragen und mein programm ab offset 2 hinterlegt. dachte die sprungadresse dieses jumps bezeichnet den offset ab 0.
-
Ja, ich glaube da hast du was verwechselt.
In den meisten Bootloadern steht an Addresse 0 (Bootloader wird uebrigens nach 0000:7C00 geladen) ein short jump zum code start. Aber eigentlich koennte an addr 0 alle moeglichen OpCodes stehen.
-
hab übrigens den fehler beseitigt und die zeichenkette mit ",0"
terminiert, und neu übersetzt. aber das programm läuft trotzdem nicht, wieder der alte fehler . aber dein tipp mit dem uninitialisiertem speicher ist toll
-
Noch ein winziger Verbesserungsvorschlag:
Nimm stattja zu_gross jmp ist_ok
lieber
jna ist_ok
-
noch mal zu dem trick mit den uninitialisierten variablen. wie funktioniert das denn genau? heisst das, daß der linker uninitialisierte variablen nicht mit in die .exe datei aufnimmt (wenn diese zum schluss kommen)??
und wie reserviert er diese variablen dann?
-
Ja, er nimmt dann diese Variablen nicht mit in die .exe-Datei auf. Im .exe-Header steht jedoch die Menge Speicher, die das Programm benoetigt...
Ich habe uebrigens den Fehler gefunden.
Hier dann noch eine ueberarbeitete und erfolgreich geteste Version des Codes (Obacht:Ich habe den Pfad+Dateinamen der Inputdatei veraendert);erstellt einen bootsektor mit loader (boot.com)
;die dateigroesse des loaders "boot.com" muss <=510 Byte sein !;============================================================================
CODE SEGMENT BYTE PRIVATE
ASSUME CS:CODE, DS:DATA, SS:STAPELstart:
mov ax,DATA
mov ds,ax;---zuerst den bootloader im bootsektor installieren--------------------
mov ax,3D00h
mov dx,OFFSET loader_pfad
int 21h ;datei mit loader (boot.com) oeffnen
jnc DateiOffen
mov ah,9
mov dx,OFFSET fehler_0
int 21h
jmp ende
DateiOffen:
mov dateihandle,axmov bx,ax
mov ax,4202h
xor dx,dx
xor cx,cx
int 21h ;dateigroesse ermitteln
mov dateigroesse,axor dx,dx
jnz zu_grosscmp ax,512
jbe ist_okzu_gross:
mov ah,9
mov dx,OFFSET fehler_1
int 21h ;boot.com zu gross, fehlermeldung ausgeben
jmp endeist_ok:
mov ax,4200h
int 21h ;dateizeiger wieder auf anfang stellenmov ah,3Fh
mov cx,dateigroesse
mov dx,offset puffer
int 21h ;boot.com in einlesenmov ah,3Eh
int 21h ;datei schliessenmov al,0
mov cx,1
mov dx,0
mov bx,OFFSET puffer
int 26h ;ersten sektor der diskette schreiben
add sp,2 ;stackpointer korrigieren;-----------------------------------------------------------------------
ende:
mov ah,4Ch
int 21h ;programm beendenCODE ENDS
;============================================================================;============================================================================
DATA SEGMENT BYTE PRIVATEloader_pfad DB 'E:\TASM\TEST.COM',00h
fehler_0 DB 'konnte test.com nicht oeffnen.'
dateihandle DW ?
dateigroesse DW ?
puffer DB 512 DUP(?)DATA ENDS
;============================================================================;============================================================================
STAPEL SEGMENT BYTE STACKDW 100 DUP(?)
STAPEL ENDS
;============================================================================END start
-
ich weiss jetzt, woran es lag: ich hatte cx & dx vor ermitteln der dateigroesse nicht auf 0 gesetzt und dadurch hat er als offset vom dateiende nicht 0 angenommen und sich so mit der dateigroesse verrechnt.
[ Dieser Beitrag wurde am 22.06.2002 um 19:05 Uhr von tenim editiert. ]
[ Dieser Beitrag wurde am 22.06.2002 um 19:06 Uhr von tenim editiert. ]
[ Dieser Beitrag wurde am 22.06.2002 um 19:07 Uhr von tenim editiert. ]