5.9. Interrupts mit Intel-Prozessoren |
![]() |
![]() |
Letztmalig dran rumgefummelt: 17.02.08 09:58:39 |
![]() |
Ein Interrupt ist die Unterbrechung des aktuell laufenden Programmes/Prozesses durch einen Prozess höherer Priorität. Durch die Auslösung eines Interrupts wird der Prozessor darauf aufmerksam gemacht, dass ein anderes Programm seine Dienste benötigt. | |||||||
![]() |
1. Interruptquellen |
|||||||
![]() |
|
|||||||
![]() |
Quellen:
|
|||||||
![]() |
Interrupts sind zeitweilige Unterbrechungen eines laufenden Programms durch Prozesse höherer Priorität. Nach Abarbeitung der "Interrupt-Routine" wird der Zustand vor der Unterbrechung wieder hergestellt und das unterbrochene Programm i. A. wieder aufgenommen. |
1. Interruptquellen |
![]() |
![]() |
![]() |
![]() |
Seit Einzug des Betriebssystems MS-DOS sind diese Interrupts faktisch unverändert erhalten und bilden gestützt auf die direkte Interruptprogrammierung der Intel-CPUs die Basis der Arbeit des Basic-In- Outsystems jedes Computers. |
![]() |
Interrupts können von 3 verschiedenen Quellen ausgelöst werden:
die BIOS-Interrupt-Tabelle Hardware-Interrupts ausgelöst durch CPU
BIOS-Interrupts
MS-DOS-Interrupts
Nicht verwechseln mit den IRQ
|
2. Int 21 - die Windows-APIs |
![]() |
![]() |
![]() |
![]() |
Über den Interrupt 21h können mehr als 100 Funktionen erreicht werden, die das DOS einem Programm zur Verfügung stellt und die deshalb als Application-Program-Interface (DOS-API) bezeichnet werden. Nachfolgend die Übersicht der Funktionen des Interrupts 21h. |
![]() |
Fkt. Beschreibung ab Version 01h Zeicheneingabe mit Ausgabe 1.0 03h Empfang eines Zeichens von der seriellen Schnittstelle 1.0 06h Direkte Zeichenein-/-ausgabe 1.0 07h Direkte Zeicheneingabe ohne Ausgabe 1.0 08h Zeicheneingabe ohne Ausgabe 1.0 0Ah Eingabe einer Zeichenkette 1.0 0Bh Lese Eingabestatus 1.0 0Ch Lösche Eingabepuffer und rufe Eingabefunktion auf 1.0 02h Ausgabe eines Zeichens 1.0 04h Ausgabe eines Zeichens auf die serielle Schnittstelle 1.0 05h Ausgabe auf parallele Schnittstelle 1.0 06h Direkte Zeichenein-/-ausgabe 1.0 09h Ausgabe einer Zeichenkette 1.0 00h Programm beenden 1.0 31h Programm beenden, aber im Speicher belassen 2.0 4Ch Programm mit Ende-Code beenden 2.0 39h Unterverzeichnis erstellen 2.0 3Ah Unterverzeichnis löschen 2.0 3Bh Aktuelles Verzeichnis setzen 2.0 47h Aktuelles Verzeichnis ermitteln 2.0 48h RAM-Speicher reservieren 2.0 49h RAM-Speicher freigeben 2.0 4Ah Größe eines Speicherbereichs ändern 2.0 58h/00h Konzept der Speicherverteilung lesen 3.0 58h/01h Konzept der Speicherverteilung setzen 3.0 58h/02h Einbindung der UMBs abfragen 5.0 58h/03h Einbindung der UMBs festlegen 5.0 44h/00h IOCTL: Lesen des Geräte-Attributs 2.0 44h/01h IOCTL: Setzen des Geräte-Attributs 2.0 44h/02h IOCTL: Daten von einem Zeichentreiber empfangen 2.0 44h/03h IOCTL: Daten an einen Zeichentreiber senden 2.0 44h/04h/1 IOCTL: Daten von einem Blocktreiber empfangen 2.0 44h/04h/2 DBLSPC: Internen Cache schreiben 6.0 44h/04h/3 DBLSPC: Internen Cache schreiben und invalidieren 6.0 44h/05h IOCTL: Daten an einen Blocktreiber übertragen 2.0 44h/06h IOCTL: Eingabestatus abfragen 2.0 44h/07h IOCTL: Ausgabestatus abfragen 2.0 44h/08h IOCTL: Ist das Medium wechselbar? 3.0 44h/09h IOCTL: Device-Remote-Test 3.1 44h/0Ah IOCTL: Handle-Remote-Test 3.1 44h/0Bh IOCTL: Zugriffswiederholung setzen 3.0 44h/0Ch IOCTL: Kommunikation mit einem Zeichentreiber 3.3 44h/0Dh IOCTL: Kommunikation mit einem Blocktreiber 3.2 44h/0Eh IOCTL: Letzte Laufwerksbezeichnung ermitteln 3.2 44h/0Fh IOCTL: Nächste Laufwerksbezeichnung definieren 3.2 44h/10h IOCTL-Unterstützung auf Handle-Ebene abfragen 5.0 44h/11h IOCTL-Unterstützung auf Geräte-Ebene abfragen 5.0 2Ah Datum abfragen 1.0 2Bh Datum setzen 1.0 2Ch Uhrzeit abfragen 1.0 2Dh Uhrzeit setzen 1.0 1Ah Setzen der DTA-Adresse 1.0 2Fh DTA ermitteln 2.0 11h Suche ersten Directory-Eintrag (FCB) 1.0 12h Suche nächsten Directory-Eintrag (FCB) 1.0 4Eh Ersten Directory-Eintrag suchen (Handle) 2.0 4Fh Nächsten Directory-Eintrag suchen (Handle) 2.0 0Fh Datei öffnen (FCB) 1.0 10h Datei schließen (FCB) 1.0 13h Datei(en) löschen (FCB) 1.0 14h Sequentielles Lesen (FCB) 1.0 15h Sequentielles Schreiben (FCB) 1.0 16h Erstellen oder Leeren einer Datei (FCB) 1.0 17h Datei(en) umbenennen (FCB) 1.0 21h Wahlfreies Lesen (FCB) 1.0 22h Wahlfreies Schreiben (FCB) 1.0 23h Lese Dateigröße (FCB) 1.0 24h Setze Datensatznummer 1.0 27h Wahlfreies Lesen mehrerer Datensätze (FCB) 1.0 28h Wahlfreies Schreiben mehrerer Datensätze (FCB) 1.0 29h Dateinamen in FCB übertragen 1.0 3Ch Datei erstellen oder leeren (Handle) 2.0 3Dh Datei öffnen (Handle) 2.0 3Eh Datei schließen (Handle) 2.0 3Fh Datei lesen (Handle) 2.0 40h Datei beschreiben (Handle) 2.0 41h Datei löschen (Handle) 2.0 42h Dateizeiger bewegen (Handle) 2.0 45h Handle verdoppeln 2.0 46h Handles angleichen 2.0 56h Datei umbenennen oder verschieben (Handle) 2.0 5Ah Temporäre Datei erstellen (Handle) 3.0 5Bh Neue Datei erstellen (Handle) 3.0 5Ch/00h Bereich einer Datei gegen Zugriff schützen 3.0 5Ch/01h Freigabe eines gesperrten Bereichs in einer Datei 3.0 6Ch Erweiterte OPEN-Funktion 4.0 5Eh/00h Namen des Rechners im Netzwerk ermitteln 3.1 5Eh/02h Initialisierungs-String für Netzwerkdrucker festlegen 3.1 5Eh/03h Initialisierungs-String für Netzwerkdrucker ermitteln 3.1 5Fh/02h Eintrag aus der Netzwerkliste holen 3.1 5Fh/03h Eintrag in der Netzwerkliste definieren 3.1 5Fh/04h Eintrag aus der Netzwerkliste entfernen 3.1 25h Setze Interrupt-Vektor 1.0 35h Inhalt eines Interrupt-Vektors auslesen 2.0 0Dh Reset der Blocktreiber 1.0 0Eh Auswahl des aktuellen Laufwerks 1.0 19h Gerätebezeichnung des aktuellen Laufwerks erfragen 1.0 1Bh Informationen über das aktuelle Laufwerk einholen 1.0 1Ch Informationen über ein beliebiges Laufwerk einholen 1.0 1Fh DPB-Zeiger für das aktuelle Laufwerk ermitteln 1.0 32h Zeiger auf DPB für ein beliebiges Laufwerk ermitteln 1.0 36h Verbleibende Plattenkapazität ermitteln 2.0 53h BPB in DPB umsetzen 2.0 26h Erstelle neuen PSP 1.0 50h Aktiven PSP setzen 2.0 51h Aktiven PSP ermitteln 2.0 55h Neuen PSP erstellen 2.0 62h Adresse des PSP ermitteln 3.0 2Eh Setzen des Verify-Flags 1.0 33h/00h Lesen des Break-Flags 2.0 33h/01h Setzen des Break-Flags 2.0 34h DOS Zeiger auf das INDOS-Flag ermitteln 2.0 37h/00h Kennzeichen für Kommandozeilen-Schalter ermitteln 2.0 37h/01h Kennzeichen für Kommandozeilen-Schalter setzen 2.0 52h Zeiger auf DOS-Info-Block ermitteln 2.0 54h Verify-Flag lesen 2.0 43h/00h Attribut einer Datei ermitteln 2.0 43h/01h Attribut einer Datei setzen 2.0 57h/00h Datum und Uhrzeit der letzten Modifikation einer Datei ermitteln 2.0 57h/01h Datum und Uhrzeit der letzten Modifikation einer Datei setzen 2.0 38h Landesspezifische Symbole und Formate ermitteln 2.0 38h/00h Landesspezifische Symbole und Formate ermitteln 3.0 38h/01h Land setzen 3.0 30h DOS-Versionsnummer ermitteln 2.0 4Bh/00h EXEC: anderes Programm ausführen 2.0 4Bh/03h EXEC: anderes Programm als Overlay laden 2.0 4Bh/05h EXEC: eigene EXECs anpassen 5.0 4Dh Ende-Code ermitteln 2.0 59h Erweiterte Fehlerinformationen einholen 3.0 60h Dateinamen erweitern 3.0 66h/01h Aktuelle Code-Page ermitteln 3.3 66h/02h Aktuelle Code-Page festlegen 3.3 67h Anzahl der verfügbaren Handles festlegen 3.3 68h Dateipuffer leeren 3.3 (Copyright 1994 Data Becker, All Rights reserved) |
3. Die Prozedur Intr |
![]() |
![]() |
![]() |
![]() |
Über die Interrupts 10h bis 1Ah können die verschiedenen Funktionen erreicht werden, die das ROM-BIOS zur grundlegenden Kommunikation zwischen einem Programm und der Hardware zur Verfügung stellt. Dazu zählen neben Funktionen zum Zugriff auf die Video-Hardware, Tastatur, Festplatten und Diskettenlaufwerke, aber auch die Abfrage von Konfigurationsdaten, sowie die Programmierung der seriellen und parallelen Schnittstelle und der batteriegepufferten Echtzeituhr. |
![]() |
Übersicht der BIOS-Funktionen Interrupt 10h Bildschirm Fkt. Beschreibung 00h Setzen des Video-Modus 01h Definition des Erscheinungsbildes des Cursors 02h Positionierung des Cursors 03h Auslesen der Cursor-Position 04h Auslesen der Lichtstiftposition 05h Auswahl der aktuellen Bildschirmseite 06h Textzeilen nach oben schieben (scrollen) 07h Textzeilen nach unten schieben (scrollen) 08h Auslesen eines Zeichens/Farbe 09h Schreiben eines Zeichens/Farbe 0Ah Schreiben eines Zeichens 0Bh/00h Auswahl der Rahmen-/Hintergrundfarbe 0Bh/01h Auswahl der Farbpalette 0Ch Schreibe Grafikpunkt 0Dh Lese Grafikpunkt 0Eh Schreiben eines Zeichens 0Fh Auslesen des Video-Modus 13h Ausgabe einer Zeichenkette (ab AT) Interrupt 11h Feststellung der Konfiguration Interrupt 12h Feststellung der Speichergröße Interrupt 13h Diskette Fkt. Beschreibung Rechner 00h Reset 01h Status Lesen 02h Lesen 03h Schreiben 04h Verifizieren 05h Formatieren 06h Festplatte 07h Festplatte 08h Format abfragen (ab AT) 09h Festplatte 0Ah Festplatte 0Bh Festplatte 0Ch Festplatte 0Dh Festplatte 0Eh Festplatte 0Fh Festplatte 10h Festplatte 11h Festplatte 12h Festplatte 13h Festplatte 14h Festplatte 15h Feststellung des Laufwerktyps (ab AT) 16h Feststellung eines Diskettenwechsels (ab AT) 17h Diskettenformat festlegen (ab AT) 18h Diskettenformat festlegen (ab AT) Interrupt 13h Festplatte Fkt. Beschreibung Rechner 00h Reset (ab XT) 01h Status lesen (ab XT) 02h Lesen (ab XT) 03h Schreiben (ab XT) 04h Verifizieren (ab XT) 05h Formatieren (ab XT) 08h Format erfragen (ab XT) 09h Anpassung fremder Laufwerke (ab XT) 0Ah Erweitertes Lesen (ab XT) 0Bh Erweitertes Schreiben(ab XT) 0Ch Schreib-/Lesekopf bewegen (ab XT) 0Dh Reset (ab XT) 0Eh Controller-Lese-Test (PS/2) 0Fh Controller-Schreib-Test (PS/2) 10h Ist das Laufwerk bereit? (ab XT) 11h Rekalibrieren des Laufwerks (ab XT) 12h Controller-RAM-Test (PS/2) 13h Laufwerk-Test (PS/2) 14h Controller-Diagnose (ab XT) 15h Feststellung des Laufwerktyps (ab AT) Interrupt 14h Serielle Schnittstelle Fkt. Beschreibung Rechner 00h Initialisierung 01h Zeichen ausgeben 02h Zeichen einlesen 03h Status erfragen Interrupt 15h Alter Kassetten-Interrupt (ab AT) Fkt. Beschreibung Rechner 83h Flag nach Zeitintervall setzen (ab AT) 84h/00h Abfrage des Status der Feuerknöpfe der Joysticks (ab AT) 84h/01h Abfrage der Stellung der Joysticks (ab AT) 85h SysReq-Taste betätigt (ab AT) 86h Warten (ab AT) 87h Speicherbereiche verschieben (ab AT) 88h Speichergröße über 1 MByte ermitteln (ab AT) 89h Umschaltung in den Protected Mode (ab AT) Interrupt 16h Tastatur Fkt. Beschreibung Rechner 00h Zeichen auslesen 01h Zeichen vorhanden? 02h Status der Tastatur erfragen 03h Wiederholrate einstellen (ab AT) 05h Tastendruck simulieren (ab AT) 10h Tastaturabfrage für erweiterte Tastaturen (ab AT) 11h Tastaturabfrage für erweiterte Tastaturen (ab AT) Interrupt 17h (paralleler) Drucker Fkt. Beschreibung Rechner 00h Zeichen ausgeben 01h Drucker initialisieren 02h Status des Druckers erfragen Interrupt 18h ROM-BASIC Interrupt 19h Booten des Rechners Interrupt 1Ah Datum und Zeit Fkt. Beschreibung Rechner 00h Zeit-Zähler auslesen 01h Zeit-Zähler setzen 02h Auslesen der Echtzeit-Uhr (ab AT) 03h Setzen der Echtzeit-Uhr (ab AT) 04h Auslesen des Datums aus der Echtzeit-Uhr (ab AT) 05h Setzen des Datums der Echtzeit-Uhr (ab AT) 06h Alarmzeit setzen (ab AT) 07h Alarmzeit löschen (ab AT) |
4. Programmbeispiele |
![]() |
![]() |
![]() |
![]() |
Gut entwickelte Programme ... |
![]() |
* Beispiel 1: Auslösen eines Wamstarts; (Achtung, bei speicherresidenten Programmen und Gerätetreibern kann diese Prozedur nicht funktionieren!) PROCEDURE WarmStart; VAR reg : Registers BEGIN Intr($19,reg) end; |
![]() |
* Beispiel 2: Abschalten des Cursors PROCEDURE CursorAus; VAR reg : Registers BEGIN reg.ah:=1; reg.cx:=$FFFF; { Zum Wiedereinschalten: $0607 } Intr($10,reg) end; |
![]() |
* Beispiel 3: Abfragen der Laufwerke anhand der BIOS- Informationen {Laufwerkstest für PC C 1994, Ralph ScholzDieses Programm prüft über den Interrupt 13, welche Diskettenlaufwerke am Gerät angeschlossen sind. Dabei wird vor Aufruf des Interrupts im Register AH die Funktionsnummer eingetragen (hier Nr. 08h). Im Register DL steht die Laufwerksnummer (00h fr LAufwerk A, 01h fr LAufwerk B). Nach Aufruf des Interrupts steht im Register BL ein Hex- Wert, über den die Laufwerksidentifizierung möglich ist. Die entsprechende Belegung ist in den unten stehenden Prozeduren ablesbar.} program Laufwerke_identifizieren; uses dos,crt; VAR reg : Registers;{Registers ist eine vordefinierte Variable} zylinder:integer; procedure Laufwerk_a; BEGIN reg.ah:=$08;{Funktionsnummer festlegen, hier Nr. 08 zur Ermittlung des Laufwerkstypes} reg.dl:=$00;{Diskettenlaufwerk 1 wird abgefragt, d.h. im Register DL steht eine 00h} Intr($13,reg); case reg.bl of $00: writeln(' nicht vorhanden.'); $01: writeln(' ist ein 5,25 Zoll- Laufwerk mit 360 KByte Speicherkapazität.'); $02: writeln(' ist ein 5,25 Zoll- Laufwerk mit 1,2 MByte Speicherkapazität.'); $03: writeln(' ist ein 3,5 Zoll- Laufwerk mit 720 KByte Speicherkapazität.'); $04: writeln(' ist ein 3,5 Zoll- Laufwerk mit 1,44 MByte Speicherkapazität.'); end; end; procedure Laufwerk_b; BEGIN reg.ah:=$08;{Funktionsnummer festlegen, hier Nr. 08 zur Ermittlung des Laufwerkstypes} reg.dl:=$01;{Diskettenlaufwerk 2 wird abgefragt, d.h. im Register DL steht eine 01h} Intr($13,reg); case reg.bl of $00: writeln(' nicht vorhanden.'); $01: writeln(' ist ein 5,25 Zoll- Laufwerk mit 360 KByte Speicherkapazität.'); $02: writeln(' ist ein 5,25 Zoll- Laufwerk mit 1,2 MByte Speicherkapazität.'); $03: writeln(' ist ein 3,5 Zoll- Laufwerk mit 720 KByte Speicherkapazität.'); $04: writeln(' ist ein 3,5 Zoll- Laufwerk mit 1,44 MByte Speicherkapazität.'); end; END; procedure laufwerk_c; BEGIN reg.dl:=$80;{Festlegen des Laufwerkes, hier erste Festplatte} reg.ah:=$08;{Fromat abfragen} Intr($13,reg); case reg.ah of $01: writeln('Nicht zulässiges Laufwerk'); $02: writeln('Adreámarkierung nicht gefunden'); $04: writeln('Sektor nicht gefunden'); $05: writeln('Fehler beim Controllerreset'); $07: writeln('Fehler bei Controllerinitialisierung'); $09: writeln('Datenübertragung über Segmentgrenze'); $0A: writeln('Sektor fehlerhaft'); $10: writeln('Lesefehler'); $11: writeln('Lesefehler, korrigiert'); $20: writeln('Fehler des Diskettencontrollers'); $40: writeln('Spur nicht gefunden'); $80: writeln('Time Out- Fehler, Laufwerk reagiert nicht'); $AA: writeln('Laufwerk nicht bereit'); $CC: writeln('Schreibfehler'); $00: begin write(' ',reg.dh+1,' Schreib- Lesek”pfe, '); write(reg.cx and 63,' Sektoren, '); zylinder:= hi(reg.cx) + (lo(reg.cx) and 192) shl 2; write(zylinder,' Zylinder'); end; end; end; procedure laufwerk_d; BEGIN reg.dl:=$81;{Festlegen des Laufwerkes, hier zweite Festplatte} reg.ah:=$08;{Fromat abfragen} Intr($13,reg); case reg.ah of $01: writeln('Nicht zulässiges Laufwerk'); $02: writeln('Adreámarkierung nicht gefunden'); $04: writeln('Sektor nicht gefunden'); $05: writeln('Fehler beim Controllerreset'); $07: writeln('Fehler bei Controllerinitialisierung'); $09: writeln('Datenübertragung über Segmentgrenze'); $0A: writeln('Sektor fehlerhaft'); $10: writeln('Lesefehler'); $11: writeln('Lesefehler, korrigiert'); $20: writeln('Fehler des Diskettencontrollers'); $40: writeln('Spur nicht gefunden'); $80: writeln('Time Out- Fehler, Laufwerk reagiert nicht'); $AA: writeln('Laufwerk nicht bereit'); $CC: writeln('Schreibfehler'); $00: begin write(' ',reg.dh+1,' Schreib- Lesek”pfe, '); write(reg.cx and 63,' Sektoren, '); zylinder:= hi(reg.cx) + (lo(reg.cx) and 192) shl 2; write(zylinder,' Zylinder'); end; end; end; {Hauptprogramm} begin clrscr; gotoxy(15,3); write('An diesem PC sind folgende Laufwerke angeschlossen:'); gotoxy(15,4); write('---------------------------------------------------'); gotoxy(1,7); write('Laufwerk A:'); laufwerk_a; gotoxy(1,10); write('Laufwerk B:'); laufwerk_b; gotoxy(1,13); write('Laufwerk C:'); laufwerk_c; gotoxy(1,16); write('Laufwerk D:'); laufwerk_d; gotoxy(1,24);write('> enter...'); readln; end. |
5. Interruptprogrammierung mit PASCAL |
![]() |
![]() |
![]() |
![]() |
Schnelle Verarbeitung von
Standard-Zugriffen auf Komponenten des PCs sowie Grundalgorithmen bei der
Verarbeitung von Daten, aber auch die Regulierung des Datenstromes bzw. die
Vorbereitung der Hardware für diese Vorgänge sind nunmehr angesagt.
|
![]() |
Quellen: - Hardware (IRQ1 - 15, Maus, Erweiterungskarten, Tastatur...) - Systemsoftware (DOS, Treiber ...) Wirkung: - das ist ein weites Feld - Kommunikation der Programme mit dem BIOS - Steuerung der externen Geräte (Massenspeicher, Tastatur, Video, Schnittstellen...) - Zusammenspiel aller Hardwarekomponenten Es gibt 128 mögliche Interrupts mit bis zu 128 Unterfunktionen. Eine vollständige Darstellung ist in diesem Rahmen also leider unmöglich. |
![]() |
hier gibt's die Beispiele |
6. Maschinenprogrammierung |
![]() |
![]() |
![]() |
![]() |
|
![]() |
|
![]() |
7. Echtzeitverhalten und Echtzeitsysteme |
![]() |
![]() |
![]() |
![]() |
Das ist eine Extremforderung an Software, welche mit genau dafür zugeschnittener Hardware ein Maximum an Effizienz, ein Minimum an Redundanz und damit wiederum ein Minimum an Rechenzeit zu erreichen sucht. Es gilt hier, in extrem kurzer Zeit auf Ereignisse von außen angemessen zu reagieren (also auch nicht über zu reagieren). Echtzeitsysteme haben ihr zu hause in der Industrie, der Weltraumfahrt |
![]() |
|
![]() |
8. Verwandte Themen |
![]() |
![]() |
![]() |
![]() |
Programme sind neben der Hardware wohl die wichtigste und so ganz nebenbei auch teuerste Komponente beim Computereinsatz. Gern wird dieser Umstand vernachlässigt und in Größenordnungen wird geklaut. Dabei ist ein Unrechtsbewusstsein in Deutschland kaum ausgeprägt und folgerichtig ist Software in Deutschland um Größenordnung teurer als in umliegenden europäischen Staaten. | |||||||||||||||||||||
![]() |
|
|||||||||||||||||||||
![]() |
|
|||||||||||||||||||||
![]() |
|
|||||||||||||||||||||
![]() |
|
|||||||||||||||||||||
![]() |
|
![]() zur Hauptseite |
© Samuel-von-Pufendorf-Gymnasium Flöha | © Frank Rost im April 2007 |
... dieser Text wurde nach den Regeln irgendeiner Rechtschreibreform verfasst - ich hab' irgendwann einmal beschlossen, an diesem Zirkus nicht mehr teilzunehmen ;-) „Dieses Land braucht eine Steuerreform, dieses Land braucht eine Rentenreform - wir schreiben Schiffahrt mit drei „f“!“ Diddi Hallervorden, dt. Komiker und Kabarettist |
Diese Seite wurde ohne Zusatz irgendwelcher Konversationsstoffe erstellt ;-) |