home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / sharew / mdebug / mdebug22.exe / BSP.PRT < prev    next >
Encoding:
Text File  |  1992-06-05  |  48.7 KB  |  1,681 lines

  1.     ───────────────────────────────────────────────────────────────────
  2.  
  3.  
  4.  
  5.  
  6.  
  7.                 ┌────────────────────────────────────────┐
  8.                 │                                        │█
  9.                 │             MDEBUG V2.00               │█
  10.                 │                                        │█
  11.                 │ Highperformance Debugging Tool für PCs │█
  12.                 │                                        │█
  13.                 └────────────────────────────────────────┘█
  14.                  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  15.  
  16.  
  17.  
  18.  
  19.  
  20.        ╔════════════════════════════════════════════════════════╗
  21.        ╟────────────────────────────────────────────────────────╢█
  22.        ║                                                        ║█
  23.        ║          Beispiele für die Nutzung von MDEBUG          ║█
  24.        ║                                                        ║█
  25.        ╚════════════════════════════════════════════════════════╝█
  26.         ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.     ───────────────────────────────────────────────────────────────────
  56.              Copyright (c) 1988 - 1992 by Bernd Schemmer
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.     Inhalt                                                 Seite
  66.     ────────────────────────────────────────────────────────────
  67.  
  68.  
  69.     Einleitung ...........................................     1
  70.     Verwendete Syntax in den Beispielen ..................     2
  71.     Allgemeine Hinweise zur Benutzung ....................     2
  72.     Tips für die Benutzung von MDEBUG ....................     2
  73.     Beispiele für die Interpreter-Befehle ................     4
  74.     Normalisieren einer Adresse ..........................     4
  75.     Rechnen mit Zahlen in Doppelwortgröße ................     4
  76.     Testen der Bits des Flag-Registers ...................     6
  77.     Setzen eines bestimmten Bits eines Registers .........     6
  78.     Löschen eines bestimmten Bits  eines Registers .......     6
  79.     Invertieren eines bestimmten Bits eines Registers ....     6
  80.     Simulation von nicht implementierten 
  81.     Maschinenbefehlen ....................................     7
  82.     Arbeiten mit Booleschen Werten .......................     9
  83.     Ausführen von BIOS-Interrupts ........................    10
  84.     Ermittlung des Tastaturcodes einer Taste .............    10
  85.     Zeichen an den Drucker senden ........................    10
  86.     Zeichenkette an den Drucker senden ...................    10
  87.     Ausführen von Funktionen des DOS-Interrupt 21h .......    11
  88.     Belegung eines Extra-Speicherbereichs für Daten über 
  89.     DOS ..................................................    11
  90.     Freigeben von Speicherblöcken ........................    11
  91.     Ermitteln von Disketten/Platten-Werten ...............    11
  92.     Ermitteln der freien Diskkapazität ...................    12
  93.     Ermitteln der maximalen Diskkapazität ................    12
  94.     Einrichten eines neuen Directorys ....................    13
  95.     Löschen eines Directorys .............................    13
  96.     Wechseln des aktuellen Directorys ....................    13
  97.     Löschen einer Datei ..................................    13
  98.     Testen, ob eine Datei existiert ......................    13
  99.     DOS-Speicherstrukturen anschauen oder ändern .........    14
  100.     Durchlaufen der DPB-Kette (DOS 3.xx) .................    14
  101.     Benutzung der SDL ....................................    15
  102.     Ermitteln der Anzahl der Einträge in der SDL .........    17
  103.     Manipulieren der SDL .................................    17
  104.     Durchlaufen der Kette der Puffer (nur DOS 3.xx) ......    19
  105.     Ermitteln  der  Anzahl  vorhandener  Puffer ..........    19
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.     ────────────────────────────────────────────────────────────────────────────────
  120.     Inhalts-Verzeichnis                                                     I    1
  121.  
  122.  
  123.  
  124.  
  125.     Inhalt                                                 Seite
  126.     ────────────────────────────────────────────────────────────
  127.  
  128.  
  129.     Ermitteln des Wertes von LASTDRIVE ...................    20
  130.     Durchlaufen der Kette der Device-Treiber .............    21
  131.     Suchen des Device-Treibers für 'LPT1' ................    21
  132.     Ermitteln aller freien Speicherblöcke ................    22
  133.     Durchlaufen der MCB-Kette ............................    22
  134.     Benutzung von MDEBUG für das Debuggen von eigenen 
  135.     Programmen ...........................................    25
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.     ────────────────────────────────────────────────────────────────────────────────
  180.     Inhalts-Verzeichnis                                                     I    2
  181.  
  182.  
  183.  
  184.     Einleitung
  185.     ──────────
  186.  
  187.     Diese Datei  enthält Hinweise und Beispiele für  die Benutzung  von
  188.     MDEBUG.  Hauptsächlich  wird  hier auf  die  Programmiersprache des
  189.     Interpreters eingegangen.
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.     ────────────────────────────────────────────────────────────────────────────────
  240.                                                                         Seite    1
  241.  
  242.  
  243.  
  244.     Verwendete Syntax in den Beispielen
  245.     ───────────────────────────────────
  246.  
  247.     ALLE in den Beispielen  angegebenen  Werte  ohne Angabe des Formats
  248.     sind hexadezimale Werte.
  249.  
  250.     Alle Beispiele gehen davon aus, daß  die  Monitor-Start-Adresse aus
  251.     den Registern  SE und OF ermittelt wird.
  252.     Das Zeichen '@' leitet Kommentare ein.
  253.  
  254.     Hinweis:
  255.  
  256.     Bei  der Entwicklung  von Befehlsketten  die über  den H-  oder HN-
  257.     Befehl mehrfach ausgeführt  werden sollen, ist  es sinnvoll den  H-
  258.     Befehl  zuerst durch einen  W-Befehl zu  ersetzen und erst nach dem
  259.     Test den H- bzw. HN-Befehl einzusetzen.
  260.  
  261.  
  262.     Allgemeine Hinweise zur Benutzung
  263.     ─────────────────────────────────
  264.  
  265.     MDEBUG wurde nach der Philosophie
  266.  
  267.          "Alles was machbar ist, ist erlaubt."
  268.  
  269.     geschrieben. Der Anwender ist also für die Folgen  seines  Handelns
  270.     voll verantwortlich! MDEBUG selbst überprüft jeweils  nur teilweise
  271.     die Syntax der Befehle.  Mensch sollte sich also vor jeder Befehls-
  272.     Ausführung genau überlegen, was passieren kann!
  273.     Zu beachten ist auch, daß alle Speicher-Operationen mit Wort-Größen
  274.     im INTEL-Format (= Vertauschte Bytes) durchgeführt werden.
  275.  
  276.     Die Vorzüge  der Philosophie  des  Programmes  überwiegen  aber die
  277.     Nachteile bei falscher Benutzung, denke ich.
  278.  
  279.  
  280.     Tips für die Benutzung von MDEBUG
  281.     ─────────────────────────────────
  282.  
  283.     Fast alle Befehle sind mit allen Registern möglich. Es  können also
  284.     auch Befehle, die  der  Prozessor  normalerweise  nicht  beherrscht
  285.     (z.B. das Rechnen mit Segment-Registern) ausgeführt werden.
  286.  
  287.     Zuweisungen der  Form MOV [mem1],[mem2] sind ebenfalls möglich.
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.     ────────────────────────────────────────────────────────────────────────────────
  300.                                                                         Seite    2
  301.  
  302.  
  303.  
  304.     Einzelne  Werte  können  auch  in  den  Hilfsregistern  gespeichert
  305.     werden;  kleinere  Texte  oder  mehrere  Werte können im nicht mehr
  306.     benötigtem PSP von MDEBUG zwischen CS:000h und CS:0100h gespeichert
  307.     werden. (siehe auch 'Programm-Interna')
  308.  
  309.     Das PSP von  MDEBUG (oder jeder beliebige andere Speicherbereich)
  310.     kann auch zum Zwischenspeichern von Befehlen genutzt werden.
  311.  
  312.     Durch die Parameter '&name' und '*name' können im  PSP gespeicherte
  313.     Befehlszeilen oder Daten  auch in einer Datei gesichert werden bzw.
  314.     aus einer Datei restauriert werden.
  315.  
  316.     Über  die '#26'-  und  '#27'-Befehle  kann  der  Eingabepuffer  des
  317.     Interpreters  auch zum Editieren und Verändern eines  Strings (z.B.
  318.     aus dem Environment) benutzt werden.
  319.  
  320.     Über den '#27'H-Befehl können auch  mehr Befehle  als in eine Zeile
  321.     passen  auf einmal  bearbeitet  werden. Der W-Befehl, der H-Befehl,
  322.     der '#27'H-Befehl, der  ¿-Befehl  und  der ¿H-Befehl ermöglichen es
  323.     zudem kleinere 'Routinen' auszuführen.
  324.  
  325.     Mit  dem Programm  MDMKHLP.COM können  eigene  Hilfstextdateien für
  326.     die Online-Hilfe von MDEBUG erstellt werden.
  327.     (z.B.  mit  einem  Hilfstext  über  die  Datenstrukturen  eines  zu
  328.      untersuchenden  Programmes, oder aus einem Teil der .LST-Datei des
  329.      Assemblers)
  330.  
  331.     Alle  Maschinen-Befehle  können über den B- bzw. G-Befehl jederzeit
  332.     ausgeführt werden.  Der jeweilige Maschinen-Code kann z.B aus einer
  333.     .LST-Datei eines Assemblers ermittelt werden.
  334.  
  335.     Sinnvollerweise  schreibt mensch den Code für  den G-Befehl  vorher
  336.     mit  einen  normalen Assembler, übersetzt  diesen und  benutzt  das
  337.     Listing später zur Eingabe. Bzw. erstellt eine Datei der Maschinen-
  338.     codes als B-Befehl  die  dann  über  den  Parameter  '&name' in das
  339.     das PSP von MDEBUG eingelesen werden kann.
  340.  
  341.     Kleinere Routinen können auch in  übersetzter  Form  über den Para-
  342.     meter '&name' mit dem  Schalter ',N'  in das PSP eingelesen werden.
  343.     Dort  können  sie  über  den  G-Befehl  ausgeführt  werden.  Die so
  344.     geladenen Routinen dürfen aber nicht mit einem RET-Befehl enden!
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.     ────────────────────────────────────────────────────────────────────────────────
  360.                                                                         Seite    3
  361.  
  362.  
  363.  
  364.     Beispiele für die Interpreter-Befehle
  365.     ─────────────────────────────────────
  366.  
  367.  
  368.     Normalisieren einer Adresse
  369.  
  370.     Normalisieren  der Adresse in den Registern SE:OF. Nach der  Norma-
  371.     lisierung  hat  das Register OF nur noch einen Wert zwischen 0h und
  372.     0Fh.
  373.  
  374.          ADD SE,(OF » 4) ^ & OF,0F
  375.  
  376.  
  377.     Rechnen mit Zahlen in Doppelwortgröße
  378.     (hier in den Registern DX:AX)
  379.  
  380.  
  381.     ■ Addition
  382.  
  383.          ADD AX,2000 ^ ADD DX,FL%0      @ DX:AX <- DX:AX + 2000
  384.          oder
  385.          ADD AX,2000 ^ adc DX,0
  386.  
  387.       Falls nach der ersten Addition das Carryflag gesetzt ist, ist ein
  388.       Übertrag  vorhanden der auf das Highword (Register DX) aufaddiert
  389.       werden muß (zweiter ADD-Befehl bzw. adc-Befehl).
  390.  
  391.  
  392.     ■ Subtraktion
  393.  
  394.          SUB AX,2000 ^ SUB DX,FL%0      @ DX:AX <- DX:AX - 2000
  395.          oder
  396.          SUB AX,2000 ^ sbb DX,0
  397.  
  398.       Falls  nach der  ersten Subtraktion  das  Carryflag  gesetzt ist,
  399.       wurde noch eine  Stelle geborgt,  die von Highword  (Register DX)
  400.       abezogen werden  muß (zweiter SUB-Befehl bzw. sbb-Befehl)
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.     ────────────────────────────────────────────────────────────────────────────────
  420.                                                                         Seite    4
  421.  
  422.  
  423.  
  424.     ■ Multiplikationen bzw. Divisionen  durch eine  Zweierpotenz können
  425.       folgendermaßen programmiert werden:
  426.  
  427.       Im Beispiel wird in CL jeweils die Zweierpotenz durch die geteilt
  428.       teilt bzw. multipliziert wird gespeichert.
  429.  
  430.          MOV CL,3                       @ Multiplikant = 2^3 = 8
  431.          < DX ^ < AX ^ ADD DX,FL%0 ^ - CL ^ ¿ CL ^ H
  432.                                         @ DX:AX <- DX:AX * 8
  433.  
  434.          MOV CL,2                       @ Divisor = 2^2 = 4
  435.          > AX ^ > DX ^ ADD AX,(FL%0 * 8000) ^ - CL ^ ¿ CL ^ H
  436.                                         @ DX:AX <- DX:AX / 4
  437.  
  438.  
  439.     ■ Multiplikationen bzw. Divisionen durch  eine andere Größe  müssen
  440.       über  den  B-Befehl  durchgeführt werden, wobei in den Beispielen
  441.       davon ausgegangen wird, daß  diese Größe im Register CX steht.
  442.  
  443.       Achtung:
  444.  
  445.       Hier darf auf keinen Fall durch 0 geteilt werden! Bei verketteten
  446.       Befehlen sollte dies durch den Befehl '¿ CX' vor dem Divisionsbe-
  447.       fehl (mit dem Register durch das geteilt wird) verhindert werden.
  448.  
  449.       ■ Division
  450.  
  451.          ¿ CX ^ B F7,F1    @ AX <- (DX:AX DIV CX) und
  452.                            @ DX <- (DX:AX MOD CX)
  453.  
  454.  
  455.       ■ Multiplikation
  456.  
  457.          B F7,E1    @ DX:AX <- AX * CX
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.     ────────────────────────────────────────────────────────────────────────────────
  480.                                                                         Seite    5
  481.  
  482.  
  483.  
  484.     Testen der Bits des Flag-Registers
  485.  
  486.     ┌──────┬────────────────┬─────────────────────────────────────────┐
  487.     │      │                │             Test auf                    │
  488.     │ Bit  │ Flag           │ gesetztes Flag    nicht gesetztes Flag  │
  489.     ╞══════╪════════════════╪═════════════════╤═══════════════════════╡
  490.     │ 00h  │ Carry          │     ¿ =(FL%0)   │     ¿ (FL%0)          │
  491.     │ 01h  │ -              │                 │                       │
  492.     │ 02h  │ Parity (Even)  │     ¿ =(FL%2)   │     ¿ (FL%2)          │
  493.     │ 03h  │ -              │                 │                       │
  494.     │ 04h  │ Auxiliary      │     ¿ =(FL%4)   │     ¿ (FL%4)          │
  495.     │ 05h  │ -              │                 │                       │
  496.     │ 06h  │ Zero           │     ¿ =(FL%6)   │     ¿ (FL%6)          │
  497.     │ 07h  │ Sign           │     ¿ =(FL%7)   │     ¿ (FL%7)          │
  498.     │ 08h  │ Trap           │     ¿ =(FL%8)   │     ¿ (FL%8)          │
  499.     │ 09h  │ Interrupt      │     ¿ =(FL%9)   │     ¿ (FL%9)          │
  500.     │ 0Ah  │ Direction      │     ¿ =(FL%0A)  │     ¿ (FL%0A)         │
  501.     │ 0Bh  │ Overflow       │     ¿ =(FL%0B)  │     ¿ (FL%0B)         │
  502.     │ 0Ch  │ -              │                 │                       │
  503.     │ 0Dh  │ -              │                 │                       │
  504.     │ 0Eh  │ -              │                 │                       │
  505.     │ 0Fh  │ -              │                 │                       │
  506.     └──────┴────────────────┴─────────────────┴───────────────────────┘
  507.  
  508.     Da die unbenutzen  Bits im Flag-Register vom Prozessor immer wieder
  509.     auf eins gesetzt werden, können sie  leider nicht für eigene Zwecke
  510.     benutzt werden. Es kann aber ein  Hilfsregister oder eine Speicher-
  511.     stelle  als weiteres Flagregister benutzt werden, da der Test eines
  512.     Bits natürlich  auch mit diesen möglich ist.
  513.  
  514.  
  515.     Setzen eines bestimmten Bits eines Registers
  516.  
  517.          | AX,1«4                       @ Setze Bit 4 von AX
  518.  
  519.  
  520.     Löschen eines bestimmten Bits  eines Registers
  521.  
  522.          & AX,(1«3)!-1                  @ Lösche Bit 3 von AX
  523.  
  524.  
  525.     Invertieren eines bestimmten Bits eines Registers
  526.  
  527.          ! AX,1«7                       @ Invertiere Bit 7 von AX
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.     ────────────────────────────────────────────────────────────────────────────────
  540.                                                                         Seite    6
  541.  
  542.  
  543.  
  544.     Simulation von nicht implementierten Maschinenbefehlen
  545.  
  546.     ■ Simulation von REPNE SCASB
  547.  
  548.       Damit AL durch die Subtraktion  nicht  verändert wird,  wird hier
  549.       als  erster  Operand  ein Ausdruck, dessen Wert gleich dem Inhalt
  550.       von AL ist,  verwendet.  Die Subtraktion  verändert daher nur die
  551.       Flags  (Benutzung des Pseudo-Registers). Da der erste Operand ein
  552.       Ausdruck ist (= Wort!), muß bei der Speicheradresse explizit  das
  553.       Byte-Format  angegeben  werden.  ES:DI  zeigt nach der Ausführung
  554.       entweder auf  das gefundene Zeichen oder  auf das  erste  Zeichen
  555.       hinter  dem String. (je nach Cursor-Position)
  556.  
  557.          S AL+0,ES:*DI ^ ¿ 1-FL%6      ^ + DI   ^ - CX  ^ ¿ CX ^ H
  558.          ─────────────   ────────        ────     ─────   ────   ─
  559.          Vergleich      Wert gefunden?  Zeiger   Zähler  CX=0? Schleife
  560.                         (ZF = 1)        erhöhen  korrig.       zuende?
  561.  
  562.     ■ Simulation von REPE SCASW
  563.  
  564.          S AX+0,ES:DI ^ ¿ FL%6 ^ ADD DI,2 ^ - CX ^ ¿ CX ^ H
  565.  
  566.     ■ Simulation des Befehls CMP AX,BX
  567.  
  568.       Damit  AX  nicht  verändert  wird,  wird hier wieder  das Pseudo-
  569.       Register benutzt, d.h. nach dem  Befehl  sind wie  beim Original-
  570.       Befehl nur die Flags verändert.
  571.  
  572.          S AX+0,BX
  573.  
  574.     ■ Simulation der Befehle SAHF und LAHF
  575.  
  576.       Diese Befehle können  nicht direkt  simuliert  werden, allerdings
  577.       kann der Wert des Flag-Registers durch einen einfachen MOV-Befehl
  578.       in ein anderes Register gesichert bzw. aus einem anderen Register
  579.       restauriert werden.
  580.  
  581.          MOV AX,FL             @ Save Flags in AX   (SAHF)
  582.          MOV FL,AX             @ Load Flags from AX (LAHF)
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.     ────────────────────────────────────────────────────────────────────────────────
  600.                                                                         Seite    7
  601.  
  602.  
  603.  
  604.     ■ Simulation des Befehls LDS SI,BX
  605.  
  606.          MOV SI,DS:[BX] ^ MOV DS,DS:[BX+2]
  607.  
  608.     ■ Simulation des Befehls ROL AX,1
  609.  
  610.          < AX ^ | AX,FL%0
  611.  
  612.     ■ Simulation des Befehls ROR AX,1
  613.  
  614.          > AX ^ | AX,FL%0*8000
  615.  
  616.     ■ Simulation des Befehls XCHG AX,BX
  617.  
  618.          ! AX,BX ^ ! BX,AX ^ ! AX,BX
  619.  
  620.     ■ Simulation des Befehls XLATB
  621.  
  622.          MOV AL,DS:[BX+AL]
  623.  
  624.     ■ Simulation der FOR-Schleife 'FOR CX=4 TO 9 BY 1 DO { AL = AL+5 }'
  625.  
  626.          Vorbereitung:
  627.  
  628.          MOV CX,4              @ Anfangswert ins Zählregister
  629.  
  630.          Ausführung:
  631.  
  632.          Im  Beispiel  wird nur AX jeweils um 5 erhöht. Der Endwert für
  633.          die Schleife ist hier 9, die Schleife soll  6 mal (9 - 4 + 1 )
  634.          durchlaufen werden.
  635.  
  636.          ADD AL,5 ^ + CX ^ ¿ CX<(9+1) ^ H
  637.                            ──────────
  638.                            Ausführen solange CX kleiner als der
  639.                            Endwert+1 ist
  640.  
  641.     ■ Simulation der WHILE-Schleife 'WHILE (AL <> 0) DO { INC AX }'
  642.  
  643.          ¿ AL¬0 ^ + AX ^ H
  644.  
  645.     ■ Simulation der UNTIL-Schleife 'REPEAT { INC AX } UNTIL (AL = 0)'
  646.  
  647.          + AX ^ ¿ AL¬0 ^ H
  648.          oder
  649.          + AX ^ ¿H AL=0
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.     ────────────────────────────────────────────────────────────────────────────────
  660.                                                                         Seite    8
  661.  
  662.  
  663.  
  664.     Arbeiten mit Booleschen Werten
  665.  
  666.     Die  Operatoren  '=', '<', '>',  '¬' und '%' ergeben  alle entweder
  667.     1 (= TRUE)  oder 0 (= FALSE).  Da  der ¿-  und der  ¿H-Befehl einen
  668.     Booleschen Wert testen, können hiermit auch logische  Verknüpfungen
  669.     programmiert werden.  Es sollte  allerdings darauf geachtet werden,
  670.     daß keinerlei  Operator-Prioritäten vorhanden sind. (Alle Beispiele
  671.     ohne  explizite Angabe  gehen von  vorzeichenlosen Werten aus.)
  672.  
  673.          ¿ AX=BX                    @ Bearbeitung fortsetzen,
  674.                                     @ falls AX = BX
  675.  
  676.          ¿ ((AX < BX) | (AX > BX))  @ Bearbeitung fortsetzen,
  677.                                     @ falls AX <> BX
  678.                                     @ (Simulation des Operators '¬')
  679.  
  680.          ¿ ((AX < BX) | (AX = BX))  @ '<='-Operator
  681.  
  682.          ¿ ( (AX < 8) & (AX > 1) )  @ Bearbeitung fortsetzen, falls AX
  683.                                     @ im Intervall 2 bis 7 (incl.) liegt
  684.  
  685.          ¿ ( (AX < 2) | (AX > 8) )  @ Bearbeitung fortsetzen, falls AX
  686.                                     @ nicht im Intervall 2 bis 8
  687.                                     @ (incl.) liegt
  688.  
  689.          ¿ ( AX%0 = 0 )             @ Bearbeitung fortsetzen, falls der
  690.                                     @ Wert aus AX gerade ist,  d.h. das
  691.                                     @ 0-te Bit ist nicht gesetzt
  692.  
  693.          ¿ ( AX%0F = 0)             @ Bearbeitung fortsetzen, falls der
  694.                                     @ vorzeichenbehaftete  Wert  aus AX
  695.                                     @ größer oder gleich 0 ist, d.h. das
  696.                                     @ 15-te Bit ist nicht gesetzt
  697.  
  698.          ¿ ( (DX > CX) | ( (AX > BX) & (DX = CX) ) )
  699.                                     @ Bearbeitung fortsetzen, falls das
  700.                                     @ Doppelwort in DX:AX größer als
  701.                                     @ das Doppelwort in CX:BX ist
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.     ────────────────────────────────────────────────────────────────────────────────
  720.                                                                         Seite    9
  721.  
  722.  
  723.  
  724.     Ausführen von BIOS-Interrupts
  725.  
  726.     Über den  INT-Befehl kann  jederzeit jeder beliebige BIOS-Interrupt
  727.     aufgerufen werden. Beachtet werden muß aber, daß verschiedene BIOS-
  728.     Routinen (z.B. des Interrupt 13h) NICHT reentrant sind!
  729.  
  730.  
  731.     Ermittlung des Tastaturcodes einer Taste
  732.  
  733.          MOV AH,0 ^ INT 16     @ Funktion 0 des INT 16h ->> Taste lesen
  734.                                @ entsprechende Taste drücken
  735.  
  736.     AX enthält nun den vom Interrupt 16h gelieferten Tastatur-Code
  737.  
  738.  
  739.     Zeichen an den Drucker senden
  740.  
  741.          MOV AL,'<zeichen>'    @ AL mit dem zu sendenden Zeichen laden
  742.          MOV AH,0              @ AH mit der Funktions-Nummer laden
  743.          MOV DX,0              @ DX mit der Drucker-Nummer laden
  744.                                @ (lpt1 = 0, lpt2 = 1, usw.)
  745.          INT 17                @ Drucker-Interrupt ausführen
  746.                                @ AH enthält nun den Druckerstatus
  747.  
  748.  
  749.     Zeichenkette an den Drucker senden
  750.  
  751.          Vorbereitung:
  752.  
  753.          In  einen freien  Speicherbereich die  gewünschte Zeichenkette
  754.          abgeschlossen mit einem Endemarker (hier  ein Null-Byte)  ein-
  755.          tragen und DS:BX auf die Adresse der Kette setzen.
  756.          (Ausgabe auf LPT1)
  757.  
  758.          Ausführung:
  759.  
  760.          M AL,DS:[BX] ^ ¿ AL¬0   ^ + BX ^ M AH,0 ^ M DX,0 ^ I 17 ^ H
  761.          ────────────   ──────     ──────────────────────   ────
  762.          akt. Zeichen    Ketten-    Zeiger korrigieren und   Zeichen
  763.          nach AL         Ende ?     Register laden           drucken
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.     ────────────────────────────────────────────────────────────────────────────────
  780.                                                                         Seite   10
  781.  
  782.  
  783.  
  784.     Ausführen von Funktionen des DOS-Interrupt 21h
  785.  
  786.     Prinzipiell können aus MDEBUG heraus auch alle  Funktionen des DOS-
  787.     Interrupts 21h ausgeführt  werden.  Da  die meisten  Funktionen des
  788.     Interrupt  21h  NICHT  reentrant sind,  sollten  Funktionen  dieses
  789.     Interrupts aber nur  ausgeführt  werden,  falls das (DOS-)Busy-Flag
  790.     von MDEBUG auf 0 steht.  Ansonsten  ist ein  Systemabsturz nach dem
  791.     Ende des Aufrufs von MDEBUG sehr wahrscheinlich!
  792.  
  793.  
  794.     Belegung eines Extra-Speicherbereichs für Daten über DOS
  795.  
  796.          MOV BX,0010 ^ MOV AH,48 ^ INT 21
  797.                                @ BX = Größe  des Speicherbereichs in
  798.                                @ Paragraphen á 16 Byte; die Gesamtgröße
  799.                                @ des zu belegenden Speichers  ist  also
  800.                                @ 16*10h (= 16 dez) = 256 Byte (dez.)
  801.  
  802.     Falls das Carry-Flag gelöscht ist, enthält  AX nun das Segment  des
  803.     belegten  Speicherbereichs,  andernfalls enthält BX  die Größe  des
  804.     größten  freien  Speicherbereichs in  Paragraphen. Die  Adresse aus
  805.     AX muß  im  Erfolgsfall (z.B.) in einem  Hilfsregister  gespeichert
  806.     werden, da dieser Speicherbereich vor dem Entfernen  von MDEBUG aus
  807.     dem Speicher wieder  freigegeben werden  sollte. Nach diesem Befehl
  808.     muß der Besitzer im  neuen MCB (Segment = AX-1, Besitzer = Wort  am
  809.     Offset 1) korrigiert werden (z.B. PSP von MDEBUG eintragen).
  810.  
  811.  
  812.     Freigeben von Speicherblöcken
  813.  
  814.          MOV ES,freizugebendes_Segment ^ MOV AH,49 ^ INT 21
  815.  
  816.  
  817.     Ermitteln von Disketten/Platten-Werten
  818.  
  819.     Hinweis:
  820.  
  821.     Falls die Werte einer Diskette ermittelt werden sollen, sollte auch
  822.     eine  Diskette  im geschlossenen Diskettenlaufwerk sein (sonst wird
  823.     der Interrupt 24h aufgerufen)!
  824.                  
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.     ────────────────────────────────────────────────────────────────────────────────
  840.                                                                         Seite   11
  841.  
  842.  
  843.  
  844.     Ermitteln der freien Diskkapazität
  845.  
  846.          MOV AH,36 ^ MOV DL,0 ^ INT 21
  847.                              @ DL = Laufwerknummer, 0 = akt. LW,
  848.                              @ 1 = Lw. A, 2 = Lw B, etc.
  849.  
  850.     Falls AX = 0FFFF wurde  eine unbekannte  Laufwerksnummer angegeben.
  851.     Sonst kann die freie Diskkapazität ermittelt werden durch:
  852.  
  853.          MOV DX,0
  854.          B F7,E1             @ MUL CX
  855.          B F7,E3             @ MUL BX
  856.                              @ DX:AX enthält die freie Kapazität
  857.                              @ in Bytes (als Doppelwort)
  858.  
  859.  
  860.     Ermitteln der maximalen Diskkapazität
  861.  
  862.          MOV AH,36 ^ MOV DL,0 ^ INT 21
  863.                              @ DL =Laufwerknummer, 0 = akt. LW,
  864.                              @ 1 = Lw. A, 2 = Lw B, etc.
  865.  
  866.     Falls AX = 0FFFF wurde eine unbekannte Laufwerksnummer angegegeben.
  867.     Sonst kann die Diskkapazität ermittelt werden durch:
  868.  
  869.          MOV BX,DX           @ Anzahl Cluster nach BX
  870.          B F7,E1             @ MUL CX -> DX:AX = Bytes/Cluster
  871.          B F7,E3             @ MUL BX -> DX:AX enthält nun die max.
  872.                              @ Kapazität in Bytes (als Doppelwort)
  873.  
  874.     Sinnvollerweise  teilt mensch den erhaltenen Wert durch 1024 um den
  875.     Wert in KB zu erhalten und  somit  in einem  Register darstellen zu
  876.     können:
  877.  
  878.          MOV BX,#1024 ^ B F7,F3   @ DIV BX (=1024)
  879.          MOV R8,AX                @ R8 = max. Diskkapazität in KB
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893.  
  894.  
  895.  
  896.  
  897.  
  898.  
  899.     ────────────────────────────────────────────────────────────────────────────────
  900.                                                                         Seite   12
  901.  
  902.  
  903.  
  904.     Falls  die im Kommandotreiber MDBSPDRV.COM  implementierten Befehle
  905.     zur  Datei- und Directorybehandlung nicht angewendet werden können,
  906.     können diese folgendermaßen programmiert werden:
  907.  
  908.     Für alle folgenden Beispiele auf dieser Seite gilt:
  909.  
  910.     Vor der Ausführung der Befehle muß der Name des Directorys bzw. der
  911.     Datei abgeschlossen mit einem Null-Byte in einem freien Speicherbe-
  912.     reich eingetragen werden.Die Adresse des Namens muß in die Register
  913.     DS (Segment) und DX (Offset) eingetragen werden.
  914.  
  915.     Falls  nach der  Ausführung das  Carry-Flag  gelöscht  ist, war die
  916.     Aktion erfolgreich.
  917.     Andernfalls trat  ein Fehler  auf und  das Register  AX enthält die
  918.     DOS-Fehlernummer.
  919.  
  920.  
  921.     Einrichten eines neuen Directorys
  922.  
  923.          MOV AH,39 ^ INT 21
  924.  
  925.  
  926.     Löschen eines Directorys
  927.  
  928.          MOV AH,3A ^ INT 021
  929.  
  930.  
  931.     Wechseln des aktuellen Directorys
  932.  
  933.          MOV AH,3B ^ INT 021
  934.  
  935.  
  936.     Löschen einer Datei
  937.  
  938.          MOV AH,41 ^ INT 021
  939.  
  940.  
  941.     Testen, ob eine Datei existiert
  942.  
  943.          MOV AX,4300 ^ INT 021          @ CF = 0 ->> CX = Dateiattribut
  944.  
  945.  
  946.  
  947.  
  948.  
  949.  
  950.  
  951.  
  952.  
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959.     ────────────────────────────────────────────────────────────────────────────────
  960.                                                                         Seite   13
  961.  
  962.  
  963.  
  964.     DOS-Speicherstrukturen anschauen oder ändern
  965.  
  966.  
  967.     Durchlaufen der DPB-Kette (DOS 3.xx)
  968.  
  969.     Im Interpeter durch den Befehl
  970.  
  971.          D M3
  972.  
  973.     die Monitor-Start-Adresse  ändern. Der Monitor zeigt nun den ersten
  974.     DPB an. Da das Verkettungs-Feld der DPBs nicht am Offset 0h sondern
  975.     beim  Offset  18h  beginnt, wird  für das Durchlaufen der  DPBs ein
  976.     verketteter Befehl oder ein Ausdruck benötigt:
  977.  
  978.          ADD OF,18 ^ P OF
  979.     oder:
  980.          P [OF+18]
  981.  
  982.     Durch Betätigen von  <CTRL-RETURN>  kann  jetzt  im Interpreter die
  983.     Kette der DPBs durchlaufen werden.
  984.  
  985.     Unter Zuhilfename des W-Befehls lautet die Befehlszeile:
  986.  
  987.          ADD OF,18 ^ P OF ^ W
  988.     oder:
  989.          P [OF+18] ^ MOV BX,[OF+18] ^ ¿ (BX+1)  ^ W
  990.  
  991.     Durch die Eingabe von <Backspace> auf dem W-Befehl wird jeweils der
  992.     nächste DPB angezeigt.
  993.  
  994.     Hinweis:
  995.     Der  letzte DPB hat als Offset im  Verkettungsfeld  beim Offset 18h
  996.     den Wert 0FFFFh stehen. Deshalb beendet (0FFFFh = -1 -> -1 + 1 = 0)
  997.     die Ausführung.
  998.  
  999.  
  1000.  
  1001.  
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.  
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.     ────────────────────────────────────────────────────────────────────────────────
  1020.                                                                         Seite   14
  1021.  
  1022.  
  1023.  
  1024.     Benutzung der SDL
  1025.  
  1026.     ■ Ermittlung der  Datei bzw.  des Geräts dem ein Handle  zugeordnet
  1027.       ist über die SDL.
  1028.  
  1029.     Zuerst muß über die Befehle
  1030.  
  1031.          MOV AH,062 ^ I 21 ^ MOV SE,BX ^ MOV OF,0
  1032.  
  1033.     das aktuelle PSP im Monitor angezeigt werden. Da diese Funktion des
  1034.     Interrupts 21h reentrant ist, kann sie jederzeit ausgeführt werden.
  1035.     Danach wird durch die Befehle
  1036.  
  1037.          MOV CX,[OF+32] ^ P OF+34
  1038.  
  1039.     das Register CX mit  der maximal  möglichen  Anzahl Handles geladen
  1040.     und die akt. lokale  Handle-Tabelle im Monitor angezeigt. Falls der
  1041.     Wert  im Register CX kleiner  als das zu  untersuchende Handle ist,
  1042.     ist dieses nicht bekannt (d.h. für den akt. Prozess unbelegt).
  1043.     Ansonsten kann jetzt über den Befehl
  1044.  
  1045.          MOV BL,[OF+HandleNummer] ^ MOV BH,0
  1046.  
  1047.     das gewünschte Handle in das DOS-interne Handle konvertiert werden.
  1048.     Falls dabei für BX der Wert  00FFh  herauskommt, ist das angegebene
  1049.     Handle für den akt. Prozess noch nicht belegt.
  1050.     Andernfalls kann danach über den Befehl
  1051.  
  1052.          D M4 ^ MOV CX,[OF+04]
  1053.  
  1054.     die erste  Teilliste der SDL  im Monitor  angezeigt und  CX mit der
  1055.     Anzahl  Elemente in dieser Teilliste geladen werden.
  1056.     Jetzt  muß  überprüft  werden, ob  der Wert in CX  größer  als  das
  1057.     ermittelte  DOS-interne  Handle ist oder nicht. Falls dies der Fall
  1058.     ist, muß  zuerst über den Befehl
  1059.  
  1060.          P OF
  1061.  
  1062.     die zweite Teilliste der SDL im Monitor angzeigt werden. (Ansonsten
  1063.     kann dieser Befehl entfallen)
  1064.  
  1065.     Durch den Befehl
  1066.  
  1067.          ADD OF,6
  1068.  
  1069.     muß nun der Header der Teilliste der SDL überlesen werden und durch
  1070.     den Befehl
  1071.  
  1072.          ADD OF,(BX*#53)+20         @ DOS 3.xx
  1073.     bzw.
  1074.          ADD OF,(BX*#59)+20         @ DOS 4.+
  1075.  
  1076.     wird im Monitor beim Offset SE:OF der Name des zugeordneten Gerätes
  1077.     bzw. der zugeordneten Datei angezeigt.
  1078.  
  1079.     ────────────────────────────────────────────────────────────────────────────────
  1080.                                                                         Seite   15
  1081.  
  1082.  
  1083.  
  1084.     Graphisch dargestellt sieht das Ganze dann folgendermaßen aus:
  1085.  
  1086.            Interrupt 21h mit AH = 62h  -> Ausgabe: BX = Zeiger auf akt.
  1087.                                                    ║    PSP (Segment=BX,
  1088.         ╔══════════════════════════════════════════╝         Offset=0)
  1089.         ║                    ┌──  Länge der lokalen Handle-Tabelle
  1090.         ║                    │           ┌── Adresse der lokalen Handle-
  1091.         ║                    │           │                       Tabelle
  1092.         ║                Offset 32h  Offset 34h
  1093.         ║  ┌────┬────┬─────┬──────┬───────────┬───┐
  1094.         ╚═>│ CD │ 20 │ ... │ mmmm │  seg:off  │...│ akt. PSP des Programms
  1095.            └────┴────┴─────┴──────┴───────────┴───┘
  1096.                                         ║
  1097.      ╔══════════════════════════════════╝
  1098.      ║┌─ Rückgabe der Routinen zur Dateiverarbeitung (Eröffnung) mit Handles
  1099.      ║│             ┌──> Handle für Routinen zur Dateiverarbeitung mit Handles
  1100.      ║│             │
  1101.      ║└> Index: >───┘  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F 10 11 12 13
  1102.      ║ Inhalt z.B.:  ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
  1103.      ╚══════════════>│01│01│01│00│02│-1│-1│-1│-1│-1│-1│-1│-1│-1│-1│-1│-1│-1│-1│-1│
  1104.                   ┌─<└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
  1105.                   │   ^  ^  ^  ^  ^  ^ ...
  1106.                   │   │  │  │  │  │  └ Ab hier folgen die Handle
  1107.                   │   │  │  │  │  │    für Benutzer-Definierte Dateien
  1108.                   │   └──┴──┴──┴──┴─ vordefinierte Handles
  1109.     ┌─────────────┘
  1110.     └────> Der Eintrag des Tabellen-Elementes mit dem gewünschten Index
  1111.            wird nun als Index für die System-Datei-Liste (SDL) genommen
  1112.            in  deren  Einträgen  jeweils beim  Offset 20h der  Name des
  1113.            Gerätes bzw. der Datei steht.
  1114.  
  1115.          1. Teilliste der SDL
  1116.        ┌───────────────────────────────────────────────────────────┐
  1117.        │ Zeiger auf die 2. Teilliste des SDL                       │══╗
  1118.        ├───────────────────────────────────────────────────────────┤  ║
  1119.        │ Anzahl Einträge in dieser Teilliste (normalerweise 5)     │  ║
  1120.        ├───────────────────────────────────────────────────────────┤  ║
  1121.        │ 1. Eintrag in dieser Teilliste      (= 0. Eintrag gesamt) │  ║
  1122.        │ ...                                                       │  ║
  1123.        │ Letzter Eintrag in dieser Teilliste (= 4. Eintrag gesamt) │  ║
  1124.        └───────────────────────────────────────────────────────────┘  ║
  1125.     ╔═════════════════════════════════════════════════════════════════╝
  1126.     ║    2. Teilliste der SDL
  1127.     ║  ┌───────────────────────────────────────────────────────────┐
  1128.     ╚═>│ Zeiger auf die nächste Teilliste, normalerweise FFFF:FFFF │
  1129.        ├───────────────────────────────────────────────────────────┤
  1130.        │ Anzahl Einträge in dieser Teilliste (Anz.= FILES - 5)     │
  1131.        ├───────────────────────────────────────────────────────────┤
  1132.        │ 1. Eintrag in dieser Teilliste      (= 5. Eintrag gesamt) │
  1133.        │ ...                                                       │
  1134.        │ Letzter Eintrag in dieser Teilliste (= n. Eintrag gesamt  │
  1135.        │                                      mit n = FILES - 1)   │
  1136.        └───────────────────────────────────────────────────────────┘
  1137.  
  1138.  
  1139.     ────────────────────────────────────────────────────────────────────────────────
  1140.                                                                         Seite   16
  1141.  
  1142.  
  1143.  
  1144.     Ermitteln der Anzahl der Einträge in der SDL
  1145.  
  1146.     (= FILES aus der Datei CONFIG.SYS,  Vorr.:  keine individuelle Ver-
  1147.     längerung der SDL in Kraft und FILES nicht im EMS installiert)
  1148.  
  1149.          MOV CX,0 ^ D M4 ^ A CX,[OF+4] ^ P OF ^ ADD CX,[OF+4]
  1150.  
  1151.     In CX steht nun die gewünschte Anzahl.
  1152.  
  1153.  
  1154.     Manipulieren der SDL
  1155.  
  1156.     Beispiel:
  1157.  
  1158.     Nach mehreren Debugger-Sitzungen, bei  denen jeweils Dateien eröff-
  1159.     net, aber  nicht wieder  geschlossen wurden,  tritt der  DOS-Fehler
  1160.     'Kein freies Handle mehr' auf,  d.h. die SDL  enthält  keine freien
  1161.     Einträge mehr.
  1162.  
  1163.     In diesem Fall kann von versierten(!) Programmierern  mit Hilfe von
  1164.     MDEBUG die interne System-Datei-Liste korrigiert werden:
  1165.  
  1166.     Zuerst muß hierfür im Interpreter durch den Befehl
  1167.  
  1168.          D M4
  1169.  
  1170.     die erste Teilliste der SDL im Monitor angezeigt werden.
  1171.  
  1172.     Da die nun angezeigte erste Teilliste der SDL im Normalfall nur die
  1173.     Einträge für  die Systemdateien/geräte (CON, LPT1, COM1, usw.) ent-
  1174.     hält, sollten in dieser Liste keine Änderungen vorgenommen werden.
  1175.  
  1176.     Der Befehl
  1177.  
  1178.          P OF
  1179.  
  1180.     führt deshalb zur Anzeige der zweiten Teilliste der SDL.
  1181.  
  1182.     Beim Offset OF+4 steht die Anzahl der Einträge in dieser Liste (als
  1183.     Wortgröße), die  mensch sich mit dem Befehl
  1184.  
  1185.          MOV R7,[OF+4]
  1186.  
  1187.     im Register R7 merken sollte.
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.     ────────────────────────────────────────────────────────────────────────────────
  1200.                                                                         Seite   17
  1201.  
  1202.  
  1203.  
  1204.     Hinweis:
  1205.  
  1206.     Falls beim Offset OF ein Doppelwort mit Offset und Segment ungleich
  1207.     0FFFFh steht, ist dies ein Zeiger auf eine weitere Teilliste.
  1208.  
  1209.     Nun kann mit dem Befehl
  1210.  
  1211.          ADD OF,6
  1212.  
  1213.     der nicht  mehr benötigte  Header  der  Teilliste überlesen werden.
  1214.     SE:OF  zeigt nun auf den 1. Eintrag in der  Teilliste der SDL. Beim
  1215.     Offset OF+20h steht der Name der Datei (bzw. des Gerätes) der (dem)
  1216.     dieser Eintrag zugeordnet ist.
  1217.  
  1218.     Der Wert am  Offset OF bestimmt, ob der Eintrag belegt (wert <> 0 =
  1219.     Anzahl der Verweise auf diesen Eintrag) oder frei (wert=0) ist. Der
  1220.     Wert am  Offset OF+02h  bestimmt, ob  die Datei zum Lesen (wert=0),
  1221.     zum  Schreiben  (wert=1)  oder  zum  Lesen  und  Schreiben (wert=2)
  1222.     geöffnet ist.
  1223.  
  1224.     Falls  der Eintrag  nicht  mehr  benötigt  wird, kann er  durch den
  1225.     Befehl
  1226.  
  1227.          MOV [OF],0
  1228.  
  1229.     gelöscht werden.
  1230.  
  1231.     Falls mehrere Einträge gelöscht werden sollen, bietet sich folgende
  1232.     Befehlskette an:
  1233.  
  1234.          ADD OF,35 ^ - R7 ^ W ^ MOV [OF],0 ^ ¿ R7 ^ H   @ DOS 3.xx
  1235.     bzw.
  1236.          ADD OF,3B ^ - R7 ^ W ^ MOV [OF],0 ^ ¿ R7 ^ H   @ DOS 4+
  1237.  
  1238.     Zuerst  wird  der Monitor  auf  die Adresse  des  nächsten Eintrags
  1239.     gesetzt und dann über den W-Befehl angezeigt. Die Eingabe von <ESC>
  1240.     bricht  die weitere Ausführung  der Befehlszeile  nun ab,  d.h. der
  1241.     Eintrag wird NICHT gelöscht; die Eingabe von <Backspace> verhindert
  1242.     ebenfalls  die Löschung  des  Eintrags  allerdings wird sofort  der
  1243.     nächste Eintrag angezeigt. Jede andere Taste führt zur Löschung des
  1244.     Eintrages und zur Anzeige des  nächsten  Eintrages. Die SDL kann so
  1245.     bequem  durchlaufen werden, wobei das Hilfsregister  R7 als  Zähler
  1246.     dient.  Der  Befehl '¿ R7'  beendet  dann die  Ausführung  nach den
  1247.     letzten Eintrag.
  1248.     Allerdings  können  hier  durch das  Schließen von Dateien, die zum
  1249.     Schreiben auf  waren,  oder  bei geladener  Netzwerksoftware Daten-
  1250.     verluste auftreten!
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.     ────────────────────────────────────────────────────────────────────────────────
  1260.                                                                         Seite   18
  1261.  
  1262.  
  1263.  
  1264.     Durchlaufen der Kette der Puffer (nur DOS 3.xx)
  1265.  
  1266.     Im Interpreter durch den Befehl
  1267.  
  1268.          D M7
  1269.  
  1270.     den Monitor auf die Adresse des ersten Puffers in der Kette setzen.
  1271.     Danach den Interpreter durch die Taste <ESC>  verlassen. Der Cursor
  1272.     steht  jetzt  auf dem Verkettungs-Feld des ersten Puffers,  so  daß
  1273.     die Kette der  Puffer durch  Eingabe von <P> im Monitor durchlaufen
  1274.     werden kann.
  1275.  
  1276.     Im Interpreter lautet der Befehl zur Anzeige  des  jeweils nächsten
  1277.     Puffers:
  1278.  
  1279.          P OF
  1280.  
  1281.     Unter  Zuhilfenahme des W- und ¿-Befehls kann folgende Befehlskette
  1282.     benutzt werden:
  1283.  
  1284.          P OF ^ MOV BX,[OF] ^ ¿ (BX+1) ^ W
  1285.  
  1286.     Durch die Eingabe von <Backspace> auf den W-Befehl wird jeweils der
  1287.     nächste Puffer  angezeigt. Der ¿-Befehl beendet die Ausführung nach
  1288.     dem letzten Puffer, da der letzte Puffer als Offset im Verkettungs-
  1289.     Feld -1 (= 0FFFFh) stehen hat.
  1290.  
  1291.  
  1292.     Ermitteln  der  Anzahl  vorhandener  Puffer
  1293.     (= BUFFERS aus der Datei CONFIG.SYS, nur bei DOS 3.xx)
  1294.  
  1295.          Vorbereitung:
  1296.  
  1297.          D M7 ^ MOV CX,0
  1298.  
  1299.          Ausführung:
  1300.  
  1301.          + CX ^ MOV AX,[OF] ^ ¿ AX+1 ^ P OF ^ H
  1302.  
  1303.     In CX steht nun die Anzahl vorhandener Puffer.
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.     ────────────────────────────────────────────────────────────────────────────────
  1320.                                                                         Seite   19
  1321.  
  1322.  
  1323.  
  1324.     ■ Testen, ob der Sektor  003 des  Laufwerks D: in einem Puffer vor-
  1325.       liegt (nur DOS 3.xx)
  1326.  
  1327.          Vorbereitung:
  1328.          (BX = Sektornummer,
  1329.           CL = Laufwerknummer, wobei A = 0, B = 1, C = 2 usw.):
  1330.  
  1331.          D M7 ^ MOV BX,0003 ^ MOV CL,'D'-'A'
  1332.  
  1333.          Ausführung:
  1334.          (damit  die  Befehlszeile  auf einmal  eingegeben werden kann,
  1335.           sind alle unnötigen Trennzeichen weggelassen worden)
  1336.  
  1337.          M AX,[OF^¿ AX+1^M AX,[OF+6^M CH [OF+4^¿ =((AX=BX)&(CL=CH))^P OF^H
  1338.  
  1339.     SE:OF zeigt nach dem Ende der Befehlszeile entweder auf den betref-
  1340.     fenden oder den  letzten  Puffer. Der  Cursor  steht im ersten Fall
  1341.     hinter  dem  zweiten  ¿-Befehl, im  zweiten Fall  hinter dem ersten
  1342.     ¿-Befehl.
  1343.  
  1344.  
  1345.     Ermitteln des Wertes von LASTDRIVE
  1346.  
  1347.          D M0 ^ MOV 8L,[OF+29] ^ ADD 8L,'@'
  1348.  
  1349.     oder (ohne Veränderung des Monitors, DOS-Busy-Flag = 0!):
  1350.  
  1351.          MOV AH,52 ^ I 21 ^ MOV 8L,ES:[BX+21] ^ ADD 8L,'@'
  1352.  
  1353.     Das  Register  8L (= Lowbyte von R8) enthält nun den Buchstaben des
  1354.     letzten möglichen logischen Laufwerkes.
  1355.  
  1356.  
  1357.     ■ Ermitteln des physikalischen Pfades des logischen Laufwerkes O:
  1358.       (Vorr.: Der bei  LASTDRIVE in der  Datei  CONFIG.SYS angegebene
  1359.               Wert ist größer oder gleich 'O'!)
  1360.  
  1361.          D M8 ^ ADD OF,('O'-'A')*51      @ DOS 3.xx
  1362.       bzw.
  1363.          D M8 ^ ADD OF,('O'-'A')*58      @ DOS 4.+
  1364.  
  1365.     SE:OF  zeigt nun auf den physikalischen Pfad für das logische Lauf-
  1366.     werk 'O:'. Falls im Byte  mit dem Offset  OF+44 das Bit Nr. 6 nicht
  1367.     gesetzt ist, ist das Laufwerk nicht bekannt.
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.     ────────────────────────────────────────────────────────────────────────────────
  1380.                                                                         Seite   20
  1381.  
  1382.  
  1383.  
  1384.     Durchlaufen der Kette der Device-Treiber
  1385.  
  1386.          Vorbereitung:
  1387.  
  1388.          D M0 ^ A OF,2A ^ M CX,0    @ -> SE:OF zeigt auf das NUL-Device
  1389.                                     @ -> CX = Zähler für die Devices
  1390.  
  1391.          Ausführung:
  1392.  
  1393.          + CX ^ P OF ^ MOV AX,[OF] ^ ¿ AX+1 ^ W
  1394.  
  1395.     Nach Eingabe von <Backspace> auf den W-Befehl wird jeweils der Kopf
  1396.     jedes Treibers angezeigt.
  1397.     Nach  Beenden  der Befehlskette durch den ¿-Befehl zeigt  SE:OF auf
  1398.     den letzten Treiber und CX enthält die Anzahl der geladenen Treiber.
  1399.  
  1400.  
  1401.     Suchen des Device-Treibers für 'LPT1'
  1402.  
  1403.          Vorbereitung:
  1404.  
  1405.          D M0 ^ ADD OF,2A ^ MOV DX,'PL' ^ MOV CX,'1T'
  1406.                                   @ -> SE:OF zeigt auf das NUL-Device
  1407.                                   @ -> DX:CX = Suchstring
  1408.  
  1409.          Ausführung
  1410.          (der  erste  Treiber ist  immer das  NUL-Device  und kann also
  1411.           überlesen werden. Damit die  Befehlszeile auf einmal eingege-
  1412.           ben werden kann  sind alle unnötigen Trennzeichen weggelassen
  1413.           worden)
  1414.  
  1415.          P OF^M AX,[OF+A^M BX,[OF+C^¿ =((AX=DX)&(BX=CX))^M AX,[OF^¿ AX+1^H
  1416.  
  1417.     Nach Beenden der  Befehlskette durch den ¿-Befehl zeigt  SE:OF ent-
  1418.     weder auf den Treiber für 'LPT1'  oder auf den  letzten Treiber (je
  1419.     nachdem hinter welchen ¿-Befehl der Cursor steht).
  1420.  
  1421.  
  1422.  
  1423.  
  1424.  
  1425.  
  1426.  
  1427.  
  1428.  
  1429.  
  1430.  
  1431.  
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437.  
  1438.  
  1439.     ────────────────────────────────────────────────────────────────────────────────
  1440.                                                                         Seite   21
  1441.  
  1442.  
  1443.  
  1444.     Ermitteln aller freien Speicherblöcke
  1445.  
  1446.          Vorbereitung:
  1447.  
  1448.          D M2
  1449.  
  1450.          Ausführung:
  1451.  
  1452.          M AL,[OF] ^¿ AL-'Z' ^A SE,[OF+3] ^+ SE ^M AX,[OF+1] ^¿ AX¬0 ^H
  1453.  
  1454.     Die  Ausführung  der  Befehlskette wird  bei jeden  Erreichen eines
  1455.     freien Speicherblocks  unterbrochen.  Nach einer Unterbrechung kann
  1456.     die Ausführung durch <CTRL-RETURN>  fortgesetzt werden.
  1457.     Der Befehl ' ¿ AL-'Z' ' verhindert die Fortsetzung falls der letzte
  1458.     Block erreicht ist, da dieser als Kennzeichen  das Zeichen  'Z' be-
  1459.     sitzt. Bei allen anderen Blöcken ist das Kennzeichen 'M'.
  1460.  
  1461.  
  1462.     Durchlaufen der MCB-Kette
  1463.  
  1464.     Im Interpreter den Befehl
  1465.  
  1466.          D M2
  1467.  
  1468.     eingeben,  diesen  über die  Taste <ESC>  verlassen  und  die Taste
  1469.     <Home> betätigen.
  1470.  
  1471.     Oder im  Monitor auf  einem Byte,  das  nicht den Wert 04Dh (= 'M')
  1472.     enthält, die Taste <M> betätigen.
  1473.  
  1474.     Die Kette  der MCBs  kann nun  im Monitor durch wiederholte Eingabe
  1475.     der Taste <M> durchlaufen werden.
  1476.  
  1477.     Im  Interpreter kann  die Kette  der MCBs  durch  folgende  Befehle
  1478.     durchlaufen werden:
  1479.  
  1480.          ADD OF,3 ^ ADD SE,[OF] ^ + SE ^ MOV OF,0 ^ W
  1481.     oder:
  1482.          ADD SE,[OF+3] ^ + SE ^ M BL,[OF] ^ ¿ (BL-'Z') ^ W
  1483.  
  1484.     Durch  die Eingabe  von <Backspace> auf den  W-Befehl  wird nun die
  1485.     Kette der MCBs  durchlaufen.  Der ¿-Befehl  beendet  die Ausführung
  1486.     nach dem letzten MCB.
  1487.  
  1488.  
  1489.  
  1490.  
  1491.  
  1492.  
  1493.  
  1494.  
  1495.  
  1496.  
  1497.  
  1498.  
  1499.     ────────────────────────────────────────────────────────────────────────────────
  1500.                                                                         Seite   22
  1501.  
  1502.  
  1503.  
  1504.     ■ Durchlaufen  der  Kette  der  MCBs im Interpreter mit Anzeige der
  1505.       Besitzer jedes Blocks
  1506.  
  1507.          Vorbereitung:
  1508.  
  1509.          D M2 ^ MOV R7,SE      @ R7 = Zwischenspeicher für akt. MCB
  1510.  
  1511.          Die Kette der MCBs kann nun durch folgende Befehlsfolge, unter
  1512.          Anzeige der Besitzer der Blöcke, durchlaufen werden:
  1513.  
  1514.          M SE,R7^A SE,[OF+3]^+ SE^M R7,SE^W^ M SE,SE+1:[2C]^W
  1515.          ─────── ──────────────── ─────── ─  ────────────── ─
  1516.          (1)     (2)              (3)    (4) (5)            (6)
  1517.  
  1518.     Durch  den  Befehl 'M SE,R7' (1)  wird zuerst  der  Monitor auf die
  1519.     Adresse  des  aktuellen MCB gesetzt. Danach wird durch  die Befehle
  1520.     'A SE,[OF+3] ^ + SE' (2)  im Register  SE  die Adresse des nächsten
  1521.     MCB  ermittelt. Durch den Befehl 'M R7,SE' (3)  wird diese dann  im
  1522.     Register R7 gesichert. Der  MCB wird  nun angezeigt (4).  Falls auf
  1523.     den  W-Befehl (4) die Taste <Backspace>  betätigt wird, wird sofort
  1524.     der nächste MCB angezeigt. Jede  andere Taste,  außer  <ESC>  führt
  1525.     dazu,  daß  über die Befehls-Folge 'M SE,SE+1:[2C]' (5)  zuerst der
  1526.     dem Block zugehörige Environmentblock angezeigt wird. Falls auf den
  1527.     zweiten W-Befehl  (6) <Backspace> betätigt  wird,  wird der nächste
  1528.     MCB angezeigt.   Da nur Hauptblöcke ein  Environment haben, ist die
  1529.     Eingabe  von <Backspace>  auf den ersten W-Befehl (4) nur  sinnvoll
  1530.     wenn das Wort am Offset OF+1 ungleich Null (Block ist frei) und un-
  1531.     gleich  08 (Block gehört zu DOS) ist.
  1532.     Außerdem muß  der Wert beim Offset  OF+1  gleich SE+1 sein, da der
  1533.     Block  sonst kein  Hauptblock ist.  Die Eingabe einer anderen Taste
  1534.     als  <ESC> oder <Backspace> auf  den  ersten W-Befehl,  falls diese
  1535.     Bedingungen nicht erfüllt sind, zeigt nur unsinnige Daten an.
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.  
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.     ────────────────────────────────────────────────────────────────────────────────
  1560.                                                                         Seite   23
  1561.  
  1562.  
  1563.  
  1564.     Graphisch  dargestellt ergibt sich also bei der Annahme das  der zu
  1565.     untersuchende MCB einem Programm gehört, daß  sein Environment noch
  1566.     nicht freigegeben hat, folgendes:
  1567.  
  1568.         zu untersuchender MCB (1)
  1569.  
  1570.                      ┌─> Länge des zugehörigen Blocks
  1571.                      │
  1572.         ┌───┬──────┬──────┬──────────────────────────┐
  1573.         │ M │ nnnn │ mmmm │ bei DOS 3.xx freier Rest │
  1574.         └───┴──────┴──────┴──────────────────────────┘
  1575.               ║
  1576.     ╔═════════╝
  1577.     ║
  1578.     ║    MCB des Hautpblocks (2)
  1579.     ║   ┌───┬──────┬──────┬──────────────────────────┐
  1580.     ║   │ M │ nnnn │ mmmm │ bei DOS 3.xx freier Rest │
  1581.     ║   └───┴──────┴──────┴──────────────────────────┘
  1582.     ║          ║
  1583.     ╠<═════════╝
  1584.     ╠<═══════════════════════════════════════════════════╗
  1585.     ║    PSP des Hauptblocks (folgt direkt auf den MCB 2)║
  1586.     ║                   Offset 2Ch                       ║
  1587.     ║   ┌────┬────┬─────┬──────┬───┐                     ║
  1588.     ╚══>│ CD │ 20 │ ... │ nnnn │...│                     ║
  1589.         └────┴────┴─────┴──────┴───┘                     ║
  1590.                            ║                             ║
  1591.     ╔══════════════════════╝                             ║
  1592.     ║    MCB des Environments des Hauptblocks (3)        ║
  1593.     ║   ┌───┬──────┬──────┬──────────────────────────┐   ║
  1594.     ║   │ M │ nnnn │ mmmm │ bei DOS 3.xx freier Rest │   ║
  1595.     ║   └───┴──────┴──────┴──────────────────────────┘   ║
  1596.     ║          ║                                         ║
  1597.     ║          ╚═════════════════════════════════════════╝
  1598.     ║
  1599.     ║    Environment des Hauptblocks (folgt direkt auf den MCB 3)
  1600.     ║   ┌──────┬──────┬──────────────────────────────┐
  1601.     ╚══>│ ...  │ 0001 │ Name des Besitzers           │
  1602.         └──────┴──────┴──────────────────────────────┘
  1603.  
  1604.         Hierbei  können die MCBs 1 und 2 oder 1 und 3 jeweils identisch
  1605.         sein.
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611.  
  1612.  
  1613.  
  1614.  
  1615.  
  1616.  
  1617.  
  1618.  
  1619.     ────────────────────────────────────────────────────────────────────────────────
  1620.                                                                         Seite   24
  1621.  
  1622.  
  1623.  
  1624.     Benutzung von MDEBUG für das Debuggen von eigenen Programmen
  1625.     ────────────────────────────────────────────────────────────
  1626.  
  1627.     MDEBUG eignet  sich  am  besten  zur  Anzeige und  Manipulation von
  1628.     Datenstrukturen von Programmen.
  1629.  
  1630.     MDEBUG  kann zum  Debuggen von  eigenen  Programmen  benutzt werden
  1631.     indem an den zu überprüfenden Stellen der Code zum Aufruf des User-
  1632.     Ints von MDEBUG eingefügt wird.
  1633.     Falls  verschiedene  Variablen  des  Programmes  untersucht  werden
  1634.     sollen, können die Adressen dieser vorher in die Prozessor-Register
  1635.     geladen werden oder aber über den Aufruf der Funktion 01h des User-
  1636.     Ints in die  Hilfsregister von MDEBUG geladen werden.
  1637.     (siehe TESTMD.PAS).
  1638.     Falls  in den  Registern SS  oder SP  Parameter  übergeben  werden,
  1639.     sollte  in MDEBUG vor  der Änderung dieser Register KEIN B-, I-, C-
  1640.     oder G-Befehl ausgeführt werden!
  1641.  
  1642.     Der aktuelle User-Int von MDEBUG sollte nicht als Konstante  einge-
  1643.     tragen,  sondern  während der Laufzeit ermittelt werden.
  1644.     Turbo-Pascal 5.0  z.B. mißbraucht den Interrupt 60h in der Entwick-
  1645.     lungsumgebung  für eigene Zwecke, so daß,  falls der  Interrupt 60h
  1646.     als User-Int von MDEBUG  installiert ist,  ein Aufruf  des User-Int
  1647.     aus  der Entwicklungsumgebung heraus zum Systemabsturz führt!
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.  
  1657.  
  1658.  
  1659.  
  1660.  
  1661.  
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.     ────────────────────────────────────────────────────────────────────────────────
  1680.                                                                         Seite   25
  1681.