home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 11 / mmr.doc < prev    next >
Encoding:
Text File  |  1989-04-28  |  18.5 KB  |  391 lines

  1.  
  2.  
  3. Interrupts auf dem PC
  4.  
  5. oder die Kunst, residente Programme wieder zu entfernen
  6.  
  7. von Karsten Gieselmann
  8.  
  9. Das Zauberwort bei PC-Software heißt TSR - Terminate but Stay
  10. Resident. Doch so nützlich TSR-Programme auch sind, oft ist ein
  11. Entfernen dieser "RAM-Fresser" nötig, sei es aus
  12. Speicherplatzmangel oder aus Gründen der Unverträglichkeit. Für
  13. selbstgeschriebene TSR- Anwendungen ist der "Griff zum
  14. Wegschmeißen" noch relativ einfach anzubringen, aber was tun
  15. bei kommerzieller oder Public- Domain-Software? Der folgende
  16. Beitrag führt Sie in anhand der Lösung dieses Problems
  17. praxisnah in die Tiefen und Höhen des Themas "Interrupts auf
  18. dem PC" ein.
  19.  
  20.  
  21. Wie funktioniert überhaupt ein TSR- Programm, was geschieht
  22. beim Laden und beim resident machen? Zunächst ist eine solche
  23. TSR-Anwendung für das DOS ein ganz normales Programm, das wie
  24. jedes andere Anwenderprogramm in den Speicher geladen und
  25. ausge- führt wird. DOS teilt das ihm zur Verfügung stehende RAM
  26. nach einem festen Schema auf.
  27.  
  28. Die TSR-Philosophie: Oft gebrauchte Programme verbleiben
  29. dauernd im Arbeitspeicher
  30.  
  31. Wenn bisher überhaupt noch keine Programme gestartet worden
  32. sind, so wird das erste aufgerufene Programm direkt hinter das
  33. DOS geladen und dann abgearbeitet. Handelt es sich bei diesem
  34. Programm nicht um eine Resident-Anwendung, also wirklich um
  35. ein "normales" Programm, so endet es mit einem Befehl, der
  36. die Kontrolle wieder an den Kommandoprozessor COMMAND.COM
  37. übergibt und den belegten Speicherplatz freimacht. Auf diese
  38. Weise wird das nächste Programm an die gleiche Stelle wie der
  39. Vorgänger geladen.
  40.  
  41. Gehört das Programm hingegen zum Typ "TSR", so endet es mit
  42. einem Befehl, der die Kontrolle zwar ebenfalls an den
  43. Kommandoprozessor übergibt, den vom Programm belegten
  44. Speicherplatz aber nicht wieder freimacht: Das Programm
  45. verbleibt an der Stelle im Speicher, an die es zur Ausführung
  46. geladen wurde. Außerdem merkt sich das DOS dies und erhöht die
  47. Anfangsadresse für das nächste aufgerufene Programm auf den
  48. Wert, welcher der letzten vom TSR-Programm belegten Speicher-
  49. stelle folgt. Damit ist der für Benutzerprogramme zur Verfügung
  50. stehende Speicherplatz geringer geworden!
  51.  
  52. Machen wir ein Beispiel: DOS hat auf diese Weise die residenten
  53. Programme KEYBGR, CLOCK, DOSEDIT und HYPERKEY geladen. Damit
  54. sieht die RAM-Belegung wie in Abbildung 2 dargestellt aus.
  55.  
  56. Gehen wir nun der Frage nach, wie die geladenen TSR's wieder
  57. zum Einsatz kommen, sind wir mitten im Thema "Interrupts". Denn
  58. in der Regel machen sich diese Programme dadurch bemerkbar, daß
  59. sie sich an den für das Betriebssystem lebenswichtigen
  60. Interruptvektoren zu schaffen machen.
  61.  
  62. Interupts sind für einen Rechner immens wichtig: Ohne sie geht
  63. nichts
  64.  
  65. Mit Interruptvektor bezeichnet man eine Unterpro- grammadresse,
  66. die an einer festen Speicherstelle im RAM "gemerkt" wird. Das
  67. DOS kennt eine ganze Reihe von solchen Interruptvektoren,
  68. insgesamt 256 Stück, und merkt sich deren Adressen, jeweils 4
  69. Bytes, Segment und Offset, in der sogenannten Interrupt-
  70. tabelle im Bereich von 0:0 bis 0:FFh.
  71.  
  72. Die Vektoren zeigen auf wichtige Unterprogramme, auch
  73. Interrupt- Service-Routine (ISR) genannt, ohne die ein Rechner
  74. überhaupt nicht funktionieren könnte. Von einem TSR-Programm
  75. wird eben diese Interrupt-Tabelle manipuliert:
  76.  
  77. Zur Erklärung: durch das Auslösen von Interrupts kön- nen
  78. Programme (Software- Interrupts) und Peripherie- geräte
  79. (Hardware-Interrupts) erzwingen, daß die CPU den normalen
  80. Programmablauf unterbricht und zunächst eine spezielle Routine
  81. abarbeitet, die die vom Interruptauslöser angeforderten
  82. Maßnahmen trifft.
  83.  
  84. Ein Beispiel: Drückt ein Anwender während eines lau- fenden
  85. Programms irgendeine Taste, so meldet die Tastatur der CPU
  86. dieses Ereignis durch Auslösen des Interrupt 9h. Für einen
  87. kurzen Augenblick, ein paar Millisekunden, wird die laufende
  88. Programmausführung unterbrochen und stattdessen "mal eben
  89. zwischendurch" dasjenige Unterprogramm abgearbeitet, auf
  90. welches der besagte Interruptvektor 9h zeigt: Die an der
  91. Tastatur bereit liegende Tastennummer abholen, entsprechend des
  92. aktuellen Umschaltstatus umcodieren und den resultierenden
  93. Tastencode im DOS- Tastaturpuffer placieren. Anschließend geht
  94. es dort mit der Ausfüh- rung weiter, wo zur
  95. Interruptbearbeitung abgebrochen wurde.
  96.  
  97. Eine wichtige Anwendung von TSR's ist die Verbesse- rung von
  98. Systemdiensten: Z.B. ein Spooler für die Druckeransteuerung,
  99. ein Kommandozeilen-Editor für die Eingabe von DOS-Kommandos
  100. oder ein Cache-Speicher für den Zugriff auf
  101. Festplatte/Diskette. Diese Programme setzen in ihrem
  102. Initialisierungsteil, dem Programmteil, der direkt nach dem
  103. Laden und vor dem resident machen ausgeführt wird, einfach den
  104. für sie wichtigen Interruptvektor auf eine neue, eigene
  105. Routine, die den verbesserten Service bereitstellt.
  106.  
  107. Viele der von TSR-Programmen installierten ISR's arbeiten dabei
  108. nicht völlig selbständig, sondern rufen Ihrerseits die vor dem
  109. Laden des TSR's gültige ISR wieder auf, bzw. setzen nach
  110. Abarbeitung der eigenen ISR die Programmausführung bei der
  111. alten ISR fort. Werden mehrere residente Programme geladen, die
  112. alle auf den gleichen Interruptvektor zugreifen, entsteht auf
  113. diese Weise eine Verkettung von Inter- ruptroutinen.
  114.  
  115. Der Zugriff auf einen Interruptvektor, im Fachjargon
  116. "verbiegen" oder "anzapfen", ist das Husarenstück eines TSR-
  117. Programms
  118.  
  119. Eine andere Art von TSR-Programmen sind die sogenann- ten Pop-
  120. Up-Routinen: Auf Knopfdruck erscheint ein Fenster, das Programm
  121. stellt seine Dienste bereit, um ebenfalls auf Knopfdruck wieder
  122. zu verschwinden und so zu tun, als ob überhaupt nichts passiert
  123. wäre.
  124.  
  125. Diese TSR's manipulieren ebenfalls mindestens einen
  126. Interruptvektor: den für die Tastaturabfrage. Sobald irgendeine
  127. Taste gedrückt wird, prüft die für die Tastatur zuständige ISR
  128. des Pop-Up's, ob diese Taste vielleicht die Aktivierungstaste
  129. (neudeutsch: Hotkey) für das Pop-Up ist. Zur Ermittlung des
  130. Tastencodes wird dabei ebenfalls auf die "normale" Tastaturrou-
  131. tine zurückgegriffen, so daß'sich beim Laden mehrerer solcher
  132. Programme auch hier eine Interrupt-Kette bildet.
  133.  
  134. Lenkt man an dieser Stelle die Gedanken in Richtung "Entfernen
  135. von residenten Programmen", so wird schnell klar, daß ein
  136. beliebiges Löschen von TSR's aus dem Arbeitsspeicher eine
  137. unsichere und gefährliche Sache ist: Unter Umständen wird mit
  138. einem TSR- Programm ein Glied aus einer Interruptkette
  139. entfernt.
  140.  
  141. Wird solch eine unterbrochene Interruptkette durch- laufen, so
  142. zeigt irgendeine eine Sprungadresse in einen (theoretisch)
  143. nicht mehr belegten Bereich. Zumeist aber steht dort
  144. mittlerweise schon etwas ganz anderes als die erwartete ISR,
  145. denn das DOS vergibt freien Speicherplatz wieder an andere
  146. Prozesse. Die Programmausführung wird dann an einer Stelle
  147. fortge- setzt, an der sich keine ISR mehr befindet: Ein
  148. sicherer Absturz des Rechners ist die Folge.
  149.  
  150. Wenn überhaupt TSR's entfernt werden können, dann höchstens von
  151. hinten nach vorne, also in der umge- kehrten Reihenfolge ihres
  152. Ladens: Nur so ist gewährleistet, daß Interruptketten intakt
  153. bleiben und alle Abläufe im Rechner weiterhin sicher vonstatten
  154. gehen.
  155.  
  156. Der erste Schritt zu einer "Verwaltung" von speicher-
  157. residenten Programmen ist ein Belegungsplan: An welcher
  158. Stelle im RAM befindet sich welches Programm und wieviel
  159. Speicherplatz belegt es? Um diese Frage beantworten zu können,
  160. müssen wir uns im Folgenden etwas detaillierter mit der DOS-
  161. Speicherverwaltung auseinandersetzen.
  162.  
  163. Das DOS organisiert seinen Hauptspeicher ganz ähn- lich, wie
  164. Turbo Pascal den Heap: in Form einer dynamisch verketteten
  165. Liste. Gemäß den Anforderungen werden über die DOS- Funktion
  166. 48h - ALLOCATE MEMORY von dem insgesamt zur Verfügung stehenden
  167. RAM mehr oder weniger große Stücke abgetrennt und als "belegt"
  168. gekennzeichnet. Bei der Freigabe solcher Bereiche durch die
  169. DOS-Funktion 49h - FREE ALLOCATED MEMORY werden diese wieder in
  170. die Freispeicherliste eingereiht.
  171.  
  172. Die zu dieser Organisation in Turbo Pascal verwende- ten Zeiger
  173. heißen bei DOS "Memory Control Blocks" (MCB). Im Gegensatz zu
  174. einem gewöhnlichen Zeiger - im Grunde genommen nicht mehr als
  175. eine Adresse - enthält ein MCB mehrere Informationen und jedem
  176. vom DOS angelegten Speicherblock wird ein MCB vorangestellt.
  177. Die- ser besteht aus insgesamt fünf Bytes, die sich wie folgt
  178. aufgliedern:
  179.  
  180.  
  181.   Byte Information
  182.  
  183.   0     Kennung ("M" oder "Z")
  184.   1,2   Segmentadresse des Programms
  185.   3,4   Blockgröße (in Paragraphen)
  186.  
  187. Das erste Byte enthält lediglich die Information, ob es sich
  188. bei diesem MCB schon um den letzten in der Kette handelt:
  189. trifft dies zu, so hat der MCB die Kennung "Z", anderenfalls
  190. die Kennung "M".
  191.  
  192. Die Bytes 1 und 2 ergeben das zum Speicherblock gehörige
  193. Programmsegment. Beim Laden eines Programms werden vom DOS
  194. zwei verschiedene Speicherblöcke ange- legt. Der erste
  195. beinhaltet das eigentliche Programm (Code, Daten- und
  196. Stacksegment). Außerdem das jedem Programm vorangestellte
  197. "Program Segment Prefix" (PSP), ein 256 Bytes großer Abschnitt,
  198. der unter an- derem Informationen über die Adressen einiger
  199. wichtiger Interruptroutinen, die DOS-Parameterzeile und die
  200. Segmentadresse des zum Programm gehörigen Environments
  201. enthält.
  202.  
  203. Die Kennzeichnung mit den Buchstaben "M" und "Z" hat seinen
  204. Grund: Es sind die Initialen des DOS-Autors, Mark Zbikovski.
  205.  
  206. Der zweite Speicherblock wird von eben diesem Environment
  207. belegt, hier finden sich die Informationen, die mit dem SET-
  208. Befehl auf DOS-Ebene manipuliert werden können (PATH,
  209. COMSPEC, PROMPT, etc.). Ab der DOS- Version 3.0 wird zusätzlich
  210. im Environment-Block noch der Name des zugehörigen Programms
  211. vermerkt, er liegt hinter den Umgebungsvariablen und ist von
  212. diesen durch die Bytefolge 00,00,01,00 getrennt.
  213.  
  214. Ist der Wert des Programm-Segments in einem MCB gleich Null, so
  215. bedeutet dies nichts weiter als das der folgende Speicherblock
  216. unbenutzt ist. Die Null wird dann vom DOS eingesetzt, wenn mit
  217. einer der dafür zuständigen DOS-Funktionen (48h, 4Ah) ein Spei-
  218. cherbereich wieder freigegeben wird und nicht an einen schon
  219. existierenden, freien Block angegliedert werden kann.
  220.  
  221. Byte 3 und 4 geben schließlich die Größe des zum MCB gehörenden
  222. Speicherblocks in Paragraphen an. Ein Paragraph entspricht 16
  223. Bytes, eine Zahl, die man als das Zeigerelement eines MCB's
  224. interpretieren kann: Addiert man zur Segmentadresse eines MCB's
  225. die Blockgröße plus eins, da trotz seiner Größe von nur fünf
  226. Bytes ein MCB immer genau einen ganzen Paragraphen belegt, so
  227. ergibt sich die Segmentadresse des nächsten MCB's!
  228.  
  229. Abbildung 3 zeigt in schematischer Darstellung, wie die
  230. Speicherverwaltung im DOS mit Hilfe der MCB's realisiert ist.
  231. Um eine Routine zu schreiben, welche sich mit Hilfe dieser
  232. MCB's durch das RAM hangelt und eine Liste aller vorhandenen
  233. Programme erstellt, benötigt man jetzt nur noch einen Einstieg:
  234. Die Adresse im Speicher, an welcher sich der erste MCB
  235. (sozusagen der Listenkopf) befindet.
  236.  
  237. Diese Adresse, oder besser gesagt einen Zeiger darauf, liefert
  238. die von Microsoft nicht dokumentierte Funktion 52h des
  239. Interrupts 21h. Nach Aufruf dieser Funktion enthält das
  240. Registerpaar ES:BX die Adresse einer Tabelle, in der die
  241. verschiedensten Informationen vermerkt sind. Genau vor dieser
  242. Tabelle befindet sich die Segmentadresse des ersten im Speicher
  243. befindlichen MCB. Zu bemerken ist, daß die Offsetadresse
  244. eines MCB immer Null ist.
  245.  
  246. Mit dem erarbeiteten Know-How läßt sich nun relativ problemlos
  247. eine Routine schreiben, welche Auskunft über die im Speicher
  248. befindlichen Programme gibt. Ausgegeben werden soll auf jeden
  249. Fall der Programmname, das Ladesegment, also die Stelle im
  250. RAM, wo sich das Programm befindet, und die Größe des vom
  251. Programm belegten Speicherplatzes. Da es Programme gibt, die
  252. nach dem Laden den Environment-Speicherblock wieder
  253. freigeben, z.B. die Treiber und residenten Dienstprogramme
  254. unter MS- DOS 3.2 wie KEYBGR oder PRINT, soll auch die Anzahl
  255. der zu einem PSP gehörigen Blöcke ausgegeben werden.
  256.  
  257. Die Landkarte der RAM-Speicherbelegung misst in Paragraphen.
  258. Allerdings keine juristischen, denn in der Informatik ist der
  259. Paragraph 16 Bytes lang.
  260.  
  261. Diese Leistungen werden durch die Turbo-Pascal-Unit MAKEMAP.INC
  262. zur Verfügung gestellt: Der Belegungsplan wird in Form einer
  263. doppelt verketteten dynamischen Liste angelegt. Die Funktion
  264. "MakeMemoryMap" liefert nach Rückkehr ins aufrufende Programm
  265. einen Zeiger auf den ersten Eintrag des Belegungsplans. Das ei-
  266. gentliche Programm MAP hat dannach außer der Ausgabe der Liste
  267. (die Abbildungen 4 und 5 zeigen typische Outputs von MAP)
  268. eigentlich nicht mehr viel zu tun.
  269.  
  270. Es gibt jedoch noch einen Punkt, den es gleich mit erledigen
  271. kann: Gerade bei residenten Programmen ist es oft sehr nützlich
  272. zu wissen, welche Interrupt- Vektoren von einer Routine
  273. "umgebogen" werden. Dies läßt sich relativ einfach angeben: Für
  274. alle Einträge in der Interrupt-Tabelle wird überprüft, ob sie
  275. in das jeweilige Programm hineinzeigen. Ist dies der Fall, so
  276. kann man davon ausgehen, daß der zugehörige Interruptvektor vom
  277. betreffenden Programm "umgebogen" wurde.
  278.  
  279. Das beschriebene Verfahren zieht allerdings eine kleine
  280. Einschränkung nach sich: Wird ein Interrupt durch mehrere
  281. residente Routinen angezapft, findet MAP immer nur das
  282. Programm, welches sich als letztes am entsprechenden Vektor "zu
  283. schaffen machte".
  284.  
  285. Wie schon angedeutet wird beim Laden eines Programms der Name
  286. im Environment-Block vermerkt. Wird beim resident machen die
  287. zugehörige Umgebung nicht berücksichtigt, so hat MAP keine
  288. allgemein gültige Möglichkeit, den Namen eines Programms zu
  289. erkennen. Gleiches gilt bei der Verwendung eines DOS mit einer
  290. Versionsnummer kleiner 3.0. In diesem Fall wird anstelle des
  291. Programmnamens von MAP ein '???' ausgegeben.
  292.  
  293. Zum Gebrauch: Man compiliert MAP.PAS am besten als EXE-File.
  294. Ein Betreiben im Memory-Mode ist im Hinblick auf den
  295. Verwendungszweck des Programms wenig sinnvoll. Da das Programm
  296. ohne das Unit CRT auskommt, läuft der Output über die
  297. Standardausgabe von DOS, kann also beliebig in Drucker, Datei,
  298. etc. umgeleitet werden.
  299.  
  300. Die von den TSR-Programmen aufgebauten Interrupt- ketten lassen
  301. im Grunde nur ,,fein sicheresKonzept für das Entfernen dieser
  302. Programme zu: Den MARK- RELEASE- Mechanismus, ein Konzept, das
  303. auch für die Heap-Verwaltung unter Turbo Pascal verwendet wird.
  304. Die Vorgehensweise ist genauso simpel wie zuverläs- sig, indem
  305. in einer linearen Liste eine Position mit MARK markiert wird.
  306. Ein anschließendes RELEASE veranlaßt, daß alle auf diese
  307. gekennzeichnete Position folgenden Listenelemente bis zum
  308. Listenende gelöscht und der von ihnen belegte Speicherplatz
  309. wieder freigegeben wird.
  310.  
  311. Befinden sich in der Liste mehrere MARKierte Positio- nen, so
  312. orientiert sich RELEASE am jeweils letzten MARK. Wird jedes an
  313. die Liste angehängte Element also vorher mit einem MARK
  314. versehen, so kann man die Liste gezielt von hinten nach vorne
  315. mittels RELEASE wieder abbauen. Ein Beispiel für die Anwendung
  316. von MARK- RELEASE zeigt Abbildung 4/5.
  317.  
  318. Wie kann dieser Mechanismus nun aber konkret als Programm
  319. umgesetzt werden? Hierzu muß man sich zunächst einmal
  320. überlegen, was die einzelnen Programmteile leisten müssen.
  321. Markiert man das Ende der Programm- Liste im RAM und lädt eine
  322. residente Routine, die man nach Gebrauch wieder entfernen
  323. möchte , so müssen eigentlich nur die Interruptvektoren nach
  324. dem RELEASE-Befehl wieder auf dem Stand sein, auf dem sie zum
  325. Zeitpunkt der Ausführung von MARK waren.
  326.  
  327. Das Programm, das die RAM-residenten Programme markiert, ist
  328. praktischerweise selbst resident.
  329.  
  330. Die einzige Aufgabe von MARK ist es also, die augen- blickliche
  331. Programm-Ladeadresse und den aktuellen Stand der
  332. Interruptvektoren irgendwo festzuhalten. Das läßt sich sehr
  333. elegant bewerkstelligen, indem MARK selbst resident auslegt
  334. wird. Zum einen lassen sich markierte Stellen so leicht mit dem
  335. MAP- Programm erkennen, zum anderen braucht man sich keine
  336. Gedanken zu machen, ob die Interruptvektoren auf einem Laufwerk
  337. oder sonstwo abgelegt werden sollen: Für sie wird einfach ein
  338. entsprechendes Plätzchen im MARK-Programmcode reserviert.
  339.  
  340. Ein Großteil der von RELEASE zu leistenden Arbeit steckt schon
  341. in dem von MAP verwendeten Include-File MAKEMAP, nämlich das
  342. Erstellen der Speicherliste. Da diese Liste vorsorglich als
  343. doppelt verkettet aufge- baut wurde, d.h.von jedem Element mit
  344. Ausnahme des ersten und letzten kann der Nachfolger bzw.
  345. Vorgänger erreicht werden, muß RELEASE sich lediglich bis zum
  346. letzten Listenelement durcharbeiten, um dann die Liste von
  347. hinten nach vorne aufzurollen, bis das erste Mal ein MARK
  348. auftaucht. Die alten Interruptvek- toren können nun wieder
  349. ausgelesen und an ihren ursprünglichen Platz gebracht werden
  350. und alle Umbie- ge- und Anzapfaktionen der danach geladenen
  351. Programme sind damit außer Kraft gesetzt.
  352.  
  353. Natürlich soll auch der von diesen Programmen belegte Speicher
  354. wieder für andere Zwecke zur Verfügung gestellt werden. Hierbei
  355. ist die DOS-Funktion 49h (FREE ALLOCATED MEMORY) behilflich.
  356. Nacheinander werden dieser Funktion alle Ladesegmente der nach
  357. MARK geladenen Programme übergeben und so wieder freigemacht.
  358.  
  359. Damit auch noch 2.x-DOS-Anwender in den MARK- RELEASE-Genuß
  360. kommen, muß eine Erkennung von MARK gewählt werden, die sich
  361. nicht auf den Namen bezieht, da bei diesen Systemen ja noch
  362. keine Programmnamen vermerkt werden. Dazu sollte es aber schon
  363. ausreichen, die ersten Bytes des jeweiligen Programmcodes mit
  364. denen von MARK zu vergleichen.
  365.  
  366. Dank der Verwendung von MAKEMAP kann RELEASE ziemlich kurz
  367. gehalten werden. Auch RELEASE ist nur als EXE- File zu
  368. betreiben: Ein Lauf im Memory-Mode schickt den Rechner
  369. unweigerlich in die ewigen Jagdgründe.
  370.  
  371. Um den Code des residenten Markierungs-Programmes möglichst
  372. klein zu halten, hilft ein Trick aus alten Zeiten: Ein "Lader"
  373.  
  374. Einiges Kopfzerbrechen bereitet zunächst das MARK- Programm: Da
  375. diese Routine wahrscheinlich des öfteren in den Speicher
  376. geladen wird, im Extremfall vor jedem residenten Programm, ist
  377. es natürlich günstig, den Programmcode von MARK so klein wie
  378. möglich zu halten.
  379.  
  380. Da der in MARK benötigte Code im Grunde genommen ver-
  381. schwindend klein ist, denn es muß ja nur das Kopieren der
  382. Interruptvektoren vorgenommen werden, wurde zu einer Methode
  383. gegriffen, die einige unter den Lesern vielleicht noch aus
  384. ihren Anfängen kennen: In Anlehnung an die berühmt-
  385. berüchtigten BASIC-Lader wird das MARK-Programm von einem
  386. "Turbo-Lader" erzeugt. Der eigentliche Programmcode taucht im
  387. Laderprogramm MAKEMARK als Array of Byte auf und wird als
  388. ausführbares COM-File auf Diskette geschrieben, so belegt er
  389. lediglich 23 Bytes auf Diskette und mit der Interrupt-Tabelle
  390. ca. 1,4 kByte resident im Speicher!
  391.