Autor Thema: Komischer Fehler bei MOV  (Gelesen 6994 mal)

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« am: 02. May 2006, 18:49 »
Hallo

Bei mir entsteht ein komischer Fehler bei diesem Code. Woran kann das liegen?mov [ecx],eax
Der Fehler sieht in Bochs so aus:BxError: instruction with op1=0xff
mod was c0, nnn was 7, rm was 7
WARNING: Encountered an unknown instruction (signalling illegal instruction)

Und auch so geht es nicht:mov ebx,ecx
mov [ebx],eax


Gruss
Noooooooooooos

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 02. May 2006, 19:22 »
Die beiden Zeilen an und für sich sind nicht das Problem. Irgendwo läuft der Programmfluss in einen Codebereich wo mindestens ein 0xFF steht.

Den Wert von eip an dieser Stelle kannst du herausbekommen, indem du das logprefix mit folgender Zeile in deiner bochsrc änderst/einfügst:

logprefix: %t-%e-@%i
(auf das %i kommt es an)

dann müsste bei dir im bochs.log irgendwas wie:
00004427615-i-@00007c04-[CPU0 ] BxError: ...
stehen. Das 00007c04 ist dann der Wert von ip/eip relativ zu cs. (Also _nicht_ die lineare Adresse.)

HTH
Dieser Text wird unter jedem Beitrag angezeigt.

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 02. May 2006, 19:49 »
Und wenn ich nun die Position hab, wie kann ich denn diese im Quelltexte finden????

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 02. May 2006, 19:56 »
Also erstmal kannst du ja abschätzen, ob sich diese Position innerhalb deines Programms befindet, oder ob der Programmfluss irgendwo anders hingelaufen ist.

Wenn sich die Position in deinem Code befindet, kannst die Position im Quelltext durch Disassemblieren oder durch die Ausgabe von .map-Files beim Linken oder beim Assemblieren (z.B. nasm foo.asm -l foo.lst). Oder du machst das im Debugger von bochs, indem du z.b. einen Breakpoint (am besten mehrere im 1-Byte-Abstand, da du genau eine Grenze zwischen 2 Instruktionen treffen musst) kurz vor die Adresse setzt.

Alternativ kannst du im Bochsdebugger mit s 4427605 kurz vor die Stelle springen. Dann brauchst du eip gar nicht. Mit s kannst du dann weitersteppen und dir einen Überblick über den Code verschaffen. 4427605 sollte dabei der Timestamp des Fehlers minus ~10 sein. Das ganze geht nur, wenn du keinen zeitabhängigen Code (Sleepfunktionen, etc.) hast.
Dieser Text wird unter jedem Beitrag angezeigt.

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 02. May 2006, 20:28 »
Also ich hab jetzt mal das mit dem .map gemacht. Doch aus dem Ergebnis werd ich nicht ganz so schlau. Wenn ich nun vor einer Code-Zeile das folgende sehe: 292 000001E2 8903
Wie kann ich jetzt da die Adresse herauslesen?

Gruss
Noooooooooos

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 02. May 2006, 21:00 »
292 ist die Zeile nach irgendeinem internen Durchnummerierungssystem von NASM, 000001E2 die Adresse (relativ zum Anfang der Ausgabe) und 8903 der Opcode.
Dieser Text wird unter jedem Beitrag angezeigt.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #6 am: 02. May 2006, 21:08 »
8903 = mov [ebx],eax
In the Future everyone will need OS-64!!!

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 03. May 2006, 20:37 »
An der von Bochs angegebenen Codestelle steht aber kein 0xFF. Das sieht man ja schön im Opcode.

Die Zeile die den Fehler auslöst, sendet das EOI des Timer-Interrupts.

Allerdings habe ich 10 Bytes weiter vorn folgende Codezeile. Die Einsen werden dann ja in 0xFF verwandelt:and ebx,11111111111111111111111111111110b


EDIT:
Wiso liegt eigentlich der Fehler ganz wo anders als ich es mit dem jmp$ ausgetestet hab????


Hilft das irgendwie weiter????
Nooooooooooooooos

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 07. May 2006, 19:12 »
Also der Fehler entsteht tatsächlich beim AND Befehl.
Aber was ist denn jetzt fehlerhaft daran? Was soll ich denn jetzt anders machen?

Und warum ist der Fehler an einem komplett anderen Ort als per jmp $ ermittelt?

Gruss
Noooooooooooooos

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 21. May 2006, 13:21 »
Also nachdem ich jetzt eine Weile nichts mehr getan habe, hab ich mich wieder mit dem Fehler beschäftigt.

1.) Ist eine Instruktion in einem Task, die auf den Kernel-Speicher zugreift nicht auskommentier wird der Fehler ausgelöst.
2.) Im Timer-Interrupt kann man den Fehler vermeiden, wenn man den Code vor einer Instruktion, die auf den Kernel-Speicher zugreif anhält.

3.) Laut Bochs-Debugger entsteht der Fehler aber erst etwas später im Code des Timer-Interrupts:

Erstens taucht da plötzlich eine Instruction mit dem Opcode 0x0 (add [eax],al) an der Adresse 0x89a2 auf. Da entsteht ja laut Bochs auch der Fehler. Zudem wird diese 0000-Stelle auch nicht angegeben, wenn ich mir kurz vorher den Speicher an dieser Stelle ausgeben lasse.
Doch etwas später kommt an der selben Adresse eine ganz normale Instruction auf.

Ich hab keine Ahnung mehr, was da falsch sein könnte und wo ich den Fehler angehen könnte. Möglich wäre, dass über die vorher genannten Speicherzugriffe etwas am Code verändert wird.....


Gruss
Nooooooooos

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 21. May 2006, 20:55 »
Es ist nicht die selbe Adresse. Die eingekreisten Zahlen sind der Wert von eip. Die tatsächliche Adresse ist hingegen davor in eckigen Klammern. (0x79a2 und 0x89a2)

Mehr kann ich leider zu dem Problem auch nicht sagen.
Dieser Text wird unter jedem Beitrag angezeigt.

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 21. May 2006, 21:04 »
Das wird ja immer noch merkwürdiger????
Wiso sollte mein Speichermanagment das Segment meines Kernels (0x8000) mit der physischen Adresse 0x7000 mappen?????

Ist schon mal jemandem etwas ähnliches passiert????
Gruss
Nooooooooooooos

 

Einloggen