Dis-assemblieren einer Interrupt-Routine. Wie geht das?

  • Die 1.0 ist mit einem Exepacker gepackt, die 2.0 nicht - weil diese schon entpackt wurde (bspw. mit dem UNP was ich angehängt hatte).

    Vergleiche mal die entpackte 1.0 mit der ungepackten 2.0 - die sind sich sehr ähnlich.

    Ansonsten - viel Spaß mit den Fake-Versionen, für mich ist das Thema erledigt.

    "The biggest communication problem is we do not listen to understand. We listen to reply." - Stephen Covey


    Webseite und Blog ist immer noch - seit fast 20 Jahren - online.

  • Vielen Dank für die vielen Rückmeldungen, (wenn auch mittlerweile ziemlich off-topic)


    aber ich werde mal so mal so mißverstanden.


    Ich ging von der Annahme aus, daß im Forum des "Verein zum Erhalt klassischer Computer" die Glocken läuten wenn es heißt NCR DMV. :)


    Ich will noch einmal deutlich machen:


    * Der NCR DMV ist eine NICHT-IBM-kompatible Maschine aus 1982-84. Die letzte DOS Version dafür ist 2.11 und ist eine eigens an seine HW angepaßte Version. Dies betrifft insbesondere die VGA-Adressierung (keine Einblendung des VRAM ins RAM bei B000/b800), Tastaturhardware, Timer-Interupt etc. So gut wie keine Portnummer ist identisch mit einem IBM PC. Das gleiche gilt für diverse Systemwerte an bestimmten (IBM) Speicheradressen.


    Das bedeutet daß so gut wie keine Software, die sich auf IBM-HW verläßt, auf dem DMV funktioniert. Es funktioniert nur Software, die mit der Hardware über DOS-Aufrufe bzw BIOS interrupt Routinen kommuniziert. Es ist standardmäßig nicht einmal der VideoInterrupt 10H vorhanden (der läßt sich aber über ein eigens dafür geschriebenes tool "clone" nachinstallieren, der auch den 16H Tastaturinterrupt aufpeppt, um ALT Tasten zu simulieren.


    Alle Vorschläge, so gut sie auch gemeint waren, "moderne" debugger zu verwenden, die "Fenstertechnik" verwenden, jedenfalls direkt ins VRAM schreiben/lesen, funktionieren nicht.


    Ich will auch nochmals die Problemstellung darlegen, die auch der Hintergrund für meinen ersten thread war (dieser ist mein zweiter). In meinem ersten thread verfolgte ich die Lösung zur Beschleunigung der Wandlung der Bytes einer Datei mit dem Ansatz, daß mein Programm die Bytes direkt vom HD-Port einliest, ich also direkt an die Hardware rangehe. Das hat sich für mich als nicht durchführbar herausgestellt, da mir dazu die Programmierfähigkeiten fehlen. Die Dokumentation des DMV ist in dieser Hinsicht zwar sehr gut, aber das geht über meine Kenntnisse. Es hätte letztlich bedeutet einen block-device Treiber zu schreiben und das ist mir zu hoch.


    Und dann wurde mir klar, daß ich um den gewünschten Effekt zu erzielen, mich ohne weiteres doch dem bestens funktionierenden int21/3f bedienen kann. Der weiß bestens und zuverlässig, wie er sich die Bytes von der HD holt, darum möchte ich mich nicht kümmern müssen. Ich brauche ja nur eine kleine Änderung:

    - das Byte, welches der int21 gerade von der HD empfangen hat, GLEICH zu wandeln und erst dann ins RAM zu speichern.


    Ich brauche also eine Kopie des int21. Und die steht komplett und wunderbar funktionierend im Speicher nach dem Einschalten des Rechners.

    Diesen Speicherbereich muß ich also disassembliert auslesen. Dann den Teil finden der für Funktion 3F zuständig ist. Der kommt dann mit entsprechender Anpassung damit er eingebettet in mein TP3 funkioniert in mein Programm und wird in die intr-vektortabelle eingetragen.


    Was ist der gewünschte Effekt, warum dieser Aufwand?

    Bei der Optimierung von Software hinsichtlich Geschwindigkeit sind die größten Steigerungen erzielbar, wenn man eben die beste Kombination von Algorythmus und seiner Implementierung findet.

    Dazu gibt es bei der Implementation mehrere Mantras (Assemblerprogrammierer kennen sie):

    - vermeide Intr-Aufrufe

    - vermeide Speicherzugriffe, verwende die Register

    - don't jump!

    - vermeide mul/div (beim 8088, der V20 kann das 4x schneller)

    - je kürzer der code (Ausführungszeit der opcodes, wie auch Anzahl benötigter opcodebytes) desto besser


    Welchen Vorteil hat der Weg über die Verwendung einer eigenen Intr21/3f-Kopie?

    1. die vollständige Vermeidung sämtliche Bytes erneut vom RAM in die CPU einzulesen

    2. die vollständige Vermeidung sie alle wieder zurück ins RAM zu schreiben


    weil


    beim normalen herkömmlich Weg

    1. die datei vollständig ins RAM gelesen wird: HD -> CPU -> RAM

    2. danach alle bytes zur wandlung wieder in die cpu gelesen werden müssen RAM->CPU

    3. alle gewandelten bytes wieder zurück ins RAM geschrieben werden müssen. CPU->RAM


    Mein Ansatz benötigt nur Punkt 1.) weil die Wandlung sofort/direkt durchgeführt wird, dann, wenn die bytes zum esten Mal in der CPU vorliegen.


    Abgesehen von der Zeit, die es sowieso in beiden Fällen braucht, um die Bytes von der HD in die CPU zu lesen, sowie von der Zeit die es braucht um das einzelne Byte zu wandeln, vermeidet mein Ansatz zigtausendfachen RAM Zugriff und somit eine der zeitfressendsten Operationen nach dem HD Zugriff .


    Es wurde von einem Poster auch so verstanden, als würde ich vorhaben den int21 zu "patchen".

    Überhaupt nicht. Der int21 bleibt unberührt wie er original ist.


    Mein Programm braucht eine Kopie des int21 (letztlich nur soweit es sich um die Unterfunktion 3fh handelt).

    Mein Programm hängt meine INtr21-Kopie in den intr-vektor ein, der original-int21 bleibt erhalten. Meine int21-intr-prozedur prüft beim Aufruf ob im Register ah der Wert 3F steht, wenn ja, dann wird sie selbst aktiv, wenn nein, wird auf den original-int21 weitergeleitet. Bin ich fertig mit der Wandlung der Datei, wird wieder die original-int21prozedur in den vektor eingehängt.


    Damit wäre ich also zurück bei meiner eigentlichen Frage:

    Kann "debug.com" (ist am DMV vorhanden) anweisen (wie?) den Speicher an der Adresse 0:84H, um ab dort in einer bestimmten Länge (bis hin zum die intr-prozedur abschließenden IRET; wie findet man diese Adresse?) zu disassemblieren und dieses Assemblerlisting in eine Textdatei schreiben (wie?)?


    Hat jemand eine DOS-KIste einschaltbereit rumstehen und könnte das ausprobieren? Ein DMV ist dazu nicht nötig, die Technik dieses Vorgangs muß ja auf allen DOS PCs gleich sein.


    EDIT:

    Falsch! Die Adresse 0:84h ist jene Adresse, an der die Adresse steht (CS:Offse, 4 Bytes) an der die Int21 Routine im Speicher steht. Man muß also diese Adresswerte auslesen und dann debug anweisen, dort hinzugehen.

    Einmal editiert, zuletzt von DoPe ()

  • Natürlich kann man das auch mit DEBUG machen.


    Ja nach Version ist die Funktionsumfang unterschiedlich.

    Vielleicht läuft auch eine neuere MS-DOS 3.x DEBUG Version unter 2.11.

    Es gibt auch den SYMDEB von Microsoft, der etwas mehr kann, aber vermutlich nicht mehr unter 2.11 läuft.


    Bei meinem DEBUG liefert "?" eine Liste der Befehle, die er versteht.


    Bei meinem VirtualBox System mit DOS 3.3 zeigt der INT21h Vektor z.B. auf

    011C:109E


    DEBUG

    -u011C:109E

    liefert dann einen Block des disassemblierten Code bis zur Stelle 011C:10BC. Weitere "d" s liefern dann immer ein Blöckchen mehr.


    Man kann auch einen größeren Adressbereich angeben (eine "range" mit Segment:Oset1,Offset2):

    -u011C:109E,1200


    -u011C:109E,FFFF

    würde dann ein ganzes Segment ausgeben, was, umgeleitet in eine Textdatei vielleicht reichen würde und den interessanten Teil zu finden. allerdings werden auch FAR Routinen aufgerufen, die dann vermutlich nicht in diesem Bereich liegen, sondern nochmal separat ausgegeben werden müssten.


    DEBUG ist ziemlich archaisch, hat aber auch gute Seiten: eine schöne ist, dass man auch die Ausgaben auf eine Datei umleiten kann und dann, wenn man eingegrenzt hat den disassemblierten Code in eine Datei schreiben kann.

    So mache ich mir z.B. ROM dumps von BIOS oder anderen ROMs, die man nicht ausbauen kann.

    Mit den GUI Tools geht das nicht.


    In einer Batch Datei kann man z.B. schreiben


    ECHO u011C:109E,FFFF > INFILE

    ECHO q >> INFILE


    DEBUG < INFILE > OUTFILE

    DEL INFILE


    Dann sollte das automagisch geschehen.


    Im Systemcode wird aber nach Herzenslust ge-JMP-ed etc. sodass es recht aufwendig sein wird, das nachzuverfolgen. Es wird sich sicher kein einfacher geradliniger Pfad bis zu einem IRET ergeben.

    DEBUG hat auch Suchfunktionen, mit denen man z.B. nach dem Opcode für IRET suchen kann, hier vermutlich aber nicht hilfreich.

    Am besten erst mal den Code manuell ansehen und dann jeweils den JMPs und CALLs manuell folgen um zus sehen, wo z.B. auf 3F getestet wird. Dann könntest Du dort den Code mit einer Batch datei disassemblieren und mit einem Texteditor weiter untersuchen.


    Ich schätze, dass es durchaus ein paar Minütchen brauchen wird, den Code zu verstehen. Auch das Eichhörnchen hat es nicht leicht ;)

  • Vielen Dank Martin, ich bin glücklich!


    Wenn das so funktioniert damit ich vorerst mal an das disassembling komme, sieht das schon mal sehr gut aus

    Daß der Aufwand mehrere Eichhörnchen beschäftigt ist mir auch klar. "Minütchen" :)


    tofro

    Es ist natürlich möglich, daß im code des int21 gar nicht der befehl des Schreibens der Bytes in den Speicher stattfindet, sondern "außerhalb", in tieferen BIOS-Schichten. Wenn das so ist habe ich mit meinem Ansatz Pech gehabt. Ich glaube aber vorerst, daß das nicht so ist. Der Grund ist, daß das das Schichtenmodell untergraben würde: Anwendungsprogramm <-> Dos <-> Bios/Hardware. Man wird sehen.

  • SYMDEB war Teil der Microsoft Entwicklungsumgebung, anbei die letzte Version (4.0).

    Kennt nur 8086 und 80286, aber für den NCR wird das ja reichen.

    Das Programm läuft übrigens unter jeder DOS Version ab 2.0 (auch unter MS-DOS 7.1 von Windows 98).

  • Es ist natürlich möglich, daß im code des int21 gar nicht der befehl des Schreibens der Bytes in den Speicher stattfindet, sondern "außerhalb", in tieferen BIOS-Schichten. Wenn das so ist habe ich mit meinem Ansatz Pech gehabt. Ich glaube aber vorerst, daß das nicht so ist. Der Grund ist, daß das das Schichtenmodell untergraben würde: Anwendungsprogramm <-> Dos <-> Bios/Hardware. Man wird sehen.

    Wie bereits zuvor erwähnt, kann das überhaupt nur funktionieren, wenn der Transfer vom Disketten-/Festplattencontroller in den RAM nicht per DMA erfolgt, was aber eigentlich die effizientere und bei PCs übliche Variante ist.

    Grund: Was auf seinem Weg in den RAM niemals in CPU-Registern landet, kann man auch nicht „vor dem Zurückschreiben“ bearbeiten.


    Hier wäre also die Frage, ob du die Zielarchitektur gut genug kennst, um das ausschließen zu können. Ansonsten verbrätst du eventuell viel Zeit für nichts.

  • Benedikt,


    das sehe ich auch so.

    Ich glaube aber das ist hier nicht der Fall, weil der alte Knabe DMV (hat einen 8237 DMA chip) bzw. der Festplattencontroller zwar DMA beherrscht (lt. Datenblatt), aber die echte Verwendung der DMA Mode (0,1,....) Übertragung statt der PIO Modes deutlich später erst Einzug in optimierten Chipsets/Bios Einzug hielt. Mein 486-er aus 92/93 (ebenfalls NCR), also 10 Jahre jünger, tut dies zB unter DOS immer noch nicht, erst wenn man entsprechende Treiber nachlädt, zB fürs CDrom Laufwerk bzw. unter Win95.

  • Peter z80.eu


    Hat der debugger "oberfläche", also arbeitet mit ein/ausblendbaren "fenstern"?

    Welcher ? SYMDEB ? Nein, ist DEBUG ziemlich ähnlich, kann aber ein bisschen mehr.

    Es gibt übrigens auch eine neuere Version für (alte) Windows-Versionen, die aber definitiv auch unter DOS läuft.

    Siehe Anhang. Würde ich aber für den NCR nicht nehmen.

    Dateien

    "The biggest communication problem is we do not listen to understand. We listen to reply." - Stephen Covey


    Webseite und Blog ist immer noch - seit fast 20 Jahren - online.