Einführung in die Programmierung digitaler Rechenautomaten [2., erw. u. neubearb. Aufl. Reprint 2018] 9783111571867, 9783111200101

199 14 28MB

German Pages 388 [396] Year 1963

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

Einführung in die Programmierung digitaler Rechenautomaten [2., erw. u. neubearb. Aufl. Reprint 2018]
 9783111571867, 9783111200101

Table of contents :
Vorwort
Inhaltsverzeichnis
1. Einleitung
2. Über die Notierung von Programmen
3. Geradeausprogramm und zyklisches Programm
4. Symbolische Adressen
5. Mehrfach zyklische Programme
6. Die Versorgung von Unterprogrammen mit Parametern
7. Systematische Behandlung der Adressenänderungen
8. Programmübersetzung
9. Maschinenorientierte Sprachen und deren Verhältnis zur Maschinensprache
10. Problemorientierte Sprachen
11. ALGOL
12. Parallelprogrammierung
Schrifttum
Namen- und Sachverzeichnis

Citation preview

GÜNTSCH • D I G I T A L E RECHENAUTOMATEN

EINFÜHRUNG IN DIE PROGRAMMIERUNG DIGITALER RECHENAUTOMATEN

VON

DR. F R I T Z R U D O L F GÜNTSCH ZWEITE,

ERWEITERTE

UND

NEUBEARBEITETE

AUFLAGE

W A L T E R DE G R U Y T E R & CO. VORMALS G.J. GÖSCHEN'SCHE VERLAGSHANDLUNG VERLAGSBUCHHANDLUNG -

GEORG REIMER -

-

J.GUTTENTAG

K A R L J. TRÜBNER -

B E R L I N 1963

V E I T & COMP.

AM

© Copyright 1963 by Walter de Gruyter & Co., vormals G. J. Göschen'sche Verlagahandlung — J. Guttentag, Verlagsbuchhandlung — Georg Reimer — Karl J. Trübner — Veit & Comp., Berlin 30. Alle Rechte, einschl. der Rechte der Herstellung von Photokopien u. Mikrofilmen, vom Verlag vorbehalten. Archiv-Nr. 1236681. — Satz und Druck: Walter de Gruyter & Co., Berlin 30. — Printed in Germany.

Vorwort Die vorliegende zweite Auflage der Einführung in die Programmierung digitaler Rechenautomaten ist vollständig umgearbeitet und dabei wesentlich erweitert worden. Dies hat vor allem zwei Gründe: Einmal gewinnen eine Reihe von Programmierungstechniken, wie die Verwendung problemorientierter Sprachen oder die Parallelprogrammierung immer größere praktische Bedeutung, so daß auch ein einführendes Buch mit dem wachsenden Stoff Schritt halten muß. Zum zweiten sind seit dem Erscheinen der ersten Auflage eine Reihe kürzerer und in ihrer Stoffwahl verhältnismäßig begrenzter deutschsprachiger Einführungen in die Programmierungstechnik — teils als selbständiges Buch, teils als Teile von Einführungen in das Gesamtgebiet der Digitalrechenanlagen — erschienen. Daher glaube ich, daß ein gewisses Bedürfnis für ein etwas umfassenderes Programmierungsbuch vorhanden ist. Gleichzeitig konnte ich bei dieser Gelegenheit die von manchen Kritikern zu Recht bemängelte übergroße Knappheit einiger Teile der ersten Auflage mildern. Als wichtigste Erweiterung gegenüber der ersten Auflage sind einige Kapitel über nicht maschinengebundene Programmsprachen lind über Parallelprogrammierung hinzugekommen. Die Darstellung der problemorientierten Sprache wurde konsequent auf ALGOL ausgerichtet, so daß die vorliegende Schrift nicht nur eine elementare Einführung in ALGOL 60 enthält, sondern in ihrer ganzen Anlage und Terminologie auf diese Sprache ausgerichtet wurde. Bei der Auswahl der deutschen Terminologie habe ich versucht, im besonderen Maße die im Fachnormenausschuß für Informationsverarbeitung im Deutschen Normenausschuß bisher erarbeiteten vorläufigen Ergebnisse zu benutzen. Bei der Darstellung der Parallelprogrammierung kam es mir darauf an, die vielfältigen und neuartigen Probleme dieses noch jungen Arbeitsgebietes, dessen zukünftige praktische Bedeutung kaum überschätzt werden kann, aufzuzeigen. Gerade bei diesen Teilen des Buches zeigt sich jedoch, daß die auch in der zweiten Auflage mit gutem Grund als Beispiel-Maschine beibehaltene Z 22 bei einer weiteren Ausdehnung des Stoffes, insbesondere auf die in der kommerziellen Datenverarbeitung außerordentlich wichtigen Einund Ausgabevorgänge, nicht mehr ganz genügt. Daher habe ich die Ein- und Ausgabeorganisation im Rahmen der Parallelarbeit nur grundsätzlich be-

Vorwort

6

handelt, ohne auf die praktischen Systeme der Ein- und Ausgabe von Magnetbändern, Lochkarten usw. einzugehen. Ich habe mich aber trotzdem bemüht, durch die Wahl der Programmbeispiele (Platzbuchung, PostscheckGebühren, Sortierverfahren, Listensuchverfahren u. ä.) auch den an der kommerziellen Datenverarbeitung interessierten Lesern gerecht zu werden. Bei der Behandlung der Z 22 selbst habe ich gern Herrn Professor J. Dörrs Ratschlag befolgt, den Befehlscode von vornherein stärker der echten Z 22 anzupassen. Das äußert sich vor allem in der Behandlung der G-Befehle. Weiter habe ich einem Hinweis Herrn Professor W. Haacks folgend bei der symbolischen Adresse die Konvention des Berliner-Codes übernommen. Das vorliegende Buch ist zweifellos kein vollständiges Lehrbuch der Programmierungstechnik, und ich muß daher zur Vertiefung und Ergänzung auf die vielfältige Zeitschriften-Literatur verweisen. Ich möchte jedoch daneben ausdrücklich auf die — zwar sehr knappe —- aber außerordentlich präzise und reichhaltige Darstellung von H. Bottenbruch im Taschenbuch der Nachrichtenverarbeitung [1] hinweisen, in der eine Reihe von hier nur elementar behandelter Techniken genauer und vollständiger beschrieben ist. Mein besonderer Dank gilt Herrn Dr. W. Händler in Saarbrücken und seinen Mitarbeitern, Herrn Dipl.-Math. •/. Schneider und Herrn cand. math. Dieter Jurksch, für viele wichtige Anregungen und Hinweise sowie für die mühevolle Überprüfung und teilweise Neugestaltung sämtlicher Programmbeispiele. Ohne diese wesentliche Hilfe wäre es für mich ein praktisch aussichtsloses Unterfangen gewesen, das Manuskript in einer vernünftigen Zeitspanne einigermaßen fehlerfrei zu erstellen. Mein Dank gilt darüber hinaus Herrn Dipl.-Math. K. Friedrich in Berlin für einige interessante Ratschläge, sowie den Herren P. Aust und Dipl.-Math. H. Kampl in Konstanz für ihre Hilfe beim Korrekturlesen und bei der Fehlersuche in den Programmbeispielen. Weiter möchte ich der Firma Telefunken für die Genehmigung danken, diese Schrift zu veröffentlichen. Es ist mir eine angenehme Pflicht, an dieser Stelle festzustellen, daß nicht zuletzt die vielseitigen und interessanten Aufgaben, mit denen ich es bei dieser Firma zu tun habe, auch für die vorliegende Arbeit Anregung und Grundlagen bilden. Dem Verlag de Gruyter gilt mein besonderer Dank für die überaus angenehme Zusammenarbeit an dieser wegen der nicht enden wollenden Korrekturen und des komplizierten Satzes schwierigen Publikation. Konstanz, April 1963

F. R. G ü n t s c h

Inhaltsverzeichnis Seite

Vorwort 1

Einleitung 1.1 1.2 1.3 1.4

2

3

5 Die verschiedenen zur Vorbereitung der Rechnung erforderlichen Schritte Programmsprachen und Flußdiagramme Kurze Beschreibung einer programmgesteuerten digitalen Rechenanlage Eine kurze Beschreibung der Z 22 1.41 Die technische Realisierung der Hauptteile der Z 22 1.42 Die Zahlendarstellung im Innern der Z 22 1.43 Der Befehlscode der Z 22

9 9 11 16 18 19 22 28

Ü b e r die Notierung von Programmen

32

2.1 2.2 2.3 2.4

32 33 36 37

Einige oft benutzte Abkürzungen Der Befehlscode Befehlsfolgen Das Flußdiagramm

Geradeausprogramm und zyklisches P r o g r a m m 3.1 3.2

Geradeausprogramme Zyklische Programme 3.21 Zyklen mit einer festen Anzahl von Durchläufen 3.22 Zyklen mit einer variablen Anzahl von Durchläufen

44 45 102 103 123

4

Symbolische Adressen

128

5

Mehrfach zyklische Programme

137

Die Versorgung von Unterprogrammen mit Parametern

156

6

6.1 6.2 6.3 7

Geschlossene Unterprogramme, die nicht selbst weiteren Unterprogrammen übergeordnet sind Verschachtelte Unterprogramme Rekursive Unterprogrammtechnik

159 180 188

Systematische Behandlung der Adressenänderungen

192

7.1 7.2

192 193 194

Klassifizierung der Änderungen nach Goldstine und von Neumann . Die Durchführung der Änderungen erster Art 7.21 Durchführung der Änderungen erster Art während der Eingabe . 7.22 Durchführung der Änderungen erster Art unmittelbar vor der Ausführung der zu verändernden Befehle

197

8

Inhaltsverzeichnis Seite

7.3

7.4

7.5

8

9

11

12

205 213 214 216 218 226 226 228 229 234

Programmübersetzung

237

8.1 8.2 8.3

238 249 252

Hauptanwendungen für Übersetzungsprogramme Interpretative Programme Erzeugende Programme

Maschinenorientierte Sprachen und deren Verhältnis zur Maschinensprache 253 9.1 9.2 9.3 9.4 9.5

10

Durchführung der Änderungen zweiter Art 7.31 Automatische Blocktransporte 7.32 Ablaufnotierung 7.33 Nachfolgende Adressensubstitution 7.34 Besonderheiten bei verschachtelten Unterprogrammen Die Durchführung der Änderungen dritter Art 7.41 Adressenfortschaltung 7.42 Mehrfach-Indizierung 7.43 Induktiv verarbeitete Unterprogramm-Parameter Besonderheiten bei Pestspeichern

Aufgaben der machinenorientierten Sprache Der interne Befehlscode der Z 22 Eine maschinenorientierte Sprache für die Z 22 Die Übersetzung symbolischer Adressen Der Aufruf von Unterprogrammen

253 256 274 283 284

Problemorientierte Sprachen

291

10.1 Operative Sprachen 10.11 Formel Übersetzung 10.12 Die verschiedenen Verfahrenssprachen 10.2 Deskriptive Sprachen 10.3 Vereinheitlichung der Sprachen.

292 292 302 304 307

ALGOL

311

11.1 Allgemeines 11.2 Die ALGOL-Syntax 11.21 Die Metasprache von Backus 11.22 Das vollständige syntaktische Schema

311 318 319 320

Parallelprogrammierung

321

12.1 12.2 12.3 12.4 12.5

321 327 336 353 358

Simultanarbeit und Zeitmultiplexbetrieb Ein- und Ausgabe, Programmunterbrechung Verteilung Programmunterbrechungen 2. Art Vertikale Parallelarbeit

Schrifttum

363

Namen- und Sachverzeichnis

377

1 Einleitung 1.1 Die verschiedenen zur Vorbereitung der Rechnung erforderlichen Schritte Jede umfangreiche numerische Rechnung erfordert eine ausführliche Vorbereitung. Unabhängig von der Art der Aufgabenstellung und unabhängig davon, ob für die Rechnung gewöhnliche Tischrechenmaschinen oder programmgesteuerte Rechenanlagen eingesetzt werden, können wir diese Vorbereitungen folgendermaßen gliedern: 1. Beschreibung der Aufgabenstellung. Der erste Schritt besteht in einer klaren Formulierung der Aufgabe. In vielen Fällen werden wir nicht in der Lage sein, die Aufgaben unmittelbar zu formulieren, sondern wir werden es mit Zusammenhängen zu tun haben, die überhaupt erst mit einem mathematischen Kalkül erfaßt werden müssen. Es muß ein mathematisches Modell gefunden werden, das es erlaubt, die Aufgabe in einer Weise zu beschreiben, die als Grundlage für eine weitere rechnerische Behandlung geeignet ist. B e i s p i e l : Es soll die Strömung durch das Schaufelgitter einer Turbine berechnet werden. Für die hier vorliegenden physikalisch-technischen Zusammenhänge stehen eine Reihe von mehr oder weniger brauchbaren mathematischen Modellen zur Verfügung. Für bestimmte Zwecke ist es zum Beispiel ausreichend, als mathematisches Bild die ebene, inkompressible, wirbelfreie Strömung zu benutzen. Damit ergibt sich als mathemathische Formulierung eine Randwertaufgabe der ebenen Potentialtheorie. In anderen Fällen besteht der erste Schritt darin, weitschweifige Beschreibungen, die sich der natürlichen Sprache1) bedienen, durch Verwendung der üblichen mathematischen Formelzeichen straffer zu fassen. Dies ist insbesondere bei kaufmännischen Aufgaben der Fall. 2. Beschreibung des numerischen Verfahrens. Ist die Aufgabe formuliert, so müssen wir als nächstes ein numerisches Verfahren aussuchen oder aufx ) Wir nennen liier die gewöhnlichen Sprachen, wie Englisch» Französisch und Deutsch, im Gegensatz zu den Programmaprachen natürliche Sprachen.

10

Einleitung

stellen, mit dessen Hilfe die Aufgabe gelöst werden kann. So ist es zum Beispiel nicht damit getan, eine Aufgabe in Form einer gewöhnlichen Differentialgleichung zu beschreiben. Die Berechnung der Lösung verlangt ein numerisches Verfahren, wie zum Beispiel das bekannte Verfahren von Bunge und Kutta. Als Vorbereitung für die spätere Benutzung dieses Verfahrens bei der eigentlichen Rechnung muß das Verfahren genau formuliert werden. Diese, meist formelmäßige, Notierung eines Rechenverfahrens nennen wir einen Algorithmus1). Er enthält alle zur Lösung der Aufgaben nötigen Angaben, so daß die Rechnung auch durchgeführt werden kann, wenn man die ursprüngliche Aufgabenstellung nicht kennt. Wird beispielsweise das Verfahren von Runge und Kutta algorithmisch notiert, so folgen daraus die zur Lösung der Differentialgleichung erforderlichen Rechenschritte, ohne daß die Differentialgleichung selbst in Erscheinung tritt. Die einzelnen Verfahrensschritte werden üblicherweise im Algorithmus in Form von Gleichungen notiert. Diese Gleichungen sind allerdings nicht wie die üblichen mathematischen Gleichungen, die auch bei der Aufgabenformulierung verwendet werden, symmetrisch, sondern sie haben den Charakter der von Zuse [3], [4] eingeführten Plangleichungen mit einem unsymmetrischen Gleichheitszeichen, dem sogenannten Ergibtzeichen (-*-). Auf diese Weise erhalten die bis dahin statischen Gleichungen einen dynamischen Charakter, das heißt sie beschreiben nicht beliebige Zusammenhänge, sondern Abläufe. B e i s p i e l : Ein numerisches Verfahren möge unter anderem die Berechnung von V

~ (a + xY

für x = 0; 0,2; 0,4 . . . 2,0 erfordern. Betrachten wir diese Gleichung, so können wir nicht ohne weiteres entscheiden, welche der Größen a, x oder y bekannt sind und welche mittels dieser Gleichung berechnet werden sollen. Mit Hilfe des Ergibtzeichens schreiben wir y9
o , den Operationsteil -+- und die Adressen 1 und 2. Es gibt allerdings auch eine Reihe von Befehlen, für die keine entsprechenden Anweisungen auf dem Formular zu finden sind. Das sind z. B. alle Befehle für die Ein- und Ausgabe von Daten sowie die Befehle, die prüfen, ob die Aufgabe gelöst ist, und je nach dem Ergebnis der Prüfung eine Fortsetzung oder den Abschluß des Programms bewirken. 1.4 Eine kurze Beschreibung der Z 22 Es soll hier eine kurze Beschreibung der Z 22 [8] gegeben werden, die als kleiner Universalrechner mit gespeichertem Programm wegen ihrer weiten Verbreitung, insbesondere an deutschen Hochschulen und Universitäten, und wegen ihrer Flexibilität besonders gut als Musterrechner für die später folgenden Programmbeispiele geeignet ist. Sie hat außerdem den Vorzug, ein Dual-Rechner zu sein, so daß gleichzeitig die Besonderheiten dieser wichtigen Rechnerklasse mit erläutert werden können. ') Bei Rechnern mit zeichenweise adressierbaren Speichern muß ein Wort etwas allgemeiner als eine durch einen Befehl gemeinsam gehandhabte Zeichenfolge definiert werden.

Eine kurze Beschreibung der Z 22

19

Auf Seite 17 ist ein grobes Blockschaltbild augegeben, aus dem die Benennung der Hauptteile und die Informations-Verbindungswege zu ersehen sind. 1.41 Die technische Realisierung der Hauptteile der Z 22 Der Speicher besteht aus zwei Einheiten, einer Magnettrommel (als Arbeits- oder Primärspeicher) und einer Magnetkern-Matrix (als Schnellspeicher).

Schreib-und Leseköpfe

Spur 0 — 1

255

Die Magnettrommel ist ein rotierender Zylinder von etwa 18 cm Durchmesser und 30 cm Länge, auf dessen magnetisierbarer Oberfläche die Informationen in einer magnetischen Impulsnotierung untergebracht sind. Auf jedem Umfang stehen 32 Wörter. Die magnetischen Notierungen längs eines Umfanges werden von einem Magnetkopf geschrieben bzw. gelesen. Den zu einem Kopf gehörigen Trommelbereich nennt man eine Spur. I n unserem Beispiel sind auf der Trommel 256 Spuren, also insgesamt 32 • 256 = 8192 Wörter untergebracht. Da die Trommel mit 100 U/sec rotiert, muß man im Mittel 5 ms ( = 1 / 2 Umdrehung) warten, bis ein bestimmtes Wort am Kopf der dazugehörigen Spur erscheint und damit zur Verarbeitung erreichbar ist. Die mittlere Zugriffszeit beträgt also 5 ms. Der Schnellspeicher besteht aus einer sogenannten Ferritkern-Matrix. Das ist eine matrixartige Anordnung von Ringen aus magnetisierbarem Material, bei denen zwei Remanenzzustände, nämlich die beiden gegenläufig ringförmigen Magnetisierungen, stabil sind. Sie werden zur Speicherung von binären Informationen (also etwa der Ziffern 0 und 1) verwendet. Der Kernspeicher enthält 16 Zellen mit sehr geringer Zugriffszeit. E r dient als schneller Zwischenspeicher f ü r oft benutzte Wörter und k a n n auf diese Weise verhindern, daß die große Zugriffszeit der Trommel den Programmablauf unvernünftig lange aufhält. 2'

20

Einleitung

Diese 16 Schnellspeicherzellen sind zum Teil durch besondere Inhalte und Funktionen festgelegt. So enthält die Schnellspeicherzelle 0 stets eine 0 und die Zelle 1 eine 2. Die Zelle 2 wird dazu benutzt, um das Vorzeichen einer dorthin transportierten Zahl zu prüfen, während die Zellen 3 und 4 eine besondere Bedeutung für das Rechenwerk besitzen. Die Zelle 5 hat dagegen eine besondere Funktion für das Leitwerk. Zelle 6 ist eng mit der Durchführung der Rechenoperationen in gleitendem Komma verbunden. Die Schnellspeicherzellen 7 bis 15 haben normale Speicherfunktionen. Über die soeben genannten Schnellspeicherzellen hinaus gibt es eine sogenannte Schnellspeichererweiterung auf 32 Zellen. Aber auch im Adressenbereich 16 bis 31 sind einige Speicher durch Sonderfunktionen festgelegt: Zelle 16 ist mit Zelle 5 identisch, Zelle 17 hat eine besondere Funktion für das Bedienungspult, während die Zellen 19 und 20 mit der Ein- und Ausgabe zu tun haben. Die Zellen 21 bis 31 stehen wieder als normale Schnellspeicher zur Verfügung. Die Informationsdarstellung ist, wie wir gesehen haben, im Speicher binär. Das gilt für die gesamte Rechenmaschine. Informationen, die nicht wie die einzelnen Stellen einer Dualzahl ohnehin binär sind, müssen beispielsweise in folgender Form nach einem bestimmten Code als Kombination von binären Angaben aufgebaut (binär verschlüsselt) werden.

Eine kurze Beschreibung der Z 22

Beispiel für eine binäre Notierung

Informationsart Dualzahl Dezimalziffern:

Buchstaben:

21

10110 0 1 2 3 4 5 6 7 8 9 A B C D

10110 0000 0001 0010 0011 0100 0101 0110 Olli 1000 1001 Fernschreibcode (Pentaden): 11000 10011 OHIO 01101

Dualcode (Tetraden):

Das Leitwerk enthält im wesentlichen die folgenden drei Register: Das Befehlsregister (BR), das Befehlszählregister (BZ) und das Steuerregister (SR). Jedes dieser Register kann einen Befehl aufnehmen. Die Befehle werden aus dem Speicher über den Schalter E in das Leitwerk transportiert und im Befehlsregister abgelegt. Zur Ausführung wird der Befehl in das Steuerregister übernommen. Im Steuerregister werden die verschiedenen zur Ausführung des Befehls benötigten Steuersignale ausgelöst. Insbesondere werden die Schalter E, C, N usw. gestellt und dem Speicher die Adressen der durch den Befehl betroffenen Speicherzellen mitgeteilt. Auf der anderen Seite werden aus dem Rechenwerk Angaben (insbesondere Vorzeichen) über die in den Schnellspeichern 2, 3 und 4 stehenden Zahlen nach SR übertragen. Diese Angaben bedingen die Ausführung des Befehls in einer Weise, die im Befehlscode näher beschrieben ist. Mit Hilfe eines besonderen Befehlswortes, das ständig zwischen dem Befehlsregister und dem Befehlszählregister kreist, wird bewirkt, daß die Be-

22

Einleitung

fehle in der Reihenfolge, in der sie im Speicher stehen, ins Leitwerk abgerufen werden. Dazu ist ein ständiges Fortschalten der Adresse notwendig. Dies wird von dem zwischen B R und BZ liegenden Addierwerk ( + ) übernommen (Steuerung der Befehlsfolge). Eine besondere Leitung f ü h r t über den Schalter F von BZ in den Schnellspeicher 5, den Speicher für die sogenannte Ablaufnotierung. Wie wir später sehen werden, dient dies dazu, bei Programmverzweigungen eine einfache Rückkehr zur Verzweigungsstelle zu ermöglichen. Bis auf die Übernahme der Befehle von B R nach SR erfolgen alle Transporte in Serie-, das heißt, die binären Elemente eines Wortes werden zeitlich nacheinander auf einem Kanal übertragen. Im Gegensatz dazu werden beim (schnelleren) Paralleltransport diese Elemente gleichzeitig auf mehreren Kanälen übertragen. Das Rechenwerk besteht aus dem Addierwerk und zwei Registern, die mit den Schnellspeicherzellen 3 und 4 identisch sind. Dem rechten Eingang des Addierwerks (A, I) können über den Schalter A Wörter aus dem Speicher und über den Schalter C Wörter aus dem Befehlsregister zugeführt werden. Dieser Zugang kann über das Komplementwerk S negiert werden, so daß im Addierwerk bei Bedarf an Stelle der Addition eine Subtraktion ausgeführt wird. Der linke Zugang des Addierwerks ist im allgemeinen mit dem Akkumulator (Schnellspeicher Nr. 4) verbunden. Beim Transport vom Akkumulator zum Addierwerk kann jedes Wort nach links bzw. rechts verschoben oder gelöscht werden (L, R, N). Der Summenausgang des Addierwerks f ü h r t immer zum Akkumulator. Ein weiterer Weg f ü h r t vom Akkumulator über den Schalter U zum Speicher. Die besonderen Funktionen der Schnellspeicher 2, 3, 5 und 6 werden weiter unten bei der Erläuterung des Befehlscodes deutlich. Zur Eingabe dient ein mechanischer oder photoelektrischer Lochstreifenabtaster, der seine Informationen über einen kleinen Pufferspeicher und von da aus über das Addierwerk in den Akkumulator abliefert. Die Ausgabe erfolgt aus dem Akkumulator über den Schalter U und den Pufferspeicher auf eine Fernschreibmaschine, an die bei Bedarf ein Lochstreifenstanzer angeschlossen werden kann. 1.42 Die Zahlendarstellung im Innern der Z 22 Innerhalb elektronischer Digitalrechner werden vor allem das Dualsystem (Basis B = 2) und das Dezimalsystem ( B = 10), bei dem jedoch die ein-

23

Eine kurze Beschreibung der Z 22

zelnen Dezimalziffern binär verschlüsselt sind, verwendet. In der Z 22 wird das Dualsystem benutzt 1 ). Die einfachste Zahlendarstellung ergibt sich, wenn jeder Ziffer ein fester Stellenwert zugeordnet wird. Man nennt diese Anordnung eine FestkommaDarstellung (FK). Für die Z 22 gilt in diesem Fall: Stelle Stellenwert

1 2 37

2 2 36

3 . . . 36 2 35 . . . 22

37 21

38 2°

Für die Größe der dargestellten Zahlen z gilt die Beschränkung: | s | < 2 35 Dabei sind mit Rücksicht auf die weiter unten besprochene Darstellung negativer Zahlen die Stellen 1 und 2 nicht benutzt worden. Da in den verschiedenen von der Maschine zu lösenden mathematischen Problemen Zahlen sehr unterschiedlicher Größenordnung vorkommen, fällt dem programmierenden Mathematiker die unangenehme Aufgabe zu, alle Größen so zu normieren, daß sie während des gesamten Rechenganges in der gleichen vorgeschriebenen Größenordnung bleiben. Diese Aufgabe ist nicht nur mühsam und durch Irrtümer gefährdet, sondern setzt zu ihrer vernünftigen Bewältigung auch im voraus gewisse Kenntnisse über das Verhalten von Größen voraus, die erst berechnet werden sollen. Es müssen also erst geeignete Abschätzungen gemacht werden, die nicht immer einfach durchzuführen sind. Um den Programmierer dieser Normierungsarbeit zu entheben, führt man die Zahlendarstellung in gleitendem Komma (GK) ein. Man benutzt im allgemeinen eine sogenannte halblogarithmische Notierung; das heißt: Jede Zahl wird in der Maschine als Zahlenpaar (z, z) dargestellt, z und z haben nun festes Komma und werden Mantisse und Skalenfaktor (oder Exponent) genannt. Mit Hilfe von z und z können die Zahlen als z = z Bz oder in einer ähnlichen Form dargestellt werden. In der Z 22 gilt (mit B = 2) z = z • 2 ? " 6 4 = z • 2*. Dabei nennen wir den um 64 verschobenen Skalenfaktor die Charakteristik z. Durch diese Verschiebung können wir von Skalenfaktoren beiderlei Vor*) Die Elemente des Rechnens mit Dualzahlen (Addition und Subtraktion) werden hier als bekannt vorausgesetzt. Die Benutzung des Dualsystems in programmgesteuerten Rechnern ist ebenso wie die halblogarithmische Zahlendarstellung zuerst bei Zuse zu finden [8], [9],

Einleitung

24

Zeichens auf eine nicht negative Charakteristik übergehen, wenn wir f ü r die Mantisse 31 und f ü r die Charakteristik 7 Stellen nach folgendem Schema vorsehen: Stelle Stellenwert

1 21

2 2«

3 4 31 32 2" 1 2 ~ a . . . 2~ 29 2« Mantisse z

33 25

34 . . .38 2 4 . . . 2°

Charakteristik z

Beschränken wir die Charakteristik auf den Bereich 0 ^ 2 und < 2001 > addiert werden und das Ergebnis nach 2002 transportiert wird. Als nächster Befehl wird < 1027 > genommen, der < 2002 > mit < 2003 > multipliziert und das Ergebnis in 2004 ablegt. (1 + 0)-Adreß-Befehle. Hier ist erst einmal zu bemerken, daß für die Bestimmung des Folgebefehls keine Adresse bereitsteht. Die Befehle werden vielmehr im allgemeinen in der Reihenfolge ausgeführt, in der sie im Speicher stehen. Dies ist eine vernünftige Maßnahme, weil es das einfachste ist, die Befehle in der Reihenfolge zu speichern, in der sie normalerweise bearbeitet werden müssen. Um nun aber nicht auf solche linearen Abläufe festgelegt zu sein, muß ein Befehlstyp geschaffen werden, mit dessen Hilfe die linearen Befehlsfolgen unterbrochen werden können. Das sind die sogenannten Sprungbefehle. Bei Sprungbefehlen wird eine (oder auch mehrere) der Operandenadressen ausnahmsweise zur Bestimmung des Folgebefehls benutzt. Will man sich auf eine Operandenadresse beschränken, so müssen bestimmte Verabredungen über die Behandlung der übrigen Operanden getroffen werden. Normalerweise gilt folgendes: Sollen zwei Operanden durch eine Operation (z. B. Addition) untereinander verknüpft werden, so bestimmt die Operandenadresse einen der beiden Eingangsoperanden (z. B. einen Summanden). Als Aufbewahrungsort für den zweiten Eingangsoperanden wird dagegen ein bestimmtes Rechenwerkregister, der sogenannte Akkumulator, vereinbart. Das Ergebnis wird wieder in den Akkumulator transportiert.

Einleitung

30 Beispiel:

steht der Befehl Operation Bringe Operanden in den Akkumulator Addition Speichere Akkumulatorinhalt nach Sprung nach

Bringe Operanden in den Akkumulator Multiplikation Speichere Akkumulatorinhalt nach

Operandenadresse 2000 2001 2002 1027

2002 2003 2004

Das Programmstück bewirkt das gleiche wie das vorige Beispiel, in dem nur zwei (3 + 1)-Adreß-Befehle vorkommen. Beim (1 + 0)-Adreß-Code wird der Rechner einfacher, aber die Programme werden etwas länger. (2 -f- 0)-Adreß-Befehle. Dieser sogenannte Quellen-Senken-Code besitzt zwei Operandenadressen. Normalerweise werden sie zur Bestimmung der beiden Eingangsoperanden benutzt. Das Ergebnis wird anschließend anstelle eines der beiden Eingangsoperanden zurückgespeichert. Auf diese Weise kann ein Akkumulator entfallen. Dieser Code empfiehlt sich vor allem beim Rechnen mit variabler Wortlänge (vgl. Kap. 9.1). Die Z 22 besitzt wie die meisten Rechenautomaten einen (1 + 0)-AdreßCode. Der Umstand, daß zwei Adressen s und t vorhanden sind, ändert nichts daran, daß hier m = 1 richtig ist, weil im allgemeinen die durch s und t bezeichneten Operanden nicht miteinander verknüpft werden; s und t werden vielmehr wahlweise zur Bestimmung eines Operanden verwendet 1 ). *) Eine Variante der Z 22, die Z 22 R, besitzt allerdings die Eigenschaft, daß alle Schnellspeicher als Akkumulator benutzt werden können, so daß s hier neben t einen gesonderten Operanden bezeichnet. Die Z 22 B h a t also einen (2 + 0)-Adreß-Code.

Einige oft benutzte Abkürzungen

31

Hinsichtlich des Operationsteiles wollen wir lediglich auf eine Besonderheit der Z 22 und einiger verwandter Maschinen gegenüber den übrigen Rechnern aufmerksam machen: Im allgemeinen wird der Operationsteil des Befehls insgesamt verschlüsselt. So kann man z. B. durch eine zweistellige Dezimalzahl hundert verschiedene Operationen darstellen. Dann kann allerdings den beiden Dezimalziffern, aus denen der Operationsteil aufgebaut ist, einzeln keine besondere Bedeutung mehr zugeordnet werden. Zur Systematisierung und Vereinfachung des Befehlscodes bzw. des Leitwerks sind nun die sogenannten analytischen Befehlscodes eingeführt worden. Bei diesen Codes werden alle Operationen nach Möglichkeit so in Teiloperationen aufgelöst, daß die Operation durch eine Kombination solcher Teiloperationen entsteht. So kann z. B. eine Subtraktion aufgelöst werden in 1. den Transport eines Wortes aus dem Speicher in den Akkumulator, 2. die Einschaltung des Addierwerks mit Einspeisung des bisherigen Akkumulatorinhalts in diesen Transportvorgang und 3. die Vorschaltung eines Komplementwerkes, um das Vorzeichen dem aus dem Speicher in den Akkumulator transportierten Zahl vor dem Addierwerk umzukehren. Die so erhaltenen Teiloperationen werden nun nach Möglichkeit so in Gruppen geordnet, daß jede Gruppe nur Teiloperationen enthält, die nicht miteinander kombiniert werden können, während Kombinationen mit den Elementen anderer Gruppen erlaubt sind. Jeder Befehl besteht dann aus Kombinationen von Teiloperationen, die alle aus verschiedenen Gruppen stammen [11]. Bei vollständiger Auflösung der Befehle in ihre Elemente kommen wir zu dem von van der Poel geschaffenen Einzelbit-Code, bei dem jedes Bit1) des Operationsteils im Befehlswort eine eigene, von den übrigen unabhängige Funktionen hat [12], [13], Die Z 22 besitzt im wesentlichen einen solchen Einzelbit-Code. Die einzelnen Binärstellen stellen also kombinierbare Elementarbefehle dar, welche jeweils wichtige Transporte und grundlegende logische Operationen bewirken. Allerdings ist die Handhabung dieses Befehlscodes umständlich. Daher wird grundsätzlich eine maschinenorientierte Sprache und nicht die Maschinensprache benutzt. ') Eine Binirstelle nennt man auch ein Bit. Das Bit (Plural: Bits) darf nicht mit der Informationseinheit bit verwechselt werden.

Shannonschen

32

Über die Notierung von Programmen

Wir wollen im folgenden den Befehlscode einer solchen maschinenorientierten Sprache einführen und schrittweise vervollständigen. Die eigentliche Maschinensprache der Z 22 werden wir in Kapitel 9.2 kennenlernen. 2 Ülber die Notierung von Programmen 2.1 Einige oft benutzte Abkürzungen Hier sollen einige uns zum Teil schon aus der Einleitung bekannte Zeichen zusammengestellt werden, die bei der Notierung von Maschinen-Programmen, insbesondere bei den Programmerläuterungen, und in den Beschriftungen der Flußdiagramme nützlich sind. Die in der algorithmischen Sprache verwendeten Symbole werden jeweils im Laufe der Darstellung eingeführt und später in einem gesonderten Kapitel (11) noch einmal vollständig zusammengestellt. Inhalt des durch n gekennzeichneten Maschinenortes. Beispiel: < 4 0 9 6 > = n Inhalt der Speicherzelle mit der Adresse 4096 ist gleich n. {x}

Der Maschinenort, an dem das Wort x aufbewahrt wird. Beispiel: {n} = 4096 Die Zahl n steht in der Speicherzelle 4096.

x -> n Transport des Wortes x an den Maschinenort n; dabei bleibt, wenn nicht ausdrücklich etwas anderes vorgeschrieben ist, das Wort x an der ursprünglichen Stelle erhalten. Beispiel: n -> 4 Die Zahl JI wird (etwa aus der Speicherzelle 4096) nach Schnellspeicher 4 transportiert. Sie ist nach wie vor in 4096 verfügbar. Rechts von dürfen auch mehrere durch Komma getrennte Größen stehen. Das bedeutet dann, daß das Wort in alle rechts angegebenen örter transportiert wird. Das Ergibtzeichen. Sein Gebrauch wird insbesondere in der algorithmischen Sprache genau geregelt. Es wird aber auch außerhalb der eigentlichen algorithmischen Notierung verwendet und hat dort eine entsprechende Bedeutung: Der Wert des (bei der hier gewählten Orientierung) rechts vom

Der Befehlscode

33

Ergibtzeichen stehenden Ausdrucks wird ermittelt und der links stehenden Größe als Wert zugeordnet. Diese Größe darf dabei auch im rechts stehenden Ausdruck vorkommen. Sie muß dann dort mit dem Wert verwendet werden, den sie vor der durch das Ergibtzeichen bewirkten neuen Wertzuordnung gehabt hat. Beispiele:

a + 3

Angenommen, der Wert von a sei durch eine vorangegangene Wertzuordnung 5, dann wird der Wert des Ausdruckes 5 + 3 = 8 . Dieser Wert 8 wird der Variablen c zugeordnet. Es gilt also fortan c = 8. i

i + 1

Der bekannte Wert von i (z. B. 3) plus 1 ergibt 4. Dieser Wert 4 wird der Variablen i zugeordnet. Es gilt also fortan i = 4. 2.2 Der Befehlscode Will man für einen Rechenautomaten Programme herstellen, so muß man einen bestimmten Befehlscode zugrunde legen. Wir wollen hier als Beispiel eine einfache maschinenorientierte Sprache für die Z 22 angeben. Für die Z 22-Befehle gilt allgemein folgendes: Alle Befehle werden im Trommelspeicher aufbewahrt und bis zum Auftreten eines Sprungbefehls E in der dort stehenden Reihenfolge ausgeführt. Jeder Befehl besitzt einen Operationsteil. Zu diesem Operationsteil kann eine Adresse n hinzukommen, nämlich: entweder eine Schnellspeicheradresse s (siehe Blockschaltbild auf Seite 17) oder eine Trommelspeicheradresse t = 1000 . . . 8000. Wird innerhalb der Maschine mit Adressen gerechnet, so haben diese folgenden Stellenwert: s" = 8 • 213 und V = t Die Striche (" und ') sollen dabei nicht nur den Stellenwert kennzeichnen, sondern auch festlegen, daß diese Zahlen in festem Komma dargestellt sind. Im einzelnen unterscheiden wir folgende Befehlstypen: 1. Ruf befehle Rufbefehle haben keine Adresse. 3 Güntsch, Digitale Rechenautomaten 2. Aufl.

34

Über die Notierung von Programmen

Wirkung

Op.

+ —

X

w M D J

< < <
+ ->4,6 > — < 4 > -> 4,6 > X 4,6 > : 4,6

j/->4,6 — < 4 > -> 4,6 < 4 > ausdrucken nächstes Wort vom Lochstreifen lesen und nach 4 transportieren

Bemerkungen

Ausführung in gleitendem Komma

Ausführung je nach Darstellung des betreffenden Wortes in FK oder GK

Zur Ausführung der Rufbefehle werden die Schnellspeicher-Zellen 3 . . . 10 benötigt. 2. GrundbefeMe Grundbefehle haben stets eine Adresse. Bef. An Un Et

In

Wirkung < 4 > + < w > -> 4 < 4 > -> n -*BR

< 4 > A

-> 4

Bemerkungen Addition in festem Komma Speichern ohne Löschen von < 4 > Sprung auf Befehl < i > , anschließend Ausführung der Befehle in t, t +1, t + 2 . . . Intersektion (stellenweises Produkt von < 4 > und < w > )

Zur Ausführung eines Sprungbefehls wird der Zielbefehl des Sprunges in das Befehlsregister transportiert1). Eine genauere Beschreibung der Vorgänge im Befehlswerk wird in Kapitel 9.2 nachgeholt, dort wird auch die Bedeutung der Namen Rufbefehl und Grundbefehl klar werden. Die Intersektion zwischen zwei Zahlen c = a A b ist das stellenweise Produkt von a und b. Das heißt, in c = a A b erscheint eine 1 an den Stellen wo sowohl a als auch b eine 1 besitzen, sonst eine 0. ') Es darf statt t auch eine Schnellspeicheradresse stehen. Im allgemeinen befindet sich dann in dem aufgerufenen Schnellspeicher wieder ein Sprungbefehl, der auf eine Trommeladresse weiterführt.

Befehlsfolgen

Beispiel:

35

« = 1 0 1 1 0 0 1 1 1 ¿> = 0 0 0 1 1 1 1 1 1 c = a A 6 = 0 0 0 1 0 0 1

1 1

Sie wird zum Ausblenden bestimmter Teile eines Wortes (etwa a) durch ein in einer Maske (etwa b) enthaltenes Bit-Muster benötigt, c = a A b enthält dann in den 1-Stellen von b ein genaues Abbild von a, während an allen übrigen Stellen Nullen stehen. Ein häufig auftretendes Beispiel ist das Ausblenden der Charakteristik aus einem Gleitkommawort. 3. Zusatzzeichen Zusatzzeichen treten in den folgenden Kombinationen mit den Operationszeichen der Grundbefehle auf: Bef. N

NEt NAn, NUn,

Bn1) Tn

Wirkung

Bemerkungen

t-+ BR, 0 ^ 4 -+ 4 < 4 > -> n, 0-s-4

Sprung mit Löschen von < 4 > Bringen Speichern mit Löschen von < 4 >

S

ASn, Sn < 4 > — < w > -> 4 Subtraktion in festem Komma Bei neg. Zahlen Kap. 1.42 NASn, NSn — -> 4 < 4 > A (— < « > ) - * 4 beachten! ISn

C

CAt CBt

+

est CNSt ölt eist

— t — t A t < 4 > A (—t)

t t

4 ->4 ->4 -»4 -> 4 -+4

Befehle mit C als Zusatzzeichen benutzen den Adressenteil als Operanden In diesem Falle liegt t in dem Bereich 0 ^ t < 213

R

ARn SRn

2- 1 < 4 > + < w > - > 4 Multiplikation mit 2~x in FK2) 2- 1 < 4 > — 4 (Rechtsverschiebung)

L

ALn SLn

2 + -»4 2 < 4 > — -> 4

Multiplikation mit 2 in FK (Linksverschiebung)

Die folgenden Bedingungszeichen müssen als spezielle Zusatzzeichen vor den anderen Operationszeichen eines Befehls stehen. *) Soll heißen: Änstelle von SA kann auch B geschrieben werden; Entsprechendes gilt für T, S usw. Beim Bechtsschieben gehen die rechts Ober die Wortgrenze geratenden Stellen verloren. 3»

Über die Notierung von Programmen

36

Die Befehle a; werden nur ausgeführt, wenn die Bedingungen





^ 0 3

Befehl 3

4

Befehl 4

5

Befehl 5

6

Befehl 6

7

Befehl 7

Befehl 7 ist ein unbedingter Sprung.

II 8

Wort 8||

Diese Position (8) wird während des Programmablaufes nicht erreicht. Sie dient nur als Aufbewahrungsort für das Wort Nr. 8.

Erläuterung

Befehl 1 wird während des Programmablaufes unter Umständen verändert. Es wird von Befehl 5 unter bestimmten Voraussetzungen auf Befehl 3 gesprungen. Befehl 5 ist ein bedingter Sprung.

Das Flußdiagramm

37

2.4 Das Flußdiagramm Die von H. H. Goldstine und J. von Neumann [14]1) eingeführten Flußdiagramme dienen dazu, die Strukturmerkmale eines Programmablaufs graphisch darzustellen. Zu diesem Zweck wird jeder Befehlsfolge eine Linie in der Zeichenebene zugeordnet. In diesen Linien werden „Kästchen" eingefügt, die bestimmten Programmelementen entsprechen. Wir wollen für den Aufbau von Flußdiagrammen folgende Elemente benutzen: Allgemeine Anweisung

nt y

Buchstabe

Satzzeichen

In diesem Fall ist das Stellen der Verzweigung mit inbegriffen. Soll das Stellen gesondert bezeichnet werden, so wird das Symbol

f ist gleichbedeutend mit)

benutzt. Der Kasten mit einem Eingangspfeil und einer Ausgangslinie enthält ein Namenpaar xjy. Dabei bezeichnet x (links) die zu stellende Verzweigung und y (rechts) den Zweig y, der durchlaufen wird, wenn das Programm dieses Stellsymbol durchlaufen hat und vor dem Erreichen der Verzweigung nicht ein weiteres, die gleiche Verzweigung betreffendes Stellsymbol mit einer der ersten widersprechenden Stellanweisung durchläuft. Wir werden im folgenden hauptsächlich Dezimalzahlen zur Bezeichnung von Verzweigungen und Zweigen benutzen; so heißt also 3/1: Ausgang 1 der Verzweigung 3. Wir wollen auch zulassen, daß die Namen der Verzweigung und auch des Zweiges nicht fest sind, sondern daß dazu Größen verwendet werden, mit denen gerechnet wird. So kann 3¡k zum Beispiel bedeuten, daß bei Weiche 3 der Zweig k durchlaufen werden soll, wobei k eine Variable ist, deren Wert im Augenblick des Verzweigungsdurchlaufs (und nicht der Stellung) zu be-

40

Über die Notierung von Programmen

nutzen ist. Wird k selbst nur zur Stellung berechnet, so kann die entsprechende Berechnungsvorschrift (im allgemeinen ein arithmetischer Ausdruck) mit in das Stellsymbol hineingeschrieben werden. Allerdings empfiehlt es sich, aus Platzgründen bei längeren Ausdrücken eine gesonderte Anweisung vorzuschalten. Für die Festlegung der Verzweigung gelten (im Gegensatz zur Bestimmung der Zweige) die Werte beim Durchlaufen des Stellsymbols (und nicht der Verzweigung). Beispiel:

1

Auf diese Weise gestellte Verzweigungen werden genauso dargestellt wie die Bedingungsverzweigungen. Nur wird diesmal innerhalb des Kastens anstelle der Bedingung das Stellsymbol mit dem Verzweigungsnamen eingetragen. Die Namen der Ausgänge werden jeweils an die Ausgangslinien geschrieben. Eine zum rechts oben gezeichneten Stellsymbol gehörende Verzweigung kann also folgendermaßen aussehen:

Die oben gezeichnete Stellanweisung verbindet hier beispielsweise für A = 20 und c = 1 den Eingang mit dem Ausgang 2.

Das Flußdiagramm Anschlußstelle

4L m

Dieses Symbol ermöglicht es, Anschlüsse zwischen räumlich entfernten Stellen eines Flußdiagramms ohne direkte Verbindungslinie herzustellen. Es wird vor allem gebraucht, um den Zusammenhang auf verschiedenen Blättern befindlicher Teile eines Flußdiagramms zu kennzeichnen. Wir unterscheiden Ausgangskreise (mit einem, Eingangspfeil) und Eingangskreise (mit einer Ausgangslinie). I n die Kreise werden Namen geschrieben, und jeder Name kommt genau zweimal vor; einmal in einem Ausgangs- und einmal in einem Eingangskreis. Ein solches, durch einen gemeinsamen Namen ausgezeichnetes Kreispaar, steht f ü r eine direkte Verbindung der beiden Kreise durch eine Verbindungslinie. Häufig werden Anschlüsse benötigt, die von mehreren Programmstellen auf einen gemeinsamen P u n k t führen. Da wir eine eineindeutige Zuordnung der Ein- und Ausgangskreise vorschreiben, muß dann der Eingangskreis vervielfältigt werden. Beispiel:

d -+2 0 -»4

2001



9

T

2

PB

6

W T

2004

B

2003

T

2000

B

2003

+

Beginn

2003

8

10 11 12 13 14 15 16 17

Bemerkungen

I wenn d ^ 0 dann dV2->c -» 6,2004 | sonst 0 c 6,2004 [ — a/2 + c

T

6

18

B

2004

19 1020

T

2001

)

2000

— a/2 — c =>zs -»• 2001 Ende

Geradeausprogramm und zyklisches Programm

64

In unserem Programmbeispiel haben wir die Bedingung mit Hilfe eines bedingten Transportbefehls PB n realisiert. In späteren Beispielen werden wir noch andere Möglichkeiten, insbesondere unter Verwendung bedingter Sprungbefehle, benutzen. Wir wollen jetzt in der algorithmischen Schreibweise die Anweisungen etwas erweitern: Zur algorithmischen Sprache: B e d i n g t e A n w e i s u n g e n Genauso wie wir mit Hilfe einer Bedingung Ausdrücke erweitert haben, kann man auch aus einer unbedingten Anweisung eine Wenn-Anweisung machen. Wir schreiben zu diesem Zweck vor die unbedingte Anweisung eine Bedingung. Beispiel: wenn i ä 0 dann v

x + i

Die durch eine Bedingung bedingte Anweisung wird nur ausgeführt, wenn die Bedingung erfüllt ist, sonst wird sie übergangen. Wir können die Wenn-Anweisung noch zu einer bedingten Anweisung erweitern, indem wir hinter die Wenn-Anweisung das Wort sonst und eine AlternativAnweisung folgen lassen, die anstelle der ersten Anweisung ausgeführt wird, wenn die Bedingung nicht erfüllt ist. Beispiel: wenn —.03 = « dann a ^ •—> (a A b ~j c) = 3 > i sonst a

falsch

Diese Alternativ-Anweisung kann selbst wieder bedingt sein. Beispiel: wenn a dann Tk _ 0 p 1 — e? sonst wenn b > 3 dann Tk_ 0

p

1 sonst Tk

0

p

0

Damit ergeben sich im allgemeinen zwei Typen von bedingten Anweisungen : a) wenn B1 dann A1 sonst wenn B2 dann A2 sonst

wenn Bn _ l dann An_1

sonst An; An

+1

Geradeausprogramme

65

b) wenn B1 dann Ax sonst wenn J5, dann Az sonst

wenn Bn_1 dann An _ 1 sonst wenn Bn dann An;An + 1 Darin sind Blt B2... Boolesche Ausdrücke und Av A2.. . unbedingte Anweisungen. Die Ausführungen der bedingten Anweisungen (a) u n d (b) k a n n man so beschreiben: E s werden die Booleschen Ausdrücke Bv B2 . . . der Reihe nach von links nach rechts berechnet bis ein Ausdruck (B() den Wert richtig ergibt. D a n n wird die rechts neben dem folgenden dann stehende Anweisung {Ai) ausgeführt. Darauf wird die Anweisung genommen, die auf die ganze bedingte Anweisung folgt (An+1). (Ist Ai eine der weiter unten (Seite 75) zu besprechenden Sprunganweisungen, so wird s t a t t An+1 das Ziel dieser Sprung-Anweisung als nächste Anweisung ausgeführt.) Liefert keiner der Booleschen Ausdrücke den Wert richtig, so wird im Fall (a) An und anschließend (falls A„ keine Sprung-Anweisung ist) An + j ausgeführt. Im Fall (b) wird die ganze bedingte Anweisimg übergangen, und es wird gleich An+1 ausgeführt. 5.

Programm-Beispiel: Es soll geprüft werden, ob die Determinante an D =

a

21

«12 «13 «22 «23

«31 «32 «33

Null ist. Das Ergebnis soll einer Booleschen Variablen d als Wert zugeordnet werden: =

a) Algorithmische

f richtig, falls D 4= 0 { falsch, falls D = 0

Formulierung:

Die Koeffizienten a, l . . . a 3 3 mögen zu Beginn der folgenden Anweisung bereits bestimmte Werte besitzen. 5 Güntscli, Digitale Rechenautomaten 2. Aufl.

Geradeausprogramm und zyklisches Programm

66

Beginn

Dl D2 D3 Di D5 D d

1,2

x a2 x a,'3,3' x a,2,3 x a , x a. 2,l

Dl D2

X

®1,3 X ®2,2 X «3,1 ' 1,2 x a2, x a„ 3 + Di — (a lfl x a 2 3 x a 3 2 + Z>5); fl +O

Ende b)

Flußdiagramm: 1000

1050

1000

D1 *= a1t1 x a 2i2 x "3,3 + D1 D2 a, 2 x + D2 D3 a, j x a DA a , ) * 3.1 - 03 a D5 «- a , t x 3.3 + D4 D «=-(G,I)* 2,3 X a3.t 4 D5) 1051

1052

1

10»

d -t-1

1055

1056

d 0 dann Sprung nach A7 bedingte Anweisungen: B3: wenn a = b dann Sprung nach 7t sonst Sprung nach 0 oder: wenn a — b dann Sprung nach n sonst a

0

oder: Hauptschritt:

wenn T = 0 dann Beginn x 1 + a; y 0 dann Beginn x0 0; Xi a + c; wenn k = 3 dann y 4 + t sonst x : y 4 + t xe; s xt + 0. 3 x y Ende sonst wenn i = 0 dann s

0 sonst s

xt — 0 . 2 x rj;

Ein solcher Sprung wird in der Weise ausgeführt, daß erst die markierte Anweisung und ihre direkten Nachfolger ausgeführt werden bis das Wort sonst erscheint. Dann wird die hinter dem Wort sonst folgende Anweisung ausgeführt, als ob man vom Anfang der zugehörigen bedingten Anweisung kommend auf dieses sonst gestoßen wäre. Wir wollen nun in einem weiteren Programmbeispiel Verzweigungen auf die soeben erklärte Weise notieren: 6. Programmbeispiel: Im Postscheckdienst gibt es ungefähr 75 Belegarten, für die etwa 15 Arten von Gebühren sowie Kombinationen dieser Gebühren erhoben werden (vgl. [17]). Wir wollen hier ein stark vereinfachtes Gebührenprogramm für eine Auswahl von 17 Belegarten und 11 Gebührenarten aufstellen. Die Gebühren sollen dabei nach folgendem Schema berechnet werden:

Geradeausprogramm und zyklisches Programm

78

Belegart

Abkürzung

Nr. N

Gebührenart

Überweisung

Ü

0

KG

Überweisung mit schriftlicher Benachrichtigung d. Empfängers

ÜsB

1

sB

Auslandsüberweisung

Ausland Ü

2

Ausland Ü

Dauerüberweisung



3



Eilüberweisung

ÜE

4

E

Telegraphische Überweisung

Ütel

5

Ütel

Überweisung mit fernschriftlichem Auftrag

ÜfA

6

fA

Telegraphische Überweisung mit fernschriftlichem Auftrag

Ütel fA

7

Ütel und f A

Scheck

S

8

S

Scheck durch Eilboten im Ortszustellbereich

SBoO

9

S und BoO

Scheck durch Eilboten im Landzustellbereich

SBoL

10

S und BoL

Eilscheck

SE

11

SundE

Eilscheck durch Eilboten im Ortszustellbereich

SE BoO

12

S und E und BoO

Eilscheck durch Eilboten im Landzustellbereich

SE BoL

13

S und E und BoL

Telegraphischer Scheck

Stel

14

Stel

Kassenscheck

KS

15

S

Zahlungsanweisung

ZAnw

16

KG

Geradeausprögramme

79

Die Gebührenarten sind im einzelnen folgendermaßen definiert: KG:

keine Gebühren

sB:

pauschal:

Ausland Ü : mindestens:

0,20 DM 0,30 DM

f ü r jede angefangenen 100 DM bis 1000 DM:

0,10 DM

f ü r jede angefangenen 100 DM bis 10000 DM:

0,05 DM

f ü r jede angefangenen 100 DM bis 100000 DM:

0,04 DM

f ü r jede angefangenen 100 DM über 100000 DM:

0,03 DM

DÜ:

pauschal:

0,20 DM

E:

pauschal:

1,00 DM

Ütel:

bis 50 000 DM:

2,50 DM

f ü r jede weiteren angefangenen 1000 DM:

0,05 DM

fA:

pauschal:

2,50 DM

S:

pauschal:

0,15 DM

zusätzlich Va'Voo des Betrages auf volle Pfennige gerundet BoO:

pauschal:

0,60 DM

BoL:

pauschal:

1,20 DM

Stel:

bis 25 DM:

2,50 DM

über 25 DM bis 500 DM:

3,00 DM

über 500 DM bis 1000 DM:

4,00 DM

f ü r jede weiteren angefangenen 500 DM:

1,50 DM

Wir wollen annehmen, daß die Belegarten-Nummer (N) und der Betrag (B) ganzzahlig sind; der Betrag wird also in Pfennigen ausgedrückt.

a) Algorithmische

Formulierung:

I n die algorithmische Formulierung haben wir eine Anweisung drucken(A) aufgenommen. Sie bewirkt, daß der Wert des arithmetischen Ausdrucks A gedruckt wird. Wir werden auf diesen Anweisungstyp später noch einmal zurückkommen (vgl. K a p . 7.3). Wir wollen in diesem Beispiel annehmen, daß die Variablen N und B bereits vor Eintritt in den folgenden Block als ganzzahlig vereinbart und daß ihnen auch ihre laufenden Werte bereits zugeordnet worden sind.

Geradeausprogramm und zyklisches Programm Beginn G 4

5

Sprung nach 1073

86

Geradeausprogramm und zyklisches Programm

Maschinen-Programm

(Fortsetzung) Befehl

Nummer

Op. 1061 62 63 64 65

1056 ->

1039,1052,1065 ->

1012, 1132 -»•

1084, 1086 ->

Adr.

d BC

4

P AC E

550 1073

66 67 68 69 70 71 72 73 74 75 76 77 78

B S T B d BC

2001 2006 6 2003

AC U SC QQBC QQT E

4150 2002 31 30 2002 1173

79 80 81 82 83 84

B AC T B SC QQE

2002 100 2002 2000 12 1088

85 86

NS QQE

4 1088

87

E

1166

88 89 90

B SC QQE

2000 13 1173

91 1092

NS QQE

4 1173

3

Bemerkungen

550' + 4' ((Ä—10 6 — 1) H-104+ 1)'-^(?'h*4 Sprung nach 1073

4 1 5 0 ' + 3 ' ( ( £ —10 7 —1) -M04+ 1)'^£'^2002

wenn (G — 31) < 0 dann 30'-» G' -> 2002 Sprung nach 1173 (Druck) E 100'-* G' -»2002

wenn JV #= 12 dann Sprung nach 1088

Sprung nach 1166 (BoO) wenn N =(= 13 dann Sprung nach 1173 (Druck)

Geradeausprogramme Maschinen-Programm

(Fortsetzung) Befehl

Nummer

Op.

1115 -»

1097 ->

1016,1105

1020,1024 ->

Adr.

Bemerkungen

E

1170

94 95 96 97

B S SC PPE

2001 2007 1 1106

98 99

BC T

250 2002

1100 101 102

B SC QQE

2000 7 1173

103 104

NS QQE

4 1173

105

E

1116

106 107 108 109 110 111 112 113 114 115

B S T B d BC

2001 2007 6 2003

AC T E

250 2002 1100

116 117 118 119

BC A T E

250 2002 2002 1173

fA • G'+ 250'-*- G'-> 2002

120 121 122 123 124 1125

B T BC •

87

5

15 2002

Sprung nach 1170 (BoL) Utel wenn B — 5 X 106— 1 ^ 0 dann Sprung nach 1106 250'-*- 0' -> 2002

wenn iV =t= 7 dann Sprung nach 1173 (Druck)

Sprung nach 1116 (fA)

2 5 0 ' + 5' ((B— 5 x 10« — 1) + 10«+ 1)' G' -»• 2002

Sprung nach 1100

Sprung nach 1173 (Druck)

1 5 ' + ( ( B — 1) + 2000 ' + !)'=*. G'2002

88

Geradeausprogramm und zyklisches Programm

Maschinen-Programm

{Fortsetzung) Befehl

Nummer

1022

1138

Op. 1126 127 128

B SC QQE

2000 9 1173

wenn N — 9 < 0 (also • N = 8) dann Sprung nach 1173 {Druck)

129 130

SC PPE

5 1173

wenn N — 1 4 0 (also • N = 15) dann Sprung nach 1173 {Druck)

131 132

AC PPE

3 1079

133 134

SC QQE

1 1166

135

E

1170

136 137 138

B SC PPE

2001 2501 1142

139 140 141

BC T E

250 2002 1173

B SC PPE

2001 2008 1 1149

BC T E

300 2002 1173

B S

2001 2004

142 143 144 145 146 147 148

1145

Bemerkungen

Adr.

149 1150

C

wenn N — 11 ^ 0 (also 2\r=ll v2V=12 v iV=13) dann Sprung nach 1079 {E) wenn N — 10 < 0 (also • N = 9) dann Sprung nach 1166 {BoO) Sprung nach 1170 (BoL), {N = 10) Stel wenn B — 2501 ^ 0 dann Sprung nach 1142

J 250'

2002

Sprung nach 1173 {Druck) wenn B — 5 X 104— 1 ^ 0 dann Sprung nach 1149 J 300'-*-

2002

Sprung nach 1173 {Druck) 1 wenn B —10 5 — 1 ^ 0 [ dann Sprung nach 1156

Geradeausprogramme

Maschinen-Programm

(Fortsetzung) Befehl

TJnmmpir

Op.

1152 ->

1087, 1134 ->

1093, 1135

1004, 1025, 1028, 1078, 1090,1102, 1104, 1115, 1119, 1128, 1130, 1141, 1148,1155,1165, 1169

89

Adr.

Bemerkungen [ wenn B — 105 — 1 0 J dann Sprung nach 1156

1151 152

SC PPE

1 1156

153 154 155

BC T E

400 2002 1173

156 157 158 159 160 161 162 163 164 165

B S T B d BC

2001 2004 6 2008 150

400'+ 150' ( { £ —10®— — l ) + ( 6 Xl0 4 ) + 1)' 2002

AC T E

400 2002 1173

Sprung nach 1173 {Druck)

166 167 168 169

B AC T E

2002 60 2002 1173

170 171 172

B AC T

2002 120 2002

173

B

2002

1174

D

| 400'-#- £'->2002 Sprung nach 1173 {Druck)

BoO Q>.)- 60'-*- 0 ->2002 Sprung nach 1173 {Druck) Q>.f. 120'

BoL G' -> 2002

Druck

G' drucken Ende

Geradeausprogramm und zyklisches Programm

90

Dieses Beispiel zeigt, daß die verschiedenen Fall-Unterscheidungen einen beträchtlichen Teil des Programms ausmachen. Daher sind sowohl in der algorithmischen Sprache als auch im eigentlichen Programm besondere Vorkehrungen für solche Verteil-Vorgänge erforderlich. Zur algorithmischen Sprache: V e r t e i l e r Für Vielfach-Verzweigungen ist der bisher benutzte Mechanismus der Sprung-Anweisungen noch zu schwerfällig. Wir erweitern ihn daher so, daß die in den Sprung-Anweisungen enthaltenen Zielausdrücke nicht nur eine Marke, sondern eine allgemeinere Regel zur Ermittlung einer Marke sein können. Wir wollen daher zulassen, daß Zielausdrücke genau wie arithmetische und Boolesche Ausdrücke durch Bedingungen bedingt werden können. Weiter sollen neben Marken sogenannte Verteiler verwendet werden. Diese Verteiler werden genau wie einfach indizierte Variable bezeichnet und beziehen sich jeweils auf eine gleichlautende Verteilervereinbarung, von der wir gleich sprechen werden. Zuvor wollen wir nur erwähnen, daß auch in Zielausdrücken Klammern benutzt werden. Solche Klammern enthalten dann wieder vollständige Zielausdrücke, die auch bedingt sein dürfen. Beispiele: Marken: 17 A35 Verteiler: T. J t+ 1 Zielausdrücke: wenn a = b dann A35 sonst wenn i = 3 dann Ti

+ l

sonst 17

oder wenn a = b dann (wenn i = 3 dann Ti

+ 1

sonst 17)

sonst v _ J + x dann 2 sonst („ _ (,)• Eine Verteiler-Vereinbarung besteht aus dem Wort Verteiler, auf das der Verteilername mit einem Ergibt-Zeichen und einer Verteilerliste folgt. Eine Verteilerliste ist eine Reihe durch Komma getrennter Zielausdrücke, also im einfachsten Fall eine Reihe von Marken.

Geradeausprogramme

91

Beispiele: Verteiler T -^0,1, B, 17 Diese Verteiler-Vereinbarung enthält in ihrer Verteilerliste die vier Marken 0,1, B und 17. oder: Verteiler X33

A35, wenn a ä 0 dann B sonst 17, 85

Die hier aufgeführte Verteilerliste enthält die Marken A35, den ausdruck wenn a 2: 0 dann B sonst 17 und die Marke 85. Der Zusammenhang zwischen dem Aufruf des Verteilers in einem Zielausdruck und der ausgewählten Marke wird über die Verteilervereinbarung folgendermaßen vermittelt. Tritt in einem Zielausdruck ein Verteiler T A auf, so sucht man die gleichnamige Verteilervereinbarung Verteiler T VI, V2, V3 . . . auf und bestimmt den (ganzzahligen) Wert W des Indexausdrucks A (arithmetischer Ausdruck). I n der Verteilerliste wird nun das W-te Glied VW aufgesucht. Ist VW eine Marke, so ist die Zielbestimmung abgeschlossen. Ist VW dagegen wieder ein Zielausdruck, so läuft das Verfahren weiter, bis endlich eine Marke als Ziel gefunden ist 1 ). Beispiel: Die folgende Anordnung führt zu einem Sprung auf die Marke 4: Verteiler T l,Sa; Verteiler £ 2,3, 4; a 3; Sprang nach T 2 Wir wollen als Beispiel unser 6. Programm-Beispiel noch einmal aufgreifen und darin Verteiler einführen. 7.

Programm-Beispiel:

Die Aufgabe lautet genau wie im 6. Programm-Beispiel: Gebühren-Berechnung im Postscheckdienst. a) Algorithmische

Formulierung:

Bei dem folgenden Algorithmus wollen wir voraussetzen, daß die Variablen B und N erst im vorliegenden Block erklärt werden. Ihre Werte erl ) Ist der Wert eines Verteilers fär eine bestimmte Sprunganweisung in einem besonderen Fall nicht definiert, so wirkt die Sprunganweisung als Leeranweisung (sie wird Übergangen).

92

Geradeausprogramm und zyklisches Programm

halten sie am Anfang der Rechnung durch die bereits auf Seite 71 eingeführte Anweisung leseniy)1). Beginn Verteiler VI

Druck, sB, Ausland Ü, Dl7, E, Ütel, fA, Ütel, S, S, S, S, S, S, Stel, 8, Druck; Verteiler V2 BoO, BoL; Verteiler V3 BoO, BoL, E,E,E; ganzzahlig B,N,G\ lesen(N); lesen(B); 0 « - 0; Sprang nach V1N + x;

sB:DÜ:G*20; Sprung nach Druck-, Ausland Ü:G 13 dann Sprung nach Druck sonst Sprung nach V3N _ 8; ') Im automatisierten Postscheckwesen werden diese Werte im allgemeinen nicht vom Lochstreifen, sondern von den Originalbelegen gelesen, auf die sie vorher mit einer Magnetschrift maschinenlesbar gedruckt worden sind [21].

93

Geradeausprogramme

Stel: 0 c- wenn B ^ 2.5 x 103 dann 250 sonst wenn B ^ 5 x 104 dann 300 sonst wenn B g 106 dann 400 sonst 400 + 150 x ((B — 1 0 5 — 1) - H 5 x *0 4 ) + l ) 5 Sprung nach Druck; BoO-.G «-(? + 60; Sprung nach Druck; BoL:G^G + 120; Sprung nach Druck -, Druck: drucken(G) Ende b)

Flußdiagramm:

Wir wollen der Verteilerform dadurch Rechnung tragen, daß wir die Verzweigungskaskaden in Vielfachverzweigungen umwandeln (Seite 94). c)

Speicheraufteilung: Nummer

anfangs

später

Darstellung

1000 •

1174 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011

Programm

— — —

(10*)' (10 5 )' (10 6 )' (10 7 )' (5 x 10°)' (5 x 104)' E 1009 E 1091 E 1135

N' B' G' FK

Befehle

Geradeausprogramme

d)

95

Maschinen-Programm Befehl

Nummer

Op. 1000 1

J

T

Bemerkungen

Adr.

2000

| N'

2000

2 3

J

T

2001

4

T

2002

5 6 7

B A E

2000 2008 4

1007

8

E

1171

Sprung nach 1171 (Druck)

1007

9

E

1024

Sprung nach 1024 (sB,DU)

10

E

1027

Sprung nach 1027

1007 ->

j

B' 0

2001 ->2002

• Sprung nach 1008 + N'

(Ausland Ü) 1007

11

E

1024

Sprung nach 1024 (DÜ)

1007 ->

12

E

1078

Sprung nach 1078 (E)

1007 ->

13

E

1090

Sprung nach 1090 (Ütel)

1007 ->

14

E

1112

Sprung nach 1112 (fA)

1007

15

E

1116

Sprung nach 1116 (S)

1007 ->

16

E

1116

Sprung nach 1116 (S)

1007 ->

17

E

1116

Sprung nach 1116 (S)

1007 h*

18

E

1116

Sprung nach 1116 (S)

1007

19

E

1116

Sprung nach 1116 (S)

1007 ->

20

E

1116

Sprung nach 1116 (8)

1007 ->

21

E

1134

Sprung nach 1134 (Stel)

1007

22

E

1116

Sprung nach 1116 (S)

1007

1023

E

1171

Sprung nach 1171 (Druck)

96

Geradeausprogramm und zyklisches Programm

Maschinen-Programm (Fortsetzung) Befehl

Nummer Op.

1009,1011 h- 1024 25 26 1010

1030

27 28 29 30

B S SC PPE

31 32 33 34 35 36 37

B T B ö

38 39 40 41 42 43 44 45 46 47 48 49 50

1041

BC T E

51 52 53 1054

BC

Adr. 20 2002

Bemerkungen

20' => G'

2002

sB,DÜ

1171

Sprung nach 1171 (Druck)

2001 2004

Ausland Ü wenn B — 106 — 1 ^ 0 dann Sprung nach 1038

1

1038 2001

6 2003

10' ( ( B — 1) -h 104 + 1)' ->G' ^ 4

10

E B S SC PPE

1072

B S T B

2001

Sprung nach 1072

2001

2005 1

wenn B — 10® — 1 ^ 0 dann Sprung nach 1051

1051 2004 6 2003

4

BC tu AC E B S SC PPE

100 1072 2001 2006 1

1064

Sprung nach 1072 wenn B —107 — 1 ^ 0 dann Sprung nach 1064

Gíeradeausprogramme

Maschinen-Programm

(Fortsetzung) Befehl

Nummer

1054

1037, 1050, 1063

1012, 1131 1132, 1133

->

97

Op.

Bemerkungen

Adr.

1055 56 57 58 59 60 61 62 63

B S T B d BC

2001 2005 6 2003

AC E

550 1072

64 65 66 67 68 69 70 71 72 73 74 75 76 77

B S T B ö BC

2001 2006 6 2003

AC U SC QQBC AC T E

4150 2002 30 0 30 2002 1171

78 79 80 81 82 83

B AC T B SC QQE

2002 100 2002 2000 12 1171

1

SC PPE

2 1171

1 wenn N '¡L 14 dann J Sprung nach 1171 (Druck)

84 1085

7 Güntsch, Digitale Rechenautomaten 2. Aufl.

5 5 0 ' + 4' ( ( £ — 1 0 6 — 1) v l O 4 + 1)' 6' -> 4

4

Sprung nach 1072

4150' + 3'((B — 107 — 1) 104 + 1)' ^ G' -> 2002

3

wenn G — 30 < 0 dann 30' 2002 Sprungnachll71 (Druck) G' + 100' =>•(?'-»• 2002 wenn N < 12 dann Sprungnachll71 (Druck)

98

Geradeausprogramm und zyklisches Programm

Maschinen-Programm

(Fortsetzung) Befehl

Nummer

1013

1111

1093

1014, 1101

->•

Op.

Bemerkungen

Adr.

1086 87

A E

2010 4

88

E

1164

89

E

1168

90 91 92 93

B S SC PPE

2001 2007 1 1102

94 95 96 97 98

BC T B SC QQE

250 2002 2000 7 1171

99 1100

NS QQE

4 1171

101

E

1112

102 103 104 105 106 107 108 109 110 111

B S T B Ô BC

2001 2007 6 2003

P AC T E

250 2002 1096

112 113 114 1115

BC A T E

250 2002 2002 1171

5

wenn N = 12 dann Sprung nach 1164 (BoO) wenn N = 13 dann Sprung nach 1168 (BoL) Ütel wenn B — 5 x 10® — 1 ^ 0 dann Sprung nach 1102 250'

G' -> 2002

wenn N =)= 7 dann Sprungnachll71 (Druck)

Sprung nach 1112 (fA)

250' + 5' ((B — 5 x 10 6 — 1) -h 104 + 1)' G' ->2002

Sprung nach 1096 G' + 250' -+G'

fA 2002

Sprung nach 1171 (Druck)

Geradeausprogramme

Maschinen-Programm

(Fortsetzung) Befehl

Nummer

1014, 1015, 1016, 1017, 1019, 1020, 1022

1021

1136 ->

99

Op.

Bemerkungen

Adr.

1116 117 118 119 120 121 122 123 124

B T BC

2001 6 2000

AC T B SC QQE

15 2002 2000 9 1171

125 126

SC PPE

5 1171

1 j

wenn N — 1 4 S: 0 (also N = 1 5 ) dann Sprung nach 1171 (Druck)

127 128

A E

2011 4

1 J

wenn N — 9 dann Sprung nach 1169 (BoO)

129

E

1164

130

E

1168

131

E

1078

132

E

1078

133

E

1078

wenn IV = 11 v N = 12 v IV = 13 dann Sprung nach 1078 (E)

134 135 136

B SC PPE

2001 2500 1140

Stel wenn B — 2501 ä 0 dann Sprung nach 1140

137 138 139

BC T E

250 2002 1171

140 141 142 1143

B S SC PPE

2001 2008 1 1147

S 15' + ((B — 1) 2000 + 1)' 0' -> 2002

wenn N — 9 < 0 (also N • = 8) dann Sprung nach 1171 (Druck)

wenn N = 10 dann Sprung nach 1164 (BoL)

1 ,

250'

G' -> 2002

Sprung nach 1171 (Druck) wenn B — 5 x 104 — 1 S: 0 dann Sprung nach 1147

100

Geradeausprogramm und zyklisches Programm

Maschinen-Programm (Schluß) Befehl

Nummer

1143 ->

1150 ->

1088, 1129 ->

1090, 1131 1008, 1023,1026, 1077,1083,1085, 1098, 1115,1124, 1126,1139, 1146, 1153, 1163,1167

Op. 1144 145 146

BC T E

300 2002 1171

147 148 149 150

B S SC PPE

2001 2004 1 1154

151 152 153

BC T E

400 2002 1171

154 155 156 157 158 159 160 161 162 163

B S T B 2002

Sprung nach 1171 (Druck) • G' + 120'

G'

BoL 2002 Druck

0' drucken Ende

Geradeausprogramme

101

Wir haben bisher für die Realisierung der Verzweigungen mit Maschinenbefehlen bedingte Befehle, insbesondere bedingte Sprungbefehle, benutzt, bei denen die Bedingungen — entsprechend dem Befehlscode der Z 22 — von den Vorzeichen des Inhaltes von Schnellspeicher 2 und 4, also zweier Rechenwerksregister, abgeleitet werden. Wir wollen darauf hinweisen, daß in der Rechenmaschinentechnik noch verschiedene andere Möglichkeiten vorgeschlagen und realisiert worden sind, um Befehle zu bedingen. So ist zum Beispiel bei der Z 22, wie wir im Kap. 9.2 noch näher ausführen werden, die Möglichkeit vorgesehen, Befehle durch den Inhalt der niedrigsten Stelle des Schnellspeichers 3 zu bedingen. Weiter kann man bei manchen Rechnern Bedingungen von außen vorgeben. Man sieht zu diesem Zweck etwa am Bedienungspult adressierbare Handschalter vor, die von bestimmten Befehlen abgefragt werden können. Auf diese Weise kann man von außen in das Programm eingreifeil und Verzweigungen veranlassen (zum Beispiel um die Schrittweite in einem numerischen Integrationsverfahren dem Gang der Lösung anzupassen) 1 ). Eine andere Art von Bedienungseingriff ist ein durch einen Handschalter bedingter Stop. Bei der Z 22 ist ein solcher Stop-Befehl dadurch realisiert, daß der gewöhnliche Stop-Befehl (Z), mit der Schnellspeicher-Adresse 17 verbunden, die Abfrage eines Handschalters am Bedienungspult bewirkt. Ist dieser Schalter eingelegt, so hält die Maschine bei Z 17. Sonst übergeht sie diesen Befehl. Eine solche Einrichtung ist besonders beim Ausprüfen neuer Programme sehr nützlich. Zu diesem Zweck werden im Programm an den interessanten Stellen Befehle Z 17 eingestreut, und das Programm wird mit eingelegtem Handschalter gefahren. Dann läuft das Programm jeweils abschnittweise bis zu dem Stopbefehl, und wir können jedesmal nachprüfen, ob es bislang ordnungsmäßig abgelaufen ist. Eine andere für das Ausprüfen neuer Programme sehr nützliche Einrichtung ist der insbesondere bei Dezimalrechnern verbreitete sogenannte Adressen-Stop. Bei diesem wird am Bedienungspult eine Adresse eingestellt, und das Programm läuft dann jeweils, bis es die gewählte Adresse erreicht hat, und hält dort an. Der Adressen-Stop hat gegenüber den durch Handschalter bedingbaren Stop-Befehlen den Vorteil, daß die Programme keine für den eigentlichen Programmablauf zumindest überflüssigen Stop-Befehle zu enthalten brauchen. x ) Bei der Z 22 kann zu diesem Zwekc folgende Einrichtung vorgesehen werden: Am Bedienungspult wird eine Gruppe von fünf binären Handschaltern angebracht. Durch einen weiteren Handschalter kann man nun erreichen, daß der eigentlich für den Lochstreifenleser gedachte Lesebefehl statt einer Fünf-LochKombination, die Kombination der fünf Handschalterstellungen abliest und in das Rechenwerk bringt. Dort können die einzelnen Schalterpositionen mit den gewöhnlichen Bedingungen ausgewertet werden.

102

Geradeausprogramm und zyklisches Programm

Eine weitere Vorrichtung, mit deren Hilfe im Rechner Verzweigungen organisiert werden können, sind Merkspeicher, in denen jeweils nur ein Bit abgelegt wird und auf die sich wiederum bedingte Befehle beziehen. I n diesen Merkspeichern kann man Vorzeichen oder andere Stellinformationen für Verzweigungen aufheben. Dies ist sehr nützlich, wenn die Stellgrößen im Rechengang anfallen, bevor die zugehörigen Verzweigungen wirklich durchlaufen werden. Man braucht dann diese Stellgrößen nicht erst im Hauptspeicher abzulegen und sie bei jedem Durchlauf der Verzweigung zur Prüfung ins Rechenwerk zurückzutransportieren, sondern man kann sie sofort ohne weiteren Transport auswerten.

3.2 Zyklische Programme Wir kommen nun zu den wichtigen zyklischen Programmen und wollen uns vorerst auf solche Programme beschränken, die nur eine Rückführung besitzen. Man spricht dann von einfach zyklischen Programmen. Sie lassen sich in folgende zwei Gruppen aufteilen: 1. Zyklen mit einer festen Anzahl von Durchläufen. Das sind Programme, bei denen die Anzahl der Durchläufe spätestens in dem Augenblick feststeht, in dem die Abwicklung dieser Programme beginnt. 2. Zyklen mit einer variablen Anzahl von Durchläufen. Das sind Programme, bei denen die Anzahl der Durchlaufe von Rechengrößen abhängt, die erst im Verlaufe der Abwicklung der betreffenden Programme gewonnen werden. Man kann die zyklischen Programme auch nach einem anderen Gesichtspunkt ordnen. Man erhält dann folgende Gruppierung: 1'. Induktionszyklen. Das sind Programme, in denen bei jedem Durchlauf eine neue Gruppe von Parametern nach der gleichen Rechenvorschrift verarbeitet wird. Das verlangt bei jedem Durchlauf die Ausführung gewisser systematischer Adressenänderungen. 2'. Iterationszyklen. Das sind Programme, in denen bei jedem Durchlauf die gleichen Parameter nach einer bestimmten Rechenvorschrift verarbeitet werden. In den meisten Anwendungen haben Induktionszyklen eine feste Anzahl von Durchläufen, während Iterationszyklen eine variable Anzahl besitzen.

Zyklische Programme

103

Das muß aber durchaus nicht so sein. Wir werden im folgenden sehen, daß sowohl bei den induktiven als auch bei den Iterationszyklen feste und variable Durchlaufzahlen vorkommen. 3.21 Zyklen mit einer festen Anzahl von Durchläufen

Wollen wir einen Zyklus mit fester Durchlaufzahl organisieren, so müssen wir nach geeigneten Mitteln suchen, um jeweils im Programm festzustellen, ob die vorgesehene Durchlaufzahl bereits erreicht ist. Zu diesem Zweck kann man entweder die Durchläufe zählen oder bei induktiven Zyklen die letzten Variablen mit einem besonderen Kennzeichen versehen. Wir wollen uns zuerst mit der Zählmethode, befassen: Dazu benötigen wir eine besondere Variable, die den Durchlauf steuert, die sogenannte Laufvariable. Es ist üblich, dafür Indizes zu benutzen. Das folgende Programmbeispiel enthält einen iterativen Zyklus, der fünfmal durchlaufen werden soll: 8.

Programm-Beispiel: Newtonsche Iteration 1. Ordnung für x — ^a mit 5 Iterationsschritten f(x) = z 2 — a = 0 x, = x{ Der Anfangswert sei x0 = 1.

a) Algorithmische

Formulierung:

Beginn reell a, Wurzel a; ganzzahlig i ; Feld x0:5;

lesen(a) ; Iterationsschritt:

Schluß: Ende

xi (xi_1-\- ajxi_1)l2; wenn i = 5 dann Sprung nach Schluß; t i + 1; Sprung nach Interationsschritt; Wurzel a

104

Geradeausprogramm und zyklisches Programm

b) Flußdiagramm:

s—n urmj 1000 ' 1001 X, *• 1 1 *• 1 1002 1003 'a Usan |

x,^(x¡., + a/x¡.,)/2 iì 5

11«» i-n

> --[Wurz«t a#x (

^Ende) Das Flußdiagramm muß nun nicht nur über die arithmetischen Vorgänge, sondern auch über das Zählen Auskunft geben. Bei der Aufstellung des eigentlichen Programmes muß neben dem arithmetischen Teil die Zählung und Verzweigung berücksichtigt werden. Es ist am einfachsten, der Laufvariablen einen gesonderten Speicherplatz zuzuordnen und die Verzweigimg mit einem durch den Wert dieser Laufvariablen bedingten Sprung zu bewerkstelligen, c) Speicheraufteilung: Nummer

anfangs

später

Darstellung

x(; Wurzel a a

GK

1000 •

Programm

1017 2000 2001 2002 2

1 —

2 —

i

FK

Zyklische Programme

d)

105

Maschinen-Programm: Befehl

Nummer 1000 1 2 3 1017 ^ 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1013 -> 1018

Op. CNS T

J

Adr. 4 2

T B T B : B

2001 2001 6 2000

B

2002

T PE

2000 1018

B AC T E

2 1 2 1004

+

2000

Bemerkungen — (5' — i') = — 4' —> 2 (also i 1) a vom Lochstreifen lesen und nach 2001 speichern

+ ajx^Jfi

Beginn

^ xt -» 2000

wenn i ^ 5 dann Sprung nach 1018 — (&—%') + 1' ->2 (also % -4= i + 1) Sprung nach 1004 Ende

Unser Beispiel ist gut dazu geeignet, folgenden wichtigen Sachverhalt zu demonstrieren: Soll eine bestimmte Rechnung iterativ oder induktiv mehrmals ausgeführt werden, so kann das zugehörige Programm — etwa in der soeben gezeigten Art — zyklisch oder aber gestreckt notiert werden. Man spricht vom Strecken eines Zyklus, wenn man den mehrfach zu durchlaufenden Programmteil mehrfach aufschreibt und so aus dem zyklischen Programm ein lineares Programm macht. Auf diese Weise wird das Programm natürlich länger als bei zyklischer Notierung. Dem größeren Platzbedarf im Speicher steht aber als Vorteil eine höhere Verarbeitungsgeschwindigkeit gegenüber; denn bei gestreckten Programmen entfallen die Programmteile, die sich mit der Organisation des Zyklus, also mit der Prüfung auf Zyklusende und dem Rücksprung, befassen. Die Anzahl der tatsächlich durchlaufenen Befehle ist also bei gestreckten Programmen gerin-

106

Geradeausprogramm und zyklisches Programm

ger als bei zyklischen Programmen. Daher werden zyklische Programme manchmal (unter Umständen teilweise) gestreckt, wenn es auf höchste Arbeitsgeschwindigkeit ankommt und ein Mehrbedarf an Speicherplatz in Kauf genommen werden kann [22], 2. Übung Das im 8. Programmbeispiel (Seite 103) angegebene Programm soll gestreckt werden. Dabei sollen die Anzahl der durchlaufenen Befehle bei zyklischer und gestreckter Notierung verglichen werden. Das mehrfache Durchlaufen einer Schleife muß nicht notwendig nach dem Schema erfolgen, das dem Flußdiagramm unseres Beispiels zugrunde gelegt wurde. Wir wollen die verschiedenen Möglichkeiten systematisch diskutieren [23]. Jede Schleife hat grundsätzlich folgende Gestalt:

Bei 2 liegt der bedingte Sprung, der das Verlassen der Schleife ermöglicht. a ist der erste mehrfach durchlaufene Befehl. Es ergeben sich zwei interessante Spezialfälle für die gegenseitige Lage von a und z: 1. a = z

Diese Anordnung ermöglicht es, die Schleife zu überspringen.

Zyklische Programme

107

2. a = z -f-1 (zyklisch)

Für den Programmierer ergeben sich noch andere Fallunterscheidungen. Denn es ist auch bei vorgegebener gegenseitiger Lage von a und z nicht gleichgültig, wo a und z innerhalb des zyklischen Programmstiickes liegen. Es ergeben sich die folgenden Fälle: zu (1)

©

®

®

vorangehendes Programmstück: PE

nO.Z

Zyklus'.

1 nachfolgendes Programmstück: zu (2)

©

©

2p r

m

vorangehendes Programmstück:

n Zyklus: nachfolgendes Programmstück:

PE.

I

108

Geradeausprogramm und zyklisches Programm

U I 1 ©

vorangehendes: Programmstück:

Zyklus:

E

nachfolgendes: Programmstück:

IT

fr

IT

Im Programm muß jeweils eine bestimmte Mindestzahl von Sprungbefehlen enthalten sein. Wir nennen sie m. Wird die Schleife n mal durchlaufen, so muß insgesamt eine von n abhängige Mindestanzahl von Sprungbefehlen durchlaufen werden. Wir nennen diese Zahl M{n). In der folgenden Tabelle sind m und M für die interessantesten Fälle, nämlich (I) . . . ( 5 ) aufgeführt:

Fall

m

M(n)

1 2 3

2 2 3

n+2 2n + 1 2n + 2

4

1

n + 1

5

3

2n + 1

Man sieht, daß der Fall 4 in dieser Hinsicht der günstigste ist. Daher wollen wir das 8. Programm-Beispiel [Fall (7)] entsprechend abändern: 9.

Programmbeispiel: a) Algorithmische Formulierung wie im 8. Programmbeispiel (Seite 103).

Zyklische Programme

b)

Flußdiagramm:

c) Speicherauf teilung : Nummer

anfangs

später

Darstellung

1000 Programm 1016 2000

1

Xi\

Wurzel a 2001 2002 2



a

GK

i

FK

2

110

d)

Geradeausprogramm und zyklisches Programm

Maschinen-Programm: Befehl

Nummer 1000 1 2 3 1016 4 5 6 7 8 9 10 11 12 13 14 15 16

Op. CNS T

5 2

J

T B T B

2001 2001

B

2000

B

2002

T B AC T QE

2000 2

+

1017

Bemerkungen

Adr.

) 6'—¿'=5'->2 Beginn j (also i 1) 1 a vom Lochstreifen lesen j und nach 2001 speichern

6

2000

1

2 1004

+ a\x^j)/2 2000

xi

-

. 6'—i' + l'->2 (also i «i= i + 1) wenn i ^ 5 dann Sprung nach 1004 Ende

Wie wir an den letzten beiden Programmbeispielen gesehen haben, nimmt die Organisation der Zählvorgänge innerhalb des Gesamtprogramms einen verhältnismäßig breiten Raum ein. Daher sind für die algorithmische Sprache besondere Vorrichtungen geschaffen worden, um die mit den Zyklen zusammenhängenden Programmteile kurz und übersichtlich zu formulieren. Zur algorithmischen Sprache:

Laufanweisungen

Der Organisation zyklischer Abläufe dienen die sogenannten Laufanweisungen. Laufanweisungen (die wie die übrigen Anweisungen auch mit einer Marke versehen werden können) bestehen aus einer beliebigen Anweisung mit einer vorgestellten Laufangabe1). Die Laufangabe enthält *) Auch hier muß der rekursive Charakter der algorithmischen Sprache beachtet werden. Die durch eine Laufangabe erweiterte Anweisung darf selbst wieder eine Laufanweisung sein, sie darf auch zusammengesetzt oder ein Block sein.

Zyklische Programme

111

Informationen darüber, welche Variable den Zyklus steuert und für welche Werte dieser sogenannten Laufvariablen die gesteuerte Anweisung ausgeführt werden soll. Die Laufangabe ist folgendermaßen aufgebaut: Zuerst kommt das Wort für, dann folgen die Laufvariable mit einem Ergibt-Zeichen und anschließend, jeweils durch Komma voneinander getrennt, die Elemente der sogenannten Laufliste; zum Schluß die Wörter führe aus. Die Lauflistenelemente geben die Werte an, die der Laufvariablen erteilt werden sollen. Sie werden in der Reihenfolge zugeordnet, in der sie von links nach rechts in der Laufliste stehen. Beispiel: für i 0 dann Sprung nach Ausgang1)-, Anw; V^V

+

I;

Sprung nach Prüfung; Ausgang:

NAnw;

Eine dritte Art des Laufdementes dient vor allem der Durchführung iterativer Zyklen mit variabler Durchlaufzahl. Wir werden es im nächsten Kapitel (Seite 127) besprechen. Zum Schluß müssen wir noch klären, welchen Wert V besitzt, nachdem der von V gesteuerte Zyklus abgearbeitet ist. Dafür gilt folgende Regel: Ist Anw zusammengesetzt, so kann darin eine Sprunganweisung enthalten sein, die aus dem Zyklus hinausführt. In diesem Fall behält V den Wert, den es unmittelbar vor Ausführung des Sprungbefehls besaß. Wird der Zyklus dagegen verlassen, weil bei der Prüfung festgestellt wurde, daß die Laufliste abgearbeitet ist, so ist der Wert von V nach Zyklusende nicht mehr definiert. Wie wir schon weiter oben gesehen haben, gibt es sowohl bei Zyklen mit fester wie auch bei Zyklen mit variabler Durchlaufzahl Induktionen und Iterationen. Unser letztes Beispiel enthielt einen Iterationszyklus. Denn das iterierte X{ wurde immer wieder xi_1 genannt und immer an der gleichen Stelle ({#«} = 2000) gespeichert, so daß die RechenVorschrift immer auf eine in der gleichen Speicherzelle stehende Variable angewendet wurde. Wir wollen nun ein einfaches Beispiel für einen induktiven Zyklus vorstellen: 10.

Programm-Beispiel: Skalarprodukt zweier Vektoren (a v a2, ... a10) • (61; b2, ... b10) = c

a) Algorithmische

Formulierung:

Die Felder a und b mögen bereits vor Eintritt in den folgenden Block durch eine Feldvereinbarung Feld a, 6 1 : 1 0 eingeführt worden sein. Außerdem sollen alle Komponenten bereits einen Wert besitzen, wenn das Programm mit der Bearbeitung des folgenden Blockes beginnt. ') Wir führen hier die Vorzeichen-Funktion sign(A) ein, die dem arithmetischen Ausdruck A die Werte + 1, 0 oder — 1 zuordnet, je nachdem, ob der Wert von A > 0, = 0 oder < 0 ist (siehe K a p . 6.1, Seite 171). 8 Güntsch, Digitale Rechenautomaten 2. Aufl.

114

Geradeausprogramm und zyklisches Programm

Beginn reell c; Feld s 0 : 1 0 ; ganzzahlig i ; für i = 1 Schritt 1 bis 10 führe aus st 7 8 9 10 11 12 1013

OK

2019 2020 2021 2

s{, c B 2000

Befehl Op. CNS T B U AC T T [Z T

o ] 6 1 ]

[Z X B

2020

T

2020

+

Bemerkungen

Adr. 10 2 2021 1007 10 1009 2020

Befehl FK

Beginn — ( 1 1 ' — *') = — 10 ^ 2 »

0

1 B{a1) «o

ai x bi +

1007 -»-1009 2020

s{ -»-2020 1 )

) I n diesem Programm haben wir die Leerstellen (1007 und 1010) mit Stop-Befehlen ausgefüllt (ZO und ZI), damit der Rechner bei „ I r r l ä u f e n " aufgehalten wird: Weicht das Programm auf Grund irgendeines Maschinen- oder Programmfehlers vom richtigen "Weg ab, so erreicht es mit einer gewissen Wahrscheinlichkeit eine mit Z n gefüllte Zelle. An dieser Stelle bleibt die Maschine stehen, und die im Leitwerk dann noch vorhandene Adresse n des Stop-Befehls gibt Auskunft darüber, an welcher Programmstelle die Maschine angehalten hat. x

8*

116

Geradeausprogramm und zyklisches Programm

Maschinen-Programm Nummer 1014 15 16 17 18 19 20 21 1022

(Fortsetzung): Befehl

Op. B AC T B AC U AC T QE

Adr. 2 1 2 1007 1 1007 10 1009 1007

Bemerkungen

— ( 1 1 ' — i') + 1 -> 2 • i i + 1 B{ai} + 1'

B{a,}

-> 1007 ^

wenn i 5 10 dann Sprung nach 1007 Ende

Wir sehen, daß bei induktiven Zyklen der Übergang von i auf ¿ + 1 nicht nur einen Zählschritt, sondern auch Adressenänderungen bei all den Befehlen erfordert, die sich auf eine mit i indizierte Variable beziehen. Damit diese Adressenänderung einfach vonstatten gehen kann, müssen diese Variablen im Speicher zweckmäßig angeordnet werden. Am besten ist es, wenn sie äquidistant gespeichert werden: fa+i} = K) + d mit festem ganzzahligem d. In unserem Beispiel war d = 1. Diese einfache Gesetzmäßigkeit für die Adressen der v( ermöglicht es, die Adressen selbst zum Zählen zu benutzen. Damit erübrigt sich das Einrichten eines besonderen Speicherplatzes für den Index i. Wir wollen unser B e i s p i e l entsprechend abändern: 11.

Programm-Beispiel:

Aufgabe und algorithmische Formulierung sowie das Flußdiagramm wie im 10. Programm-Beispiel (Seite 113): Skalarprodukt zweier Vektoren. c)

Speicheraufteilung: Die Speicherliste ändert sich insofern, als der Schnellspeicher 2 nicht mehr benötigt und < 2021 > = B 2020 wird2). Die Abkürzung für einen Befehl x mit der Adresse von a,j werden wir außerhalb der eigentlichen algorithmischen Sprache öfters gebrauchen; genauso das Ergibtzeichen für Befehlsumrechnungen. 8 ) Diese besondere Notierung von B 2020 könnte noch eingespart werden, weil ein Befehl B 2020 im Programm selbst vorkommt.

Zyklische Programme

d)

117

Maschinen-Programm: Befehl

Nummer

Op.

1000

1019

1 2

U

1008

CS T

1006

5

T

2020

6

[Z T

0] 6

[Z X

1]

9 10

B

B{a J

-> 1 0 0 6

0

s0

2020

B{at} B{bt} -*-st

2020

2020

+

12

T

2020

13

B

1006 1

14

AC

15

U

16

AC

17

U

1008

S

2021

QQE

1006

18

1008

a\ x bi +

11

1019

B{bt} 1

10

3

8

Beginn

10

4

7

12.

2021

B CS

Bemerkungen

Adr.

1006

•i +

1

10

B{a{} + 1 ' i B{ai+1} + 10'

B{ai) ^

1006

B{bt}

1008

• wenn i ^ 10 dann Sprung nach 1006 Ende

Programm-Beispiel:

Berechnung eines Polynoms

mit Hilfe des Hornerschen Pol

a) Algorithmische

Schemas

10

=Iatxi ¿=o

Formulierung:

In diesem Programm wird vorausgesetzt, daß a durch eine Vereinbarung Feld ®o: xo und x durch eine Vereinbarung reell x vor Eintritt in den folgenden Block erklärt worden sind. Sie sollen außerdem bereits einen Wert zugeordnet bekommen haben.

Xlg

Geradeausprogramm und zyklisches Programm

Beginn reell p, Pol; ganzzahlig i ; P «10; für i 4= 10 Schritt — 1 bis 1 führe aus p

x x p +

ai_1\

Pol 4= p Ende b)

Flußdiagramm:

c) Speicheraufteilung Nummer

: anfangs

1000 Programm 1015

später

Darstellung

Zyklische Programme

Speicheraufteilung

(Fortsetzung)

Nummer

anfangs

2000 2001

später

Darstellung

ao ai

GK





2010 2011 2012 d)

119

«10

Pol

X

B 2000

Befehl

Maschinen-Programm:

Nummer 1000 1 2 3 4 1013 5 6 7 8 9 10 11 12 13 14 1015

Befehl Op. B AC T B T B X [Z

+

Bemerkungen

Adr. 2012 9 1007 2010 6 2011 0]

B SC U S PPE

1007 1 1007 2012 1005

B T

6 2011

• i « - 10; B{a9} -> 1007 «io ^ V

6

x x p + ««_!

i

6;

i — 1 ; B{ai_1} — 1'

B\ai-i)

B{ai_1}

| wenn i > 0 dann Sprung nach 1005 | p

Pol ->2011

Haben wir in den bisher ausgeführten Programm-Beispielen das Zyklusende immer mit Hilfe eines Zählvorganges bestimmt, so wollen wir nun zeigen, wie man zum gleichen Zweck Markierungen benutzen kann: Manche Maschinen verfügen über die Möglichkeit, bestimmte Wortarten (zum Bei-

120

Gieradeausprogramm und zyklisches Programm

spiel nur Befehle), jedes Wort oder (bei Dezimalrechnern und solchen, die alphanumerische Zeichen gesondert verarbeiten können) jedes Zeichen mit einem oder mehreren Markierungszeichen zu versehen. Solche Markierungszeichen nennt man nach Rutishauser [5] auch Q-Zeichen. Für diese Markierung werden in den betreffenden Wörtern oder Zeichen ein oder mehrere Bits bereitgestellt. Außerdem sind Befehle vorgesehen, mit deren Hilfe man die Markierungszeichen setzen, und andere, mit denen man sie abfragen kann. Das Abfragen geschieht meist mit bedingten Sprungbefehlen, die auf ein Markierungszeichen ansprechen. Haben wir nun induktive Zyklen mit fester Durchlaufzahl vor uns, in denen eine Folge von Größen nacheinander in einer bestimmten Reihenfolge verarbeitet wird, so können wir die letzte Größe mit einem Markierungszeichen versehen und bei jedem Durchlauf prüfen, ob die gerade bearbeitete Größe markiert ist oder nicht. 13. Programm-Beispiel: Aufgabe und algorithmische Formulierung wie im 10. Programm-Beispiel (Seite 113): Skalarprodukt zweier Vektoren. b)

Flußdiagramm:

Zyklische Programme

c)

121

Speicheraufteilung: Nummer

anfangs

später

Darstellung

1000 Programm 1020 2000 2001

2009 2010 2011

2019 2020 2021

«i a2

«10 öi

&10 —

B 2000

GK

s(, c

Befehl

Für dieses Programm-Beispiel wollen wir annehmen, jedes Z 22-Wort verfüge über ein zusätzliches Bit, das zur Markierung benutzt werden kann. Dabei soll diese Markierung außer in den Befehlen, die sieh ausdrücklich darauf beziehen, nicht in Erscheinung treten. Als besondere Befehle für diese Markierung fügen wir vorübergehend ein: /.um: ,

Q ->n (Markierungs-Bit setzen)

[ißx: Der Befehl x wird nur dann ausgeführt, wenn < 4 > Q enthält. Mit (ian wird Q dem bisherigen Inhalt von n zugefügt, und das Wort wieder nach n zurückgespeichert, während ßß eine Bedingung ist, die jedem Befehl (aus Kapitel 2.22 sowie dem Befehl ¡IG) zugefügt werden kann. Außerdem wollen wir noch festlegen, daß bei allen arithmetischen Verknüpfungen das Ergebnis wieder die Marke Q enthält, wenn mindestens einer der Operanden Q enthielt.

122

Geradeausprogramm und zyklisches Programm Maschinen-Programm:

d)

Bei ehl

Nummer

1020

1000 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Op.

Adr.

fia

2009 2019 2021 1007 10 1009 2020

B U AC T T [Z T

0] 6

[Z X B

1]

Bemerkungen «io, Q

j j

b10, Q

2009 -> 2019

B{ai}

->

B{a^

+ 10'

0

Beginn

1007 (i

s0

B{b^

1) 1009

2020

a( x bi + «i.!

2020

2020

+ U /iß E

2020 1021

B AC U AC T E

1007 1 1007 10 1009 1007

wenn s« Q enthält (also i = 10) dann Sprung nach 1021 B{ai}

1'

+ ln

B{at}

/

+ 10'

B{at}

«l 1 11

B{bi}

1007

1009

Ende

1014 ->• 1021 2. Ü b u n g :

I n den Speicherzellen 3000—3999 seien 500 Sortiereinheiten Ei (i = 0,1 ... 499) folgendermaßen abgelegt: 1. Jedes Et besteht aus zwei Wörtern. Das erste enthält das Sortiermerkmal Mi, das zweite die eigentlich zu sortierende Sortierinformation Ii. 2. Zusammengehörige Mi und I i (mit gleichem i) sind jeweils in benachbarten Speicherzellen abgelegt: {h} = {Mt} + 1 = {M „} + 2i + 1 = 3000 + 2» + 1 Sortieren

durch

Ablegen1):

*) Die Misch- u n d Sortierverfahren für Rechenautomaten sind in den umfassenden Arbeiten von C. Boehm [24] (Mischprozesse) und [25] (Sortierprozesse) beschriehen. Dort findet sich auch eine vollständige Literatursammlung.

Zyklische Programme

123

3. Alle Mt (i = 0 , 1 ... 499) sind verschieden und belegen die Zahlen 0', 1', 2' ... 499' in beliebiger Permutation (der Merhmalsbereich ist 0 bis 499). Die Aufgabe besteht darin, den Speicherbereich 3000—3999 durchzugehen und dabei jedes Ii entsprechend der Größe der zugehörigen Mi im Speicherbereich 4000—4999 so abzulegen, daß die Ei dort (bezüglich der Mi) der Größe nach geordnet sind. 3.22 Zyklen mit einer variablen Anzahl von Durchlaufen

Ist die Anzahl der Durchläufe nicht vorher bekannt, so können wir das Ende des Zyklus nicht durch einen Zählvorgang ermitteln. Es müssen dann andere Kriterien angewendet werden. Typische Beispiele für Zyklen mit variabler Durchlaufzahl sind Iterationen, bei denen die Genauigkeit der Näherung das Abbrechen des zyklischen Verfahrens bewirkt (iterative Zyklen) oder das Durchsuchen von Listen. Hier entscheidet das Auffinden einer Listenposition, ob der Zyklus unterbrochen wird oder nicht (induktive Zyklen). Bei iterativen Zyklen mit variabler Durchlaufzahl kann eine besondere Zählvariable (Index) häufig entfallen, wenn nicht außer dem Ergebnis auch die Anzahl der Iterationsschritte, die zu dem Ergebnis geführt haben, interessiert. 14.

Programm-Beispiel:

Newtonsche Iteration für x = JIa (vgl. 8. Programm-Beispiel, Seite 103) Xi+1 =

y (Xi+ 57) l Der Anfangswert x0 sei 1, die Genauigkeitsschranke s, und die Anzahl der benötigten Iterationsschritte soll auf keinen Fall 20 überschreiten. a) Algorithmische

Formulierung:

Die variable Durchlaufzahl können wir mit einer Laufanweisung trotz des festen Endwertes (hier 20) zum Beispiel dadurch realisieren, daß wir in die gesteuerte Anweisung eine bedingte Sprunganweisung hineinschreiben, die das Verlassen des Zyklus bewirkt, a und s mögen vor Eintritt in den folgenden Block durch eine Vereinbarung reell a, s erklärt sein und bereits Werte besitzen. Beginn reell Wurzel a, y; ganzzahlig i; Feld x0 . 2 0 ; x0 «s- 1:

124

Gieradeausprogramm und zyklisches Programm

für i 0 Schritt 1 bis 20 führe aus Beginn xi + x y ^ {xt + a/xj)/2; wenn abs((xi+1-—xi)/xi) < s dann Sprang nach Schluß1) Ende; Schluß: Wurzel a y Ende b)

Flußdiagramm:

e)

Speicheraufteilung: Nummer

anfangs

später

Darstellung

1000 •

1019 2000 2001 2002 2003 2004

Programm

a 1 2 s —

GK «¿+i, V, Wurzel a

-

' ) Wir wollen für den Absolutbetrag eines arithmetischen Ausdrucks A die Funktion abs(A)

benutzen.

Zyklische Programme d)

125

Maschinen-Programm: Befehl

Nummer

Op.

1017->1000 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

B T B :

2000 6 2001

B

2001

B

2002

T B

2004 2001

QQE

1020

17 18 19

B T E

2004 2001 1000

+

Bemerkungen

Adr.

+

a/x t )/2 -> xi+1

y ->6,2004



B QQM B

2001 1 %i 2 = 2 3 4 3 = 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 5 = 20 1021

Op.

Adr.

B T B AC T

1042 1005 1005 2 1005 0] 6 2000

[B T B —

QQE

1002

B U AC U SC U U SC U U [B T

1005 1020 1 1025 2 1027 1038 1 1022 1034 0] 6

Befehl

Nummer Op. 9 = 1022 23 24 6 = 25 26 7 27 28 29 30 31 32 33 10 = 34 35 36 37 8 = 38 39 40 41 42 4 = 1 = 1043

[B

Adr. 0]



T [B T [B

1043 0] 6 0]



B : T B T [B

1043 1043 2000 6 0]



B X [B

1043

T E B

2000

+

[Z

0]

3000 0]

Bei den folgenden Beispielen wollen wir uns mit den symbolischen Adressen zufriedengeben. Wir werden ohnehin später Methoden kennenlernen, die uns von der monotonen Arbeit der Adressenzuordnung ganz befreien. 16. Programm-Beispiel: Taylorentwicklung von ex

Symbolische Adressen

135

Es soll eine Näherung gefunden werden, die so genau ist, daß die Differenz zweier aufeinander folgender Teilsummen, bezogen auf die Größe der Teilsummen, kleiner als 10~5 ist. a) Algorithmische Formulierung-. Für die Variable x möge in einem umfassenden Block eine Vereinbarung reell x vorliegen, und x soll bei Eintritt des Programmes in den folgenden Block bereits einen Wert besitzen. Beginn reell U, S, T, i, e hoch x; U*- T^ 1; für i 0, i + 1 solange abs{Tfü) ^ 10~5 führe aus Beginn S U; T x x Tfti + 1); U ^ 8+ T Ende; U e hoch x Ende b) Flußdiagramm:

136 c)

Symbolische Adressen

Speicher-

Nummer

aufteilung:

anfangs

später

Darstellung

1000 Programm 1033 2000 d)

e hoch x

X

GK

Maschinen-Programmteile:

Befehl Op.

Bemerkungen

Adr.

B

.6

U

.1

U T

.2 .3

B

2000

T

6

B

.1

Beginn

1 -> .1 (also i 1 =>• T -> .2 1 8 -> .3

T x x I (i + 1) B

B

+

T ->• .2

+ 1

.2 T + £ ^ U

X U

0)

6,4

.2 .3

U

2

B

.3

wenn QQM B

.8

QQE

.5

I7-S Z7

< lO - 6 dann Sprung nach .5

Mehrfach zyklische Programme

d) Maschinen-Programmteile Nummer 4 =

6 3 2 1 8

= = = = =

Bemerkungen

Adr.

B T B T B

2 .3 .1 6 .6

+

5 =

(Fortsetzung):

Befehl Op.

T E

.1 .7

B T E

2 2000

U

10- 5

8

3

• (i + 1) + 1

• U *> e hoch x

1 [Z [Z [Z

137

o ] 1 ] 2 ]

.1 (also i

i -4- 1)

2000

Sprung auf eine Portsetzung des Programms S T i + 1 Ende

5 Mehrfach zyklische Programme Bislang haben wir uns auf Programme mit einer Rückführung, also auf einfach zyklische Programme, beschränkt. Eine Erweiterung auf den Fall, daß mehrere nicht verschachtelte Zyklen vorliegen, bringt keine neuen Gesichtspunkte. Programme mit nebenstehenden FlußÔ diagrammstrukturen lassen sich bequem durch entsprechende Schnitte auf die bisher behandelten einfach zyklischen Programme zurückführen.

3

Mehrfach zyklische Programme

138

Anders wird das bei verschachtelten Zyklen und nur von diesen wollen wir im folgenden sprechen. Programme mit Flußdiagrammen folgender Art

O

CP

3

Ô ô

verlangen neue Überlegungen, weil die Abwicklung der einzelnen Zyklen nicht mehr voneinander unabhängig ist. Das äußert sich in der algorithmischen Formulierung am sinnfälligsten darin, daß die von einer Laufangabe gesteuerte Anweisung selbst wieder (auch verschachtelte) Laufanweisungen enthalten darf (vgl. Seite HOff.), oder darin, daß man aus einer solchen Anweisimg hinaus auf eine andere Laufanweisung springen darf. Die engste Verkopplung mehrerer Zyklen Hegt dann vor, wenn die Laufvariablen wechselseitig voneinander abhängig sind. Schließlich wollen wir noch bemerken, daß bei mehrfach zyklischen Programmen die einzelnen Zyklen unabhängig voneinander induktiv oder iterativ sein können und eine feste oder variable Durchlaufzahl besitzen dürfen. Insoweit gilt also das im vorigen Kapitel für einfach zyklische Programme Ausgeführte auch hier. Wir wollen als nächstes Programm-Beispiel ein dreifach zyklisches Programm aufstellen, dessen Zyklen alle induktiv sind und eine feste Durchlauf zahl haben. 17.

Programm-Beispiel: Matrizenmultiplikation (a t] ) x (b}ic) = (c»fc)

i,j,k

= 1, 2, ... »

n

Cik = 2 7= 1

a

ifijlc

Mehrfach zyklische Programme

a) Algorithmische

139

Formulierung:

Für den gesamten Programmablauf wollen wir folgendes voraussetzen: Der im folgenden ausführlich aufgeschriebene Block mit der Matrizenmultiplikation sei in einem übergeordneten Block enthalten, an dessen Anfang die Variablen a und b durch eine Vereinbarung Feld a, 1:n erklärt werden und in dem a und b vor Eintritt in die Matrizenmultiplikation ihren Wert erhalten. Damit die in dieser Vereinbarung enthaltene Variable n einen Wert besitzt, setzen wir weiter voraus, daß ein die beiden bisher genannten Blöcke umfassender Block existiert, in dessen Vorspann n durch eine Vereinbarung ganzzahlig n erklärt ist, und in dem n vor Eintritt in den nächsten Block seinen Wert erhält. Beginn ganzzahlig i,j, k; Feld c 1:M

1:n;

reell z; für i

1 Schritt 1 bis n führe aus

für k

1 Schritt 1 bis n führe aus

Beginn z

0;

fürj 3 c

1 Schritt 1 bis n führe aus a it

i, k -

j

x bh k + 2;

2

Ende Ende b) Flußdiagramm: c)

(siehe Seite 140 unten)

Speicheraufteilung:

Wir wollen das Programm so anlegen, daß es für behebige Ordnung n und für beliebige Lage der Blöcke (a11 ... ann), (i» x l ... ö»„) und (c 1 : L ... cnn) im Speicher brauchbar ist, sofern nur vorweg die Parameter n, { o n } , {&n}, { c n } im Programm an den dafür vorgesehenen Stellen gespeichert werden.

Mehrfach zyklische Programme

Nummer

anfangs

später

Darstellung

; ' - ( » + 1)'

FK

1000 • Programm 1062 2 {xiii} = {^11}



— n — 1 (OK) ; x = a,b, c

Mehrfach zyklische Programme

141

d) M aschinen-Programm: Befehl

Nummer

8 =

Op.

Adr.

SN U U T B T B T B T

.4 2 .5 .9 .10 .2 .11 .3 .12 .7

T

.1

2 =

[B T

0] 6

3 =

[B X B

0] .1

Bemerkungen

— n'= j', k', i' — (n + 1)

i

j

Beginn 2, .5, .9

1 ^ K i } -> -2 • B { \ i } -> -3 T{cm}

0

.7

.1

•B{M a-ui x 6;,» + z

.1

+ T B AC T B A T B AC T QE B 7 = r

.1 .2 1 .2 .3 .4 .3 2 1 2 .2 .1 0]

+ 1' -»• B{au)} -> .2

J"

j + 1 ; B{bhk} + »'

j ' — (» + 1)' + 1'

.3

j' — (n+ 1)' -> 2

w e n n j — (n + 1 ) < 0 dann Sprung nach .2 • z — cilh

{Cl)1} + i x n + k — n — 1

142

Mehrfach zyklische Programme

Maschinen-Programm, (Fortsetzung)

Nummer

Befehl Op.

Adr.

B S T SN T B S T B AC T B AC U QQEN

.2 .4 .2 .4 .2 .3 .6 .3 .7 1 .7 .5 1 .5 .8

Bemerkungen

•— W

-B{a«,i}

£{&,,*} — (ra2 — 1)' k 1

.2

-> .3

£ + 1; T{c.3

fc«- 1 » ' — ( » + 1)' + 1' h* .9 wenn i — ( » + 1 ) < 0 dann Sprung nach .8 0 h» 4

E

+ n'

Mehrfach zyklische Programme

143

Maschinen-Programm, (Fortsetzung) Nummer 1 k 5 6 9 10 11 12 13

Befehl Op.

Bemerkungen

Adr.

[Z

0] n'

[Z (n2 — iy [Z B B

1]

Jc> —

2]

»' — (» + 1)'

{ n

+iy

Ki} {M

T

Kl}

Zur algorithmischen Sprache:

Ende Bemerkungen

Mehrfach zyklische Programme können so unübersichtlich werden, daß man Bemerkungen zur Erklärung in den Algorithmus hineinschreiben möchte. Allerdings müssen bestimmte Regeln eingehalten werden, damit keine Verwechslungen zwischen Elementen des Algorithmus und Teilen der Bemerkungen vorkommen können. Auf folgende Weise dürfen Bemerkungen in die Algorithmen eingeschoben werden, ohne daß sich das Verfahren dadurch ändert: 1. Hinter einem Semikolon darf das Wort Bemerkung mit einer darauffolgenden beliebigen wieder mit einem Semikolon abgeschlossenen Zeichenfolge geschrieben werden. Allerdings darf diese Folge selbst kein Semikolon enthalten. Beispiel:

8 4- 0; Bemerkung hier wird der Anfangswert festgelegt; r>

x

Mehrfach zyklische Programme

144

2. Das Wort Beginn darf genauso behandelt werden wie das Semikolon. Beispiel: Beginn Bemerkung Diese Bemerkung ist zwischen das Zeichen Beginn und die erste Anweisung, nämlich t 1 + e, eingeschoben worden; t 1 + s;

3. Hinter dem Wort Ende dürfen beliebige Zeichenfolgen geschrieben werden, sofern sie nicht Ende, sonst oder ein Semikolon enthalten. Beispiel:

a zt Ende Zyklus i Ende Programm Wir wollen ein weiteres Programm-Beispiel angeben, das induktive Zyklen mit fester Durchlaufzahl und einen iterativen Zyklus mit variabler Durchlaufzahl aufweist. 18.

Programm-Beispiel: Lösung des linearen n

k=l

Gleichungssystems

Xk = a

{Xi}

B{at,*} + 1'

B{at,i}

.9

-s-Si

B{at,*} * .2

+ » ' + 2'

â{xî> + 1'

• T{xi} + 1'

£{« .10

B{xi} ->.11

T{xt}

.12

1' -> jfc' -> .4 -f- i ' ^ i' -> .5

• wenn n — i > 0 dann Sprung nach .13

150

Mehrfach zyklische Programme

Maschinen-Programm

(Fortsetzung):

Befehl Op.

1 4 5 7 9 15 16 17 20 21 22 23 19

19.

= = = = = = = = = = = = =

Bemerkungen

Adr.

B T B

.9 6 .20

PPE

.14

E

.19

[Z [Z [Z

7] 8] 9]

[Z

10] 8192'

wenn sn — £ 2: 0 dann Sprung nach .14

y

V

Ki} K) T B Z

s 0+0

0+0 12

Befehlen, die s = t = 0 enthalten sollen, geben wir die Adresse 0 + 0 (s. Seite 279). u Ende

Programm-Beispiel: Tabellensuchverjähren1)

In einer Folge von 1000 benachbarten Speicherplätzen befindet sich eine Tabelle von 1000 Tabelleneinheiten Ei (i = 0 , 1, 2 ... 999), die je aus einem Wort bestehen. Jedes Ei soll im Beispiel ein Tabellenmerkmal Mi (zum Beispiel eine Kontonummer) und eine Tabelleninformation Ii (zum Beispiel ein Guthaben) enthalten. Mt soll jeweils eine zwanzigstellige, positive Dualzahl sein, die die zwanzig niedrigsten Stellen von Ei besetzt. Die Mi sind in einer beliebigen statistischen Verteilung aus dem Zahlenbereich 0, 1 ... (220 — 1) ' ) Zum Tabellensuchproblem siehe [33], [34].

Mehrfach zyklische Programme

151

ausgewählt. Allerdings soll jedes Mi nur einmal vorkommen. Außerdem ist die Numerierung i = 0, 1, 2 . . . 999 so vorgenommen, daß die Mi der Größe nach geordnet (sortiert) sind: kleine Mi haben kleine i. Weiter sind in einem anderen zusammenhängenden Speicherbereich 20 andere Tabelleneinheiten e* (4 = 0, 1, 2 . . . 19) gespeichert, deren Tabellenmerkmale r«*: eine Teilmenge der Mt darstellen. Die Aufgabe besteht nun darin, die zwanzig ejt nacheinander aufzusuchen und für jedes et das Ei zu suchen, dessen Mi — m* ist. Anschließend soll jeweils das Ei, anstelle des vorgegebenen ex, gespeichert werden. Wir haben dann 20 vorgegebene Tabelleneinheiten aus der Tabelle herausgesucht und gespeichert. Als Sachverfahren soll nun nicht ein einfaches Durchlaufen der Tabelle gewählt werden, sondern das gesuchte Et soll durch ein (bei langen Tabellen) zeitsparendes Einschachteln gefunden werden. Dazu werden durch laufende Einstiche in die Tabelle einzelne Ei. herausgegriffen (etwa als stäche man mit einem Messer in eine Kartei ein) und mit dem vorgegebenen w»t verglichen. Ist das gefundene Mi' gleich mt, sind wir fertig. Ist Mi' größer als m,k, suchen wir uns einen neuen Einstichpunkt „links" von i', sonst „rechts" davon. Das einfachste Verfahren ergibt sich, wenn wir in der Mitte anfangen und die Abstände zwischen zwei aufeinander folgenden Einstichpunkten laufend halbieren (Mitteneinstich).

a) Algorithmische

Formulierung:

Die Variablen E, M, e und m seien in einem übergeordneten Block durch ganzzahlig Feld E, M0.999, e, m0:19 erklärt und mögen dort vor Eintritt in den folgenden Block ihre Werte erhalten. Beginn ganzzahlig n, für k

d,i,k;

0 Schritt 1 bis 19 führe aus

Beginn d für i

500; 500, wenn Mi > »

t

solange Mi 4= m^ führe aus

dann i — d sonst i + d

Mehrfach zyklische Programme

152

Beginn d

d -f- 2;

Ende Suchen für Ende Zyklus k Ende Programm b)

Flußdiagramm:

k 0 0 wenn WA = 0 — 1 wenn WA < 0 ']/WÄ Sinus von WA Cosinus von WA Arcustangens von WA natürlicher Logarithmus von WA eWA

Wurzel(A) sin(A) cos(A) arctan(A) ln(A) exp(A) ganz(A)

größte ganze Zahl, die nicht größer als WA ist

Darin bedeutet WA den Wert des arithmetischen Ausdrucks A. Alle diese Funktionen können mit Parametern vom Typ ganzzahlig und reell

172

Die Versorgung von Unterprogrammen mit Parametern

arbeiten; sie liefern Funktionswerte vom Typ reell bis auf sign(A) und ganz(A). Diese liefern Werte vom Typ ganzzahlig. Für Prozedurvereinbarungen gilt allgemein das, was wir früher für die anderen uns schon bekannten Vereinbarungen, nämlich, die Typ-, Feld- und Verteilervereinbarungen gesagt haben. Hier müssen wir noch die besondere Form der Prozedurvereinbarung besprechen: Jede Prozedurvereinbarung besteht aus dem Wort Prozedur mit vorangestelltem Typ (zur Kennzeichnung des Typs der Funktionswerte), einem Prozedurhopf und einem Prozedurrumpf. Der Prozedurrumpf ist im allgemeinen eine algorithmische Anweisung (auch zusammengesetzte Anweisung oder Block), die angibt, wie die Funktion zu berechnen ist. Der Prozedurkopf enthält eine Reihe von zusätzlichen Angaben, aus denen man ersehen kann, wie die Funktion heißt, welche Parameter darin auftreten und welche Eigenschaften diese Parameter haben. Der Prozedurkopf enthält daher als erstes den Prozedurnamen und den Parameterteil, das heißt die in Klammern gesetzte Parameterliste. Beispiele: reell Prozedur sin(x) ganzzahlig Prozedur Zufallszahl Boolesch Prozedur 8heffer(a, b) Dabei dürfen die Parameter beim Funktionsaufruf anders heißen als in der Prozedurvereinbarung. Steht etwa eine Funktion innerhalb eines Ausdrucks (zum Beispiel a + / (x + y, 3)), so dürfen die darin enthaltenen Parameter selbst wieder Ausdrücke sein (hier also im Beispiel x + y). Die beim Aufruf der Funktion tatsächlich in der Parameterliste stehenden Ausdrücke nennen wir Aktualparameter. Dagegen stehen im Verfahrenskopf in der Parameterliste nur Namen als Parameter (zumBeispiel /(a,f>)). Wir nennen diese dann Formalparameter1). Es muß natürlich jedem Aktualparameter durch seine Stellung innerhalb der Formalparameterliste genau ein Formalparameter aus der Formalparameterliste zugeordnet werden können (zum Beispiel: x + y entspricht a, und 3 entspricht b). Die Formalparameter müssen in einem weiteren Teil des Prozedurkopfes erklärt werden. Das heißt, es muß angegeben werden, welche Arten von Aktualparametern für die Formalparameter eingesetzt werden dürfen. Die uns hier vorerst interessierenden Angaben dieser Art, die vom vorangehenden Teil und untereinander durch Semikolon getrennt werden, Entsprechend heißen die Parameterteile: Aktualparameterteil Listen: Aktualparameterliste und Formalparameterliste.

und FormalparameterUil

und die

Geschlossene Unterprogramme

173

sind der Typ mit einer Liste der jeweils durch Komma getrennten Parameter, die vom angegebenen Typ sein müssen, und bei Feldern der Typ und das Wort Feld mit einer entsprechenden Liste. Bei Feldern vom Typ reell kann der Typ entfallen. Beispiele: 1. reell Prozedur sin(x); reell x 2. ganzzahlig Prozedur größte Komponente(v); ganzzahlig Feld v 3. Boolesch Prozedur Skalarprodukt(a, b, n); Boolesch Feld a, b; ganzzahlig n Das erste Beispiel bedeutet: Für den Formalparameter x dürfen wir arithmetische Ausdrücke vom Typ reell einsetzen. Der Funktionswert ist vom Typ reell. Das zweite Beispiel besagt (zum Beispiel), daß die größte Komponente eines Feldes vom Typ ganzzahlig bestimmt werden soll. Das Ergebnis ist vom Typ ganzzahlig. I m dritten Beispiel soll das Skalarprodukt zweier Felder vom Typ Boolesch gebildet werden, n ist vom Typ ganzzahlig (n sei etwa die Ordnung der Vektoren a und b). Das Ergebnis ist vom Typ Boolesch. Der Aufruj einer Funktion geht nun im einfachsten Fall folgendermaßen vonstatten: Tritt in einem Ausdruck ein Funktionsbezeichner mit einer Reihe von Aktualparametern auf, so wird die im gleichen Block dann notwendigerweise vorhandene Prozedurvereinbarung gleichen Namens aufgesucht. I m Prozedurrumpf dieser Vereinbarung werden dann alle Formalparameter durch die zugehörigen Aktualparameter ersetzt. Damit stehen alle Angaben zur Verfügung, mit denen die in einem Ausdruck aufgerufene Funktion berechnet werden kann. Anschließend wird der berechnete Wert in den Ausdruck eingesetzt. Beispiel: Beginn reell x, y, v, T,G; reell Prozedur Approx(s, t); reell s, t; Approx (s2 + 2 x i3)/( 1 —t);

T

Ende

+ [3 — Approx(x, y — l)]l(v — 1);

174

Die Versorgung von Unterprogrammen mit Parametern

Bei der Ausführung der Ergibt-Anweisung für T wird folgendermaßen substituiert: T+. G + {3 — [«« + 2 x (y -

1)3] / [1 _ (y — 1)]} / (« — 1)

Man sieht, daß zusätzliche Klammern benötigt werden. Weiter müssen etwa auftretende Widersprüche in den Namen durch sinnvolle Umbenennungen aufgehoben werden. Beispiel: Beginn reell x, y, v, T,G; reell Prozedur Approx(s, t); reell s, t; Beginn reell v; 0.7; v Approx (s2 + 2 x tslv)l( 1 —t) Ende Prozedur;

+ [ 3 — Approx{x, y — !)]/(» — 1);

T+-G

Ende Programm Wegen der Zweideutigkeit von v wird die im Prozedurrumpf vorkommende Variable » i n w umbenannt und folgendermaßen substituiert: T^G+{

3



[X*

+ 2X

(y — 1 ) > ] / [1 — (y — 1)]} / (t> — 1)

Außerdem muß darauf geachtet werden, daß der Prozedurname im Prozedurrumpf normalerweise nur (einmal) auf der linken Seite einer Ergibt-Anweisung auftreten darf, weil er rechts innerhalb eines Ausdrucks wieder den Aufruf der Punktion bewirken würde. Beispiel: reell Prozedur Approx(s, t); reell s, t; Beginn reell z; z s2 + 2 x t 3 ; Approx z/(l — t) Ende Prozedur;

Geschlossene Unterprogramme

175

Der Prozedurrumpf darf nicht ersetzt werden durch: Beginn Approx •«= s2 + 2 x ts; Approx .2

.2 .2 Sprung auf Unterprogramm Pol(A, K, n) . Parameter für Pol(A, K, n) •

. x x Pol{x2, a, 4)

sin(a;)

4

Sprung auf eine Fortsetzung des Programms

1 — 0,16667 0,0082517 — 0,00019619 0,0000025771

GK

X

12 Güntsch, Digitale Rechenautomaten 2. Aufl.

178

Die Versorgung von Unterprogrammen mit Parametern

Zur algorithmischen Sprache: P r o z e d u r e n Wenn wir das letzte Programm-Beispiel aufmerksam durchlesen, stellen wir fest, daß wir ein wenig anders vorgegangen sind, als wir zuvor besehrieben hatten: Wir haben nicht den Formalparameter A durch den Ausdruck x2 ersetzt und den Wert dieses Ausdruckes erst an den Stellen des Prozedurrumpfes bestimmt, an denen A vorkommt. Wir haben also nicht erst im Unterprogramm Pol (in der Anweisung p 4;

B{x}

Hauptprogramm

0 0

1 — 0,16667 0,0082517 — 0,00019619 0,0000025771

Koeffizienten K für Pol(A,K,n),

OK

Das Programm, Pol(A, K, n) kann unverändert aus dem 21. ProgrammBeispiel (Seite 168) übernommen werden. In diesem Programm-Beispiel rief das Unterprogramm sin(x) ein anderes Unterprogramm Pol(A, K, n) auf. Dabei stand es fest, daß sin(x) nur das Programm Pol aufrufen würde und kein anderes. Da wir aber nicht voraussetzen wollten, daß beim Programmieren von sin(x) explizit bekannt ist, wo sich Pol im Speicher befindet, mußten wir dem Programm sin(x) die Adresse des benötigten Unterprogramms Pol als besonderen Parameter (in der Form E{Pol}) mitteilen. Mit dieser Maßnahme können wir aber auch eine etwas allgemeinere Aufgabe lösen, nämlich die Benutzung von Unterprogrammen, die ihrerseits wieder ein oder mehrere Unterprogramme aufrufen, von denen nicht vorher feststeht, um welche Programme es sich dabei handelt. Die Auswahl dieser Programme soll nicht im aufrufenden Unterprogramm, sondern im Hauptprogramm erfolgen. Allerdings müssen zu diesem Zweck alle in Frage kommenden Unterprogramme gleichartige Parameter verwenden und diese in gleicher Weise übernehmen. Wir wollen uns die Anwendung dieser Möglichkeit in folgender Übung klarmachen:

187

Verschachtelte Unterprogramme

7. Ü b u n g : Es soll ein mit der Simpsonschen für das Integral

Regel arbeitendes

Quadraturprogramm

«9 Int = f ){x)dx ug entworfen und mit dessen Hilfe das Integral 1 8 — j sin2(x — 0,3)g(x)dx 0 berechnet werden, wobei g(x) in den Punkten Xi

= i X 10- 1 (i = 0, 1, 2 . . . 10)

numerisch bekannt und im Hauptprogramm gespeichert vorliegen soll. Das Unterprogramm für Int soll mit beliebigen Integranden f(x) und frei wählbaren Grenzen ug, og und freier Schrittweite h arbeiten. Das heißt: f(x), ug, og und h sind die Formalparameter des Programms. Wir nennen es daher Int{f, ug, og, h). Zur Berechnung von f(x) wird von Int ein vom Hauptprogramm bestimmtes Unterprogramm aufgerufen. In unserem Beispiel (j(x) — sin2(x —0,3) V i - - - 2/(xe-xa)/h

ifce-xa)/h+6 : 2. Das Programm Runge und Kutta versorgt das von ihm benötigte Unterprogramm Berechnung von f(x, y) folgendermaßen mit Parametern: px: Argument x p2: Argument«/

212

Systematische Behandlung der Adressenänderungen

3. Das Programm Berechnung von f(x, y) versorgt das von ihm benötigte Programm sin folgendermaßen: p1: Das Argument x p2: Der Anfang des von ihm benötigten Unterprogramms Pol in der Form E{Pol} 4. Das Programm sin versorgt Pol wie folgt (vgl. 23. Programm-Beispiel, Seite 181): / p1: Argument x p2: Adresse von a0 in der Form B{a0} p3: Adresse von an in der Form B{an} Weiter gilt: a) Bei Aufruf eines Unterprogramms enthält Schnellspeicher 4 die Adresse von b) Bei der Rückkehr zum Hauptprogramm enthält Schnellspeicher 4 den berechneten Funktionswert (Ausnahme: beim Rücksprung von Runge und Kutta ist < 4 > irrelevant). c

) J?2> Pa ••• folgen jeweils direkt hinter der Absprungstelle im übergeordneten Programm.

d) Alle Programme enthalten einen Vorspann für die Änderungen erster Art. Dabei wird vorausgesetzt, daß die Programme jeweils ab 1000 gezählt werden und daß r gleich 5000 und a gleich 13 ist (vgl. 24. ProgrammBeispiel Seite 195). e) Das Hauptprogramm bekommt einen anderen Vorspann, der bewirkt, daß es ab 1000 gespeichert und daß nach r eine 0 gebracht wird: T T T

1000 5000 5000

T E E

T 1000 - > a ( = 13) 0 —> r ( = 5000)

Dabei wird vorausgesetzt, daß zuerst das Hauptprogramm und anschließend die übrigen Programme eingelesen werden. Haben wir uns bisher bei der Besprechung der Unterprogrammtechnik (mit Ausnahme der Verwendung von Indexregistern für die Änderungen erster Art) damit begnügt, Adressenänderungen direkt als Adressenrechnungen auszuführen, die vom Programm explizit vorgenommen werden,

Die Durchführung der Änderungen zweiter Art

213

so wollen wir nun einige Hilfsmittel besprechen, die es erlauben, die vielfältigen Änderungen zweiter Art bequemer, schneller und platzsparender auszuführen. 7.31 Automatische Blocktransporte

Ein für Änderungen zweiter Art besonders günstiger Zeitpunkt ist der Augenblick, in dem das Unterprogramm vom Hauptprogramm aufgerufen wird, weil in diesem Augenblick im Rechner sowohl die Absprungstelle im Hauptprogramm als auch der Anfang des Unterprogramms in bestimmten Registern explizit vorliegt. Daher werden in allen Verfahren zur Automatisierung der Änderungen zweiter Art die erforderlichen Informationstransporte unmittelbar im Zusammenhang mit dem Sprung ins Unterprogramm vorgenommen. Am konsequentesten geschieht das in der Form, daß zugleich mit dem Sprung in das Unterprogramm der ganze hinter der Absprungstelle stehende Parameterblock in eine Reihe von Auffangzellen eingespeichert wird, die am Anfang des Unterprogramms für diesen Zweck freigehalten werden [44], [40], [11]. Beispiel: Hauptprogramm: Nummer

p - 1 P

Befehl: Operationsteil

Bringe Adresse nach Indexregister Sprung auf das Unterprogramm mit Blocktransport

p + 1 • Parameterblock p + k

Adresse

k s + k

214

Systematische Behandlung der Adressenänderungen

Unterprogramm: Nummer

Befehl:

s Auffangzellen für Parameterblock s + k — 1 5 + k

Anfang des eigentlichen Unterprogramms

Wir haben einen Sprungbefehl mit Blocktransport benutzt, der mit einem Indexregister zusammen arbeitet, in das vor dem Absprung in das Unterprogramm die Blocklänge gebracht wurde [44]. Eine andere Möglichkeit besteht darin, bestimmte Befehle des Unterprogrammes zu kennzeichnen und den Sprung auf das Unterprogramm mit folgender Vorrichtung auszustatten: Das Unterprogramm wird von vorn nach hinten nach den Kennzeichen abgesucht. Wird das erste Kennzeichen gefunden, so wird die erste hinter dem Sprungbefehl stehende Zahl als Adresse in den gekennzeichneten Befehl eingesetzt. Dann wird weiter gesucht und die nächste Zahl als Adresse eingesetzt, sobald wieder ein gekennzeichneter Befehl gefunden worden ist, und so fort. Der Vorgang läuft so lange, bis ein Befehl mit einem geeigneten verabredeten Schlußzeichen vorkommt. Dann wird der erste Befehl des Unterprogrammes ausgeführt [11]. 7.32 Ablaufnotierung Der etwas aufwendige Transport eines ganzen Parameterblocks an den Anfang des Unterprogramms kann durch eine einfachere Maßnahme ersetzt werden, die sich als sehr wirksam erweist : Statt des Parameterblocks wird beim Sprung auf das Unterprogramm automatisch die Adresse des auf den Absprungbefehl folgenden Befehls an eine für das Unterprogramm bequem erreichbare Stelle gebracht. Die Notierung dieser Folgeadresse nennt man eine Ablaufnotierung. Sprungbefehle, die mit solchen Ablauf-

Durchführung der Änderungen zweiter Art

215

notierungen verbunden sind, werden häufig Unterprogrammsprünge genannt. Für eine solche Ablaufnotierung besonders günstige Auffangstellen sind a) ein bestimmtes Indexregister [48] und b) der Anfang des Unterprogramms. Haben wir die Ablaufnotierung in einem Indexregister abgelegt, so können wir die Parameter mit indizierten Befehlen erreichen. Ausführungsbeispiel Z 22 Es wird verabredet: Zu dem Grundbefehl E kann das Zusatzzeichen F zugefügt werden. Der Befehl EF wird mit F abgekürzt. F n bewirkt: < w > -> BR (Sprung auf < w > ) , ferner: Befehl E p + 1 Schnellspeicher 5 Dabei ist p + 1 die Adresse des auf Fn folgenden Befehls. Hauptprogramm: Nummer

V

Befehl

Op. F

Adr. g.

p+1

1. Parameter

p+i

i-ter Par.

p+k p+k+1

fc-ter Par.

Bemerkungen

Ep-\-1 -> 5, Sprung nach q

216

Systematische Behandlung der Adressenänderungen

Unterprogramm : Nummer

Befehl Op.

Adr.

Bemerkungen

+ i) t t bzw. « s — 1 > — t) t ->-t ( < s > + t) - > s bzw. ( < s — 1 > — t ) t —>8 dann Ausführung des Befehls x t. Auch hinter CGÄ'-Befehlen muß jeweils ein Wort freigelassen werden.

Die Durchführung der Änderungen dritter Art

227

Wir wollen hier auch noch angeben, welche Wirkung die Kombination der Zusatzzeichen G und C (ohne K) hat: BGGs + t: ( + < . s > + t->s; BCtausführen UCGs + t:«s> + t)t=¥-t; < s > + Leerbefehl (ohne Wirkung) ausführen Mit Hilfe des Zusatzes CG kann also in jedem Schnellspeicher gezählt werden. Die Anfangsadresse steht im Schnellspeicher, das Inkrement als Trommeladresse im Befehl. Bei der Verwendung des Minuszeichens muß s wieder um Eins erhöht werden. 28. Programm-Beispiel: Das Programm für die Berechnung des Shalarproduktes zweier Vektoren aus dem 10. Programm-Beispiel (Seite 113) sieht bei Verwendung von CGKBefehlen beispielsweise folgendermaßen aus: Befehl

Nummer

Op.

Adr.

CNS T BC T BC T T BCGK

10 2 1999 10 2009 11 2020 10 + 1 o 6 11 + 1

Bemerkungen Beginn

1 =

II z

T BCGK

II

z X B

1

—10' { a j — 1' H* 10

»4-1

{&i} — 1 ' ->11 0

II II

s 0 -> 2020 B{at}

B{bt} a% x bt + «¿.j «> Si -> 2020

2020

+ T UCG

II z QE 15»

2020 2+ 1 2 .1

— (11— i)' + 1' - * 2

II

wenn i < 10 dann Sprung nach .1 Ende

228

Systematische Behandlung der Adressenänderungen

Die CGiT-Befehle machen das Programm, wie das Beispiel zeigt, viel übersichtlicher und kürzer. Gleichzeitig sehen wir, welche Maßnahmen man treffen muß, um die Änderungen dritter Art noch kompakter programmieren zu können: a) Will man mehrere indizierte Variable, die mit der gleichen Schrittweite im Speicher notiert sind, mit einem Indexregister aufrufen, so muß man das Inkrement in das Indexregister und den Nullpunkt der Speicherfolge, die mit Hilfe des Indexregisters durchgearbeitet werden soll, in die Befehlsadresse verlegen. Die laufende Adresse muß dann immer in den Adressenteil des Befehls zurückgespeichert werden. b) Die vollständigste Einrichtung für die Änderungen dritter Art, bei der auch die Prüfung auf Erreichen des Endwertes automatisiert ist, besteht aus einem dreigeteilten Indexregister i mit folgenden Teilen [54]: i[

enthält den laufenden Wert einer Zählgröße,

in enthält den AdressenziiwacÄs von Wort zu Wort innerhalb der Folge, i,

enthält den Endwert der Zählgröße. Dann werden besondere Befehlszusätze vorgesehen, die

1. zur Adresse eines Befehls < i t > hinzuaddieren und 2. zum Inhalt von il den von iz addieren. Ferner werden bedingte Sprungbefehle eingeführt, die nur dann ausgeführt werden, wenn = ist. Die Befehle, deren Adressen mit dem Indexlauf geändert werden sollen, enthalten dann jeweils die Anfangsadresse der indizierten Zahlenfolge. Auf diese Weise braucht die jeweilige Adresse nicht in den Befehl zurückgespeichert zu werden, so daß die Anfangsadresse im Befehl erhalten bleibt. Außerdem können — gleichartige Speicherung vorausgesetzt — wie bei (a) mehrere Folgen mit einem Indexregister versorgt werden. Allerdings muß man darauf achten, daß der in it enthaltene Anfangswert im Laufe der Zählung verlorengeht. E r muß also vom Programm erzeugt und jeweils bei Bedarf nach il gebracht werden. 7.42 Mehrfach-Indizierung

Für viele Aufgaben ist die Handhabung mehrfach indizierter Variabler von großer Bedeutung. So würde zum Beispiel bei der Matrizenmultiplikation (17. Programm-Beispiel, Seite 138) eine automatische Änderung

Die Durchführung der Änderungen dritter Art

229

zweier Indizes sehr viel Programmierungsarbeit ersparen. Ein im Prinzip einfaches, in der Realisierung aber meist etwas aufwendiges Mittel ist die Bereitstellung zweier Indexnummern im Befehlswort, mit deren Hilfe der Inhalt zweier Indexregister zu einer Grundadresse addiert werden kann. Ein solches Befehlswort hat dann etwa folgende Struktur [55]: OP

Ii

h

A

Damit können wir alle Komponenten eines zweidimensionalen Feldes aik erreichen, wenn wir voraussetzen, daß die am sowohl hinsichtlich i (bei festem k) als auch hinsichtlich k (bei festem i) äquidistant gespeichert sind. Um fortlaufend alle a a u f z u s u c h e n , müssen wir laufend das Indexregister für i bis zu einem Endwert erhöhen, dann einen Schritt mit dem Indexregister f ü r k ausführen, wieder mit i zählen und so fort. Entsprechend könnte man auch eine drei- und mehrfache Indizierung durchführen. Die Ausnützung wird dann jedoch nicht sehr gut, weil die Häufigkeit, mit der fc-fach indizierte Variable auftreten, mit wachsendem k stark abnimmt. 7.48 Induktiv verarbeitete Unterprogramm-Parameter Häufig werden die Änderungen dritter Art komplizierter, als man anfangs vermutet, weil die induktiv zu verarbeitenden Größen Parameter eines Unterprogramms sein können, die selbst nur durch Änderungen zweiter Art erreichbar sind. Die einfachste Art, mit dieser Aufgabe fertig zu werden, ist die, sich die Anfangsadresse der Variablen-Folge über eine Änderung zweiter Art zu verschaffen, sie in ein Indexregister umzuspeichern und mit diesem so zu verfahren, wie wir das in Kapitel 7.41 beschrieben haben.

29.

Programm-Beispiel:

Berechnung einer Sinus-Tabelle 1.

(vgl. Seite 219)

Hauptprogramm

2. Unterprogramm sin 3. Unterprogramm Pol Über die Speicherverteilung gelten die Verabredungen von Seite 219.

230

Systematische Behandlung der Adressenänderungen

Hauptprogramm: Es benötigt (einschließlich seiner Unterprogramme) die Schnellspeicher 2, 11, 12, 13, 14.

Nummer -

2 =

Befehl Op.

Adr.

BC T BC T GKB Z T F

2000 13 2299 14 13 + 0 0 .1 5000

Z E B CG KT Z BC CG KS Z PPE

1 4000 .1 14 + 1

Bemerkungen

{*„} 13 0 i {sin £ 0 } — 1' ->14 Xt

Beginn

Argument für sin

Sprung nach sin xi,

sin(Xi)

E

{Pol}

sin{xi) speichern

2

2099 13 + 1 3 .2

wenn i

99 dann Sprung Ende

Unterprogramm

sin:

Es benötigt aus dem Hauptprogramm die folgenden Parameter: p1: x p2:E

(Argument) {Pol}

(Sprung auf das Unterprogramm Pol).

Das Ergebnis wird anstelle von x im Parameterblock des übergeordneten Programms gespeichert. Das Programm benötigt (zusammen mit dem Programm Pol) die Schnellspeicher 2, 11, 12.

Die Durchführung der Änderungen dritter Art

231

Programm sin: Befehl Op.

Adr.

B T BGK |[Z

5 11

0]| 6

x2 •=>• p1 für Pol

.1

4 .2 11 .3 11 + 1 111

z B Z B T B T BGK |Z X TGK |Z EGK

Ablaufnotierung ->11

11+0

u

X T SC T B T FGK Hz

Bemerkungen

2

A 3 .3 11

— 4 -»•— n' für Pol -» .2 11 räumen Sprung auf Pol

B{a„} — n', später Ablaufnotierung ->11

.1

6 11+0

4| 11+0 5| 11+2

1 —0,16667 0,0082517 -0,00019619 0,0000025771

x x Pol(x2, a, 4)

sin{x)

Rücksprung auf das übergeordnete Programm (Hauptprogramm)

Koeffizienten K für Pol{A, K, n)

232

Systematische Behandlung der Adressenänderungen

Unterprogramm Pol: Es benötigt aus dem Sinus-Programm folgende Parameter: Pl:x pi\B{an} Das Programm berechnet Pol(x, a, n) und speichert es anstelle von x im Parameterblock des übergeordneten Programms. Es benötigt die Schnellspeicher 2 (zum Zählen), 11 (für die Änderungen 2. Art) und 12 (für die Änderungen 3. Art). Programm Pol: Nummer

2 =

1 =

Befehl Op.

Adr.

B T BGK |[Z u T

5 11 11 + 1

P T BGK Ilz T BGK Ilz X BCGK Ilz

+

011 12 .2 1] 6 11+2 2 II 2 11+0

Bemerkungen

Ablaufnotierung -» 11

B {an} ~> 12, .2

an - > 6 • — n'

2

3 II 13 — 1

• x x p + Oj.j

p

4,6

4 II

UCG HZ QE

2+ 1

TGK Ilz EGK

11+0

5 II .1 6 II 11+3

i

— 1

wenn i ^ 0 dann Sprung nach .1 Pol

Rücksprung auf das übergeordnete Programm sin

Die Durchführung der Änderungen dritter Art

233

12. Ü b u n g : Sortieren durch Mischen mit bekannten Sequenzlängen (vgl. [25]). Es seien wiederum 1000 Sortiereinheiten mit Sortiermerkmalen vorgegeben, und es sollen die Bezeichnungen und Voraussetzungen über die Unterbringung der Sortiermerkmale in den Sortiereinheiten sowie über die Verteilung der Sortiermerkmale im Merkmalbereich die gleichen sein wie in der 4. Übung (S. 155). Das Sortieren soll diesmal durch ein wiederholtes Mischen erfolgen. Dabei versteht man unter Mischen das Zusammenfügen zweier bereits sortierter Folgen, sogenannter Sequenzen, in der Weise, daß wiederum eine Sequenz entsteht. Wir wollen vorerst annehmen, daß die Anzahl der Sortiereinheiten (N) eine Zweierpotenz (2P) ist und damit beginnen, daß wir jeweils eine Sortiereinheit als eine Sequenz (der Länge eins) betrachten und jeweils zwei Einheiten zu einer Sequenz der Länge zwei mischen. I n einem zweiten Durchlauf mischen wir wieder je zwei Sequenzen der Länge zwei zu einer Sequenz der Länge vier usw. Die Anzahl der Sequenzen verringert sich dabei mit jedem Durchlauf auf die Hälfte und nach p Durchläufen sind die beiden letzten Sequenzen mit den Längen 2 p l zu einer Sequenz der Länge N = 2P gemischt. Damit ist die Sortieraufgabe gelöst. Ist N keine Zweierpotenz, so bleiben je nach der Teilbarkeit durch zwei bei den einzelnen Durchläufen noch Sequenzen kleinerer Länge übrig. Dies ändert nichts am Prinzip des Verfahrens, sondern stört nur dessen Symmetrie und erhöht die Anzahl der Durchläufe um eins. Das Mischen selbst nehmen wir am besten so vor, daß wir neben dem von den vorgegebenen Sortiereinheiten belegten Speicherbereich einen zweiten Bereich gleicher Größe reservieren. Beim ersten Durchlauf nehmen wir dann je zwei aufeinanderfolgende Einheiten aus dem ersten Bereich, mischen sie und speichern sie fortlaufend in den zweiten Bereich. Beim zweiten Durchlauf nehmen wir wiederum je zwei aufeinanderfolgende Sequenzen (der Länge zwei) aus dem zweiten Bereich, mischen sie und speichern sie in den ersten Bereich zurück, und so fort. Auf diese Weise speichern wir alle Sortiereinheiten so lange zwischen den beiden Speicherbereichen hin und her, bis die Folge sortiert ist. Es gibt eine Möglichkeit, die Änderungen zweiter Art zur Übernahme des Anfangswertes einer Sequenz, die induktiv verarbeitet werden soll, mit der Änderung dritter Art dadurch zu verbinden, daß man auf die Adressentranslation und gegebenenfalls die nachgeschaltete Substitution (zurÄnde-

234

Systematische Behandlung der Adressenänderungen

rung zweiter Art) eine weitere Adressentranslation nachfolgen läßt (für die Änderung dritter Art). Dabei gibt die Adresse des Befehls die relative Lage des Parameters, der den Anfang der indizierten Folge kennzeichnet, innerhalb des Parameterblocks an. Die vorgeschaltete Translation führt dann — etwa über die Ablaufnotierung—zu diesem Parameter. Die Substitution führt zum wirklichen Anfang der Sequenz (wenn der Parameter selbst bereits der Anfang ist, kann die Substitution entfallen), und die nun noch nachgeschaltete Translation führt dann zu dem Exemplar der Folge, das durch den Wert des laufenden Index bezeichnet wird. Zu diesem Zweck muß der Befehl nicht nur das Indexregister mit der Ablaufnotierung, sondern auch ein zweites Indexregister, das den laufenden Indexwert enthält, ansprechen können [40]. 7.6 Besonderheiten bei Festspeichern Die bislang in diesem Kapitel geschilderten Verfahren zur Durchführung der Änderungen erster, zweiter und dritter Art lassen sich nicht alle anwenden, wenn man es mit sogenannten Festspeichern zu tun hat [56], [57]. Unter Festspeichern (auch Totspeicher genannt) versteht man solche Speicher, deren Inhalt zwar wie bei gewöhnlichen Speichern (zum Unterschied zu Festspeichern auch Aktivspeicher genannt) gelesen werden kann, die aber — zum mindesten vom Programm her — nicht beschrieben werden können. Solche Festspeicher können technisch auf verschiedene Weise realisiert werden [58]. Am bekanntesten sind Ferritkern-Speicher, bei denen der Speicherinhalt durch ein bestimmtes, dem Programm entsprechendes Fädelungsmuster festgelegt wird. In der Z 22 können die Schreibverstärker für die Trommel gruppenweise abgeschaltet werden, so daß die Trommel anschließend vom Programm zwar gelesen, aber nicht mehr beschlieben werden kann. Solche Festspeicher haben den Vorteil, daß Programme, die längere Zeit unverändert benutzt werden sollen, bei Maschinenfehlern nicht durch Irrläufe des Rechners aus Versehen überschrieben werden können. Außerdem können sie je nach Technik unter Umständen sicherer, billiger oder schneller als vergleichbare Aktivspeicher gemacht werden. Programme, die lange unverändert benutzt werden, treten vor allem bei industriellen Steuerungsaufgaben auf, bei denen ein geordneter Betrieb verlangt, daß dieBetriebsverfahren selten geändert werden. Außerdem empfiehlt es sich auch, bei sonstigen Anwendungen gewisse Grundprogramme, wie zum Beispiel Leseprogramme und Notprogramme, in Festspeichern unterzubringen.

Besonderheiten bei Festspeichern

235

Liegt ein solches Pestspeicherprogramm vor, so können wir von den verschiedenen Möglichkeiten, Änderungen zu realisieren, alle die nicht gebrauchen, bei denen im Laufe der Änderung irgendwelche Größen in das Programm gespeichert werden müssen. 1. Änderungen erster Art Da Festspeicher nach Voraussetzung meist lange Zeit festliegen, ist eine Automatisierung der Änderungen erster Art in diesem Fall nicht so wichtig. Im Vergleich mit der Häufigkeit, mit der das Programm benutzt wird, ist die Mühe, die Änderungen erster Art beim Programmieren im voraus explizit durchzuführen, nicht sehr groß. Am besten wird es sein, alle Festspeicherprogramme von einem besonderen Übersetzungsprogramm vorbereiten zu lassen. Dabei können die Änderungen erster Art mit berücksichtigt werden (siehe Kapitel 8). Im übrigen ist die Änderung mit Hilfe der einfachen Adressentranslation durch Indexregister und die Relativadressierung ohne weiteres anwendbar. 2. Änderungen zweiter Art Änderungen zweiter Art können bei Festspeicherprogrammen nicht in der Weise durchgeführt werden, daß im Anfang des Unterprogramms vorsorglich die Adressen berechnet und in das Programm eingesetzt werden. So kann zum Beispiel der Rücksprung in das Hauptprogramm nicht dadurch bewerkstelligt werden, daß die Ablaufnotierung im Akkumulator in das Unterprogramm übernommen wird und daß der Operationsteil eines Sprungbefehls dazuaddiert und der sich damit ergebende Rücksprungbefehl am Ende des Unterprogramms gespeichert wird. Genauso sind ParameterBlocktransporte an den Anfang des Unterprogramms ausgeschlossen. Dagegen können ohne weiteres die Methoden übernommen werden, bei denen die Parameter über Indexregister durch Adressentranslationen mit oder ohne anschließende Substitution aufgesucht werden. Auch die rekursive Unterprogrammtechnik ist anwendbar, wenn die Orientierung innerhalb des Arbeitsspeichers von einem Indexregister vermittelt wird. Stehen keine Indexregister zur Verfügung, so kann man die Änderungen 2. Art jeweils von einem besonderen Unterprogramm ausführen lassen, das mindestens teilweise im Aktivspeicher liegt. 3. Änderungen dritter Art Hier sind alle Verfahren ausgeschlossen, bei denen die jeweiligen Adressen im Befehlswort selbst gespeichert werden. Enthalten die Adressen dagegen

236

Systematische Behandlung der Adressenänderungen

nur das (unveränderliche) Inkrement oder beziehen sie sich überhaupt nur auf ein Indexregister, so können die Verfahren auch bei Festspeicherprogrammen angewendet werden. Auch hier müssen spezielle, zum Teil im Aktivspeicher liegende Programmteile aufgesucht werden, wenn keine Indexregister vorhanden sind1). 13. Übung: Es soll ein vereinfachtes Teilprogramm für eine Eisenbahn-Platzbuchung als Unterprogramm für Festspeicher aufgestellt werden. Dabei wollen wir voraussetzen, daß das Hauptprogramm in einem Aktivspeicher steht. Das Hauptprogramm liefert als Parameter eine Buchungsanfrage an das Unterprogramm. Diese Buchungsanfrage kann eine Anforderung eines, zweier oder dreier Plätze beinhalten. Die Abteile, die gebucht werden können, sollen im Aktivspeicher in einer Liste aufgeführt sein. Es sollen 1000 gleichberechtigte Abteile zur Verfügung stehen. Sie sind etwa in deu Speicherzellen 2000 . . . 2999 so notiert, daß jeweils ein Wort (neben anderen Informationen) in seinen niedrigsten sechs Binärstellen das Abbild eines Abteils mit sechs Plätzen enthält. Dabei sei etwa folgendes verabredet: Bit-Nr.

entspricht

33 34 35 36 37 38

Fensterplatz in Fahrtrichtung Fensterplatz rückwärts Gangplatz in Fahrtrichtung Gangplatz rückwärts Mittelplatz in Fahrtrichtung Mittelplatz rückwärts

Ist eine dieser Stellen mit einer Eins besetzt, so soll das heißen, daß der entsprechende Platz belegt ist. Ist dort eine Null, so ist der Platz noch frei. Das Buchungsprogramm soll nun je nach Typ der Anfrage (ein, zwei oder drei Plätze) den Speicher durchsuchen, bis es ein Abteil gefunden hat, in dem der Buchungswunsch befriedigt werden kann. Dann werden in diesem Abteil die Plätze belegt, und eine entsprechende Vollzugsmeldung wird dem Hauptprogramm zurückgemeldet. Diese Vollzugsmeldung soll die Nummer des Abteils und die Platznummern enthalten. Kann der ursprüngliche 1 ) Bei Festspeicherprogrammen sind die sogenannten Exekutiv-Sprünge sehr nützlich. Das sind Sprungbefehle, hei denen automatisch vom Sprungziel sofort wieder auf den Folgebefehl des Exekutiv-Sprunges zurückgekehrt wird. Auf diese Weise kann innerhalb des Festspeicherprogrammes schnell jeweils ein Befehl im Aktivspeicher ausgeführt werden.

Programmübersetzung

237

Buchungswunsch nicht befriedigt werden, so wollen wir folgende Fälle unterscheiden: a) Buchungswunsch ein Platz: Dann wird dem Hauptprogramm zurückgemeldet, daß die Buchung nicht vollzogen werden kann (Zug besetzt). b) Buchungswunsch zwei oder drei Plätze: Dann soll versucht werden, die Plätze auf mehrere Abteile zu verteilen. Die Vollzugsmeldung enthält dann zwei oder drei Abteilnummern mit den entsprechenden Platznummern. Beim Aufsuchen freier Plätze sollen jeweils zuerst die „besten" Plätze gebucht werden. Dabei gilt für die einzelnen Plätze eine Reihenfolge der Güte, die mit der Platznummernfolge 33, 34 ... 38 (Fensterplatz in Fahrtrichtung besser als Fensterplatz rückwärts usw.) übereinstimmt. Das bedeutet, daß bei einer Buchungsanfrage für einen Platz zuerst in allen Abteilen nach einem freien Platz Nummer 33 gesucht wird. Erst, wenn alle Nummern 33 besetzt sind, wird nach freien Plätzen Nummer 34 gesucht usw. Entsprechend gilt für die Güte von Platzkombinationen die Reihenfolge der arithmetischen Summen der Platznummern (33 + 34 besser als 33 + 35 usw.). Bei der Aufteilung auf mehrere Abteile gilt bei zwei Abteilen für jedes Abteil das gleiche wie für ein Abteil. Bei drei Plätzen ist jede Aufteilung auf zwei Abteile besser als eine Aufteilung auf drei Abteile. 8 Programmübersetzung Unter einer Programmübersetzung versteht man ganz allgemein die Überführung der Programme aus einer vorliegenden in eine bestimmte andere Form. Dabei denkt man in erster Linie an den Übergang zwischen verschiedenen Programmsprachen, also etwa an die Übersetzung einer problemorientierten oder einer maschinenorientierten Sprache in die Maschinensprache eines vorgegebenen Rechners. Diese Sprachübersetzungen sind aber nicht die einzigen Anwendungen der Programmübersetzung. Ehe wir uns einige Anwendungen betrachten, wollen wir zwei wesentliche Varianten der Programmübersetzung nennen, nämlich die interpretative und die erzeugende Übersetzung. Erzeugende Programme — oder Generatoren — erzeugen nach den in der Übersetzungsvorschrift festgelegten Regeln ein vollständiges Programm, das gespeichert oder ausgegeben werden kann, während interpretative Programme — oder Interpretationsprogramme — die jeweils nach den Übersetzungsregeln ermittelten Programmstücke sofort ausführen. Die Programme werden dabei also sozusagen nur umgedeutet.

238

Program m Übersetzung

8.1 Hauptanwendungen für Übersetzungsprogramme Wir wollen hier kurz die Hauptanwendungen für Programmübersetzungen zusammenstellen: 1. Übersetzung problem- oder maschinenorientierter schinensprache.

Sprachen in eine Ma-

Die häufigste Anwendung ist die Übersetzung problem- oder maschinenorientierter Sprachen in die Maschinensprache eines Rechners. Auf diese Anwendung werden wir weiter unten noch ausführlich eingehen. 2. Simulierung von Rechnern. Eine wichtige Aufgabe ist die Simulierung eines Rechners, des sogenannten Ausgangsrechners, durch einen zweiten, den sogenannten Objektrechner [60], [61]. Darunter versteht man die Nachbildung der Wirkungen eines jeden Befehls des Ausgangsrechners durch entsprechende Programme des Objektrechners. Solche Simulierungen sind um so schwieriger, je verschiedener die Rechner in ihrer Struktur sind. Sie werden außer bei der Entwicklung von Rechenanlagen und bei der Entwicklung von datenverarbeitenden Systemen vor allem in den folgenden beiden Fällen benötigt: a) Benutzung von Programmen einer anderen Maschine [62] Stehen von einer anderen Maschine Programme zur Verfügung, so ist es manchmal sparsamer, die andere Maschine kurzerhand zu simulieren, als neue Programme für die eigene Maschine zu schreiben. Diese Situation tritt besonders häufig dort auf, wo eine alte Maschine durch einen neuen modernen Rechner abgelöst wird. Es muß allerdings beachtet werden, daß durch die Simulierung eine erhebliche Verlangsamung des Programmablaufes entsteht. b) Programmierung eines Spezialrechners Spezialrechner haben häufig ein sehr geringes Maß an Programmierungsbequemlichkeit und sind wegen ihrer beschränkten Leistungsfähigkeit auch kaum in der Lage, sich diese Bequemlichkeit durch geeignete Übersetzungsprogramme zu verschaffen [57]. Daher schreibt man die Programme am besten extern in einer für den Menschen bequemen Form und läßt einen Universalrechner diese Programme in die Maschinen-

Hauptanwendungen für Übersetzungsprogramme

239

spräche des Spezialrechners übersetzen. Das Ausprüfen dieser Programme besorgt man dann am besten — vor allem, wenn es sich um Festspeicher Programme handelt — auch auf dem Universalrechner, indem man den Spezialrechner auf dem Universalrechner simuliert. Auf diese Weise erhält man auch auf dem Spezialrechner indirekt die gewünschte Programmierungsbequemlichkeit. 3. Umordnungsprozesse. Es ist häufig wichtig, ein Programm mit Rücksicht auf hohe Rechengeschwindigkeit in besonderer Weise umzuordnen. Hier sind vor allem zwei wichtige Umordnungsprozesse zu nennen: a) Umordnung mit Rücksicht auf Wartezeiten bei Trommeln-Speichern optimales Programmieren) [63], [64].

(zeit-

Soll ein Programm auf einer Trommelmaschine schnell durchlaufen, so muß dafür gesorgt werden, daß die Befehle und Zahlen unter Berücksichtigung der Operationszeiten auf der Trommel in einer Reihenfolge notiert sind, die kleine Wartezeiten garantiert. Um das zu erreichen, muß ein ursprünglich erstelltes Programm geeignet umgeordnet werden. Eine solche Umordnung ist besonders einfach bei Rechnern, die in jedem Befehl (wenigstens) eine Folgeadresse enthalten (siehe Seite 28). Die Befehle können dann beliebig umgeordnet werden, weil der Zusammenhang des Programms stets durch die Folgeadressen hergestellt wird. 30. Programm- Beispiel: Wir wollen als Beispiel das Skalarprodukt zweier Vektoren berechnen (vgl. 10. Programm-Beispiel) und dafür folgenden hypothetischen (3 + 1)Adreß-Code benutzen: Operationsteile: a a [i £ v

(Addition) (Subtraktion) (Multiplikation) (Verzweigung) (Nullbefehl)

*) Das gleiche gilt auch für die nur noch wenig verbreiteten akustischen Laufzeitspeicher.

Programmübersetzung

240

Der Nullbefehl soll ein Pseudobefehl mit der Eigenschaft v + (o

a>

sein, wobei o> eine beliebige Operation des Codes darstellt, und die Addition ( + ) mit dem Additionsbefehl (a) des Codes realisiert wird. Adressen: Es sind die Operanden-Adressen nv n2, n3 und eine, Folgeadresse ni vorgesehen. Ausführungszeiten: Das zeitoptimale Programmieren verlangt Kenntnisse über die Ausführungszeit der Befehle; denn die Befehlsfolge soll ja so eingerichtet werden, daß auf der Trommel der Folgebefehl gerade dann unmittelbar erreicht wird, wenn die laufende Operation abgeschlossen ist. Wir wollen hier die Ausführungszeiten in Adresseneinheiten a angeben. Das heißt, ein Befehl mit der Ausführungszeit a benötigt zu seiner Ausführung so lange, daß der Folgebefehl a Adresseneinheiten hinter dem Befehl stehen muß, wenn er anschließend ohne Wartezeit ausgeführt werden soll.

Befehle

a

Wirkung 4-

-+n3;

Folgebefehl

2



-> ii 3 ;

Folgebefehl

2

¡x nv n2, n3, w4

< W j > x < » 2 > ->w 3 ;

Folgebefehl

18

s"

wenn < W j > < 0 dann

Folgebefehl

1

wenn < w 1 > = 0 dann

Folgebefehl

wenn

Folgebefehl

xnv a

n2, n3, n4 tt2,

^

n3, w4

1 > ^2»

> 0 dann

Das Programm für die Berechnung des Skalarproduktes soll mit ähnlicher Speicheraufteilung arbeiten wie das 10. Programm-Beispiel (S. 113):

Hauptanwendungen für Übersetzungsprogramme

241

Speicherauf teilung : Nummer

anfangs

später

Darstellung

1000 • Programm 2000

«i

2009 2010

«10

2019 2020 2021 2022 2023 2024 2025

bio

GK



St, c



at x bi

¡i 2000, 2010, 2021, 1003 vi, 1,0,0 fi 2009, 2019, 2021, 1003

Befehle Prüfgröße für Zyklusende



Das Programm kann dann folgendermaßen aufgeschrieben werden: Programm: Nummer

Befehle

Bemerkungen 2020 0 H {a 0 }, {&„}, 2021, 1003

1000 a 2020,2020,2020,1001 1 a 2022,2020,1002,1002 1006->2 [p 2000,2010,2021,1003] 3 a 2020,2021,2020,1004

ai x bi + Sj.j

Beginn 1002

Si -> 2020

fi {ai}, {òi}, 2021, 1003 4

a 1002,2023,1002,1005

5 6

a 2024,1002,2025,1006 C 2025,1002,1002,1007

+ v 1, 1, 0, 0 fi {ai}, {bi}, 2021, 1003

1002

• wenn i ^ 10 dann Sprung nach 1002

1007 16 Güntsch, Digitale Rechenautomaten 2. Aufl.

Ende

Programmübersetzung

242

Wollen wir das Programm zeitoptimal schreiben, müssen wir die Ausführungszeiten a berücksichtigen und das Programm folgendermaßen umordnen: Programm: Nummer 1000

1028

Befehle Beginn

a 2020, 2020, 2020, 1002

1002

a 2022, 2020, 1004, 1004

1004

[fj, 2000, 2010, 2021, 1022]

1022

a 2020, 2021, 2020, 1024

1024

a 1004, 2023,1004,1026

1026



n

s> % + 1-

Das interpretierende Programm durchsucht nun alle Befehle des gespeicherten Programm.es und sorgt dafür, daß wie gewöhnlich einer nach dem anderen ausgeführt wird, bis ein Rufbefehl auftritt, auf den eine Zahl folgt. Dann werden, je nach dem Operationszeichen des Rufbefehls, folgende Operationen ausgeführt: *) Daa Rechnen mit komplexen Zahlen kann natürlich auch mit Ein- oder Zwei-Adreß-Befehlen organisiert werden.

Interpretative Programme

Befehl ± »1

n3

Wirkung ± ±

n3 + 1

• — • - + •

• < w 2 > + - 2 + < W 2 + 1>2

+

1

+ 1>

< % + 1 > • — < % > - < w 2 + 1 > 2+2 Für das Interpretationsprogramm können wir ganz grob folgendes Flußdiagramm skizzieren:

14. Ü b u n g : Es soll ein Interpretationsprogramm aufgestellt werden, das in der Lage ist, eine fremde Maschine auf der Z 22 zu simulieren. Der Befehlscode dieser l ) Zahlen h a b e n in den beiden obersten Stellen Nullen oder Einsen (siehe Seite 28 u n d Seite 257), so d a ß sie auf diese Weise leicht v o n Befehlen unterschieden werden k ö n n e n .

252

Programmübersetzung

Maschine sei der im 30. Programm-Beispiel (Seite 239) angegebene (3 + 1 )Adreß-Code. Das Interpretationsprogramm soll Programme, die in diesem Code geschrieben sind, verstehen und sie auf der Z 22 ausführen. 8.3 Erzeugende Programme Eine zweite Art von Übersetzungsprogrammen sind die Generatoren oder erzeugenden Programme. Diese Generatoren analysieren das Ausgangsprogramm und stellen daraus ein vollständiges Maschinenprogramm her. Dieses Programm wird gespeichert oder ausgeschrieben und später — unabhängig von der Übersetzung — bei Bedarf ausgeführt [68]. Es gibt zwei wichtige Spielarten der Generatoren: 1. Erzeugung in kleinen Abschnitten während der Eingabe, 2. Erzeugende Übersetzung eines Programmes, das vollständig gespeichert vorliegt. Die Erzeugung während der Eingabe wird in großem Umfang angewendet, tun aus Programmen, die in einer problem- oder maschinenorientierten Sprache abgefaßt sind, Maschinen-Programme herzustellen. Sie h a t drei wesentliche Vorteile: a) Bei der Erzeugung während der Eingabe braucht nichtdas ganze Ausgangsprogramm gespeichert zu werden. E s wird also bei langen Programmen viel Speicherraum gespart. b) Bei manchen Rechnern — wie z. B. bei der Z 22 — fällt bei der Eingabe nutzlose Wartezeit an, die durch die Übersetzung sinnvoll verwendet werden kann (vgl. Kapitel 12.2). c) Die Übersetzung k a n n mit einer sorgfältigen Prüfung des eingegebenen Programms auf formale Fehler verbunden werden, so daß der Lesevorgang beim Auftreten eines solchen Fehlers unterbrochen und das Programm zurückgewiesen werden kann. Bei der Erzeugung von Programmen t r i t t gegenüber der Interpretation bereits gespeicherter Programme folgende Schwierigkeit auf: Die neu berechneten Programme enthalten im allgemeinen weit mehr Befehle als das Ursprungsprogramm. Daher verschiebt sich das Adressenschema innerhalb des Programms so, daß der Generator das neue Programm nicht in einem Durchgang berechnen kann. So hängt zum Beispiel der wirkliche Wert einer nach vorn weisenden Sprungadresse davon ab, in welcher Weise der zwischen Sprungbefehl und Zieladresse liegende Programmteil durch die Übersetzung gespreizt wird.

Aufgaben der maschinenorientierten Sprache

253

Weiter läßt sich zum Vergleich zwischen Interpretation und Erzeugung noch folgendes sagen: Da das Programm im Fall der Interpretation selbst unverändert bleibt, muß es bei jedem Durchlauf von neuem übersetzt werden. Das Erzeugen erfolgt dagegen ein für allemal. Daher ist das Erzeugen bei Programmen mit vielen Durchläufen und bei Programmen, die häufig benutzt werden sollen, schneller als das Interpretieren. Dies gilt um so mehr, wenn Wartezeiten während der Eingabe für die Erzeugung ausgenutzt werden können. 9 Maschinenorientierte Sprachen und deren Verhältnis zur Maschinensprache Da wir im vorigen Kapitel einige programmtechnische Hilfsmittel zur Übersetzung von Programmen kennengelernt haben, wollen wir nun dazu übergehen, die bereits in der Einleitung beschriebene Stufenleiter der Programmsprachen, nämlich die Folge: Maschinensprachen, maschinenorientierte Sprachen und problemorientierte Sprachen, näher zu beschreiben. Daher wenden wir uns zuerst der maschinenorientierten Sprache und deren Verhältnis zur Maschinensprache zu. 9.1 Aufgaben der maschinenorientierten Sprache Wir haben bereits in der Einleitung ausgeführt, daß maschinenorientierte Sprachen vor allem benutzt werden, damit dem Menschen der Umgang mit dem Rechner erleichtert wird. Wir wollen nun einige wichtige Mittel besprechen, mit denen die maschinenorientierten Sprachen diese Vorzüge gegenüber den Maschinensprachen erzielen. 1. Plausible Abkürzungen für die Operationsteile der Befehle. Maschinensprachen verwenden für die Darstellung der Operationsteile im allgemeinen fortlaufende Zahlen verschiedener Zahlensysteme (z. B. Dualzahlen, Oktalzahlen oder Dezimalzahlen). Für den Menschen ist es aber günstiger, nach mnemotechnischen Gesichtspunkten ausgewählte Abkürzungen zu benutzen. So ist es zum Beispiel angenehmer, für Addition und Multiplikation die Zeichen + und x anstelle von Zahlen — etwa 03 und 97 — zu verwenden. 2. Dezimale Adressen. Bei Rechnern, deren Adressen intern im Dualsystem dargestellt sind, möchte man im allgemeinen extern Dezimaladressen benutzen. 3. Adressierung bei variabler Befehlslänge. Es gibt Rechner, die mit variabler Wortlänge arbeiten. Es sind dies vor allem Serienrechner mit einem

254 Maschinenorientierte Sprachen und deren Verhältnis zur Maschinensprache

Quellen-Senken-Code (vgl. Seite 30) ohne Akkumulator, bei denen Transporte aus einer Folge von Speicherzellen zeichenweise in eine andere solche Folge ablaufen (siehe etwa [69]). Die bei jedem Transport gewünschte Wortlänge kann mit Hilfe von im Speicher verteilten Wort-Grenzmarken oder mit Hilfe einer im Transportbefehl angegebenen Wortlänge bestimmt werden. Man findet variable Befehlslängen jedoch auch bei Parallelrechnern [70]. Durch diese Behandlung der Operanden ergeben sich eine Reihe von eigentümlichen Adressierungsaufgaben, auf die wir hier nicht weiter eingehen wollen. Zusätzliche Schwierigkeiten entstehen, wenn auch die Befehle variable Länge haben. Zur Bestimmung von Adressen, die auf Punkte innerhalb des Programmes verweisen (also insbesondere bei Sprung-Adressen), müssen die Längen der einzelnen Befehle des Programmes explizit bekannt sein und berücksichtigt werden. Das ist so umständlich, daß man in den maschinenorientierten Sprachen (wenn man keine symbolischen Adressen verwendet) zum mindesten eine befehlsweise Adressenfortzählung benutzt. Bei Programmübersetzung müssen dann die in der Maschinensprache gültigen Adressen für die Befehle automatisch eingesetzt werden. 4. Symbolische Adressen. Wie wir schon früher gesehen haben, ist die Handhabung absoluter Adressen sehr schwerfällig. Daher möchte man sich in den maschinenorientierten Sprachen mit symbolischen Adressen begnügen. 5. Bufbefehle. Häufig möchte man mit einem Befehl der maschinenorientierten Sprache Funktionen aufrufen, die in der Maschinensprache durch ein geschlossenes Unterprogramm realisiert werden sollen. Wir nennen solche Befehle Rufbefehle, wenn sie intern einem Sprungbefehl zu diesem Unterprogramm entsprechen. Typische Beispiele sind trigonometrische Funktionen. Bei der Z 22 haben wir schon in Kapitel 2.2 die Rufbefehle + , —, X, :, W, M, D, J kennengelernt. Sie rufen jeweils ein Unterprogramm für die Gleitkomma-Addition, -Subtraktion, -Multiplikation usw. auf. 6. Makrobefehle. Bestimmte Befehle der maschinenorientierten Sprache nennt man, aus dem Blickwinkel der Maschinensprache betrachtet, Makrobefehle. Dies sind Befehle, die im Maschinenprogramm nicht durch einen Sprungbefehl auf ein geschlossenes Unterprogramm, sondern durch ein offenes Unterprogramm realisiert werden, das im Maschinenprogramm anstelle des Makrobefehls eingefügt wird. Makrobefehle werden häufig für eine Änderung des Typs der Operanden gegenüber den im Befehlscode vorgesehenen Typen benutzt. Häufige Typänderungen sind: Festkomma-Zahlen/Gleitkomma-Zahlen reelle Zahlen/komplexe Zahlen

Aufgaben der maschinenorientierten Sprache

255

einfache Genauigkeit/mehrfache Genauigkeit skalare Größen/Matrizen Sollen also zum Beispiel mit einer Festkomma-Maschine Gleitkomma-Rechnungen durchgeführt werden, so sind Makrobefehle für Gleitkomma-Addition, -Multiplikation usw. sehr nützlich. 7. Organisation von Zyklen. Für Rechner, in deren Befehls-Code keine oder nur wenige Hilfsmittel zur Automatisierung der Zyklen vorliegen, empfiehlt sich die Verwendung einer entsprechend ergänzten maschinenorientierten Sprache. Bei deren Übersetzung in die Maschinensprache müssen die für die Bereitstellung der Anfangs- und Endwerte sowie für die jeweilige Prüfung auf Zyklusende nötigen Befehle eingesetzt werden. 8. Anschluß von Unterprogrammen. Genau wie bei der Organisation der Zyklen können extern auch Hilfsmittel für die Änderungen erster Art und vor allem für die Änderungen zweiter Art bereitgestellt werden. Die für den Anschluß der Unterprogramme nötigen Programmteile werden dann beim Übersetzen in die Maschinensprache automatisch eingesetzt. Wir haben in der Aufzählung dieser typischen Aufgaben einer maschinenorientierten Sprache die Reihenfolge so gewählt, daß ausgehend von einer einfachen umkehrbar eindeutigen Zuordnung zwischen den Befehlen der Maschinensprache und der maschinenorientierten Sprache die Übersetzung in die Maschinensprache immer komplizierter wird. Wir haben uns jedoch — wenigstens im Vergleich zu den problemorientierten Sprachen — verhältnismäßig eng an die Struktur der Maschinensprache angelehnt. Das ist typisch für die maschinenorientierte Sprache. Die Anlehnung an die Maschinensprache geht so weit, daß man bei maschinenorientierten Sprachen oft von externen Befehls-Codes spricht. Das heißt, man beschreibt dann die maschinenorientierte Sprache durch eine Liste von Befehlen und deren Wirkungen. Dem Benutzer steht damit ein erweiterter Befehlscode zur Verfügung, ohne daß in dessen Handhabung ein wesentlicher Unterschied zum eigentlichen Maschinencode besteht. Bei den problemorientierten Sprachen ist das im allgemeinen nicht mehr möglich, weil sie eine wesentlich kompliziertere Struktur aufweisen als die vergleichsweise primitiven „KommandoSprachen" [71]. Die Strukturähnlichkeit der maschinellorientierten und der Maschinensprache bewirkt — und das ist bei der Konzeption maschinenorientierter Sprachen meist ein wesentlicher Gesichtspunkt —, daß im allgemeinen auch in den maschinenorientierten Sprachen alle Möglichkeiten der Maschinen-

256

Maschinenorientierte Sprachen und deren Verhältnis zur]_Maschinensprache

spräche ausgenutzt werden können. Das heißt, es soll kein Maschinenprogramm geben, das nicht auch in der maschinenorientierten Sprache formuliert werden kann. Außerdem gilt schon für die niaschinenorientierte Sprache ein Grundsatz, der in noch höherem Maße für die problemorientierte Sprache von Bedeutung ist: Die Sprache soll weitgehende Möglichkeiten zur Einführung neuer Ausdrucksmittel enthalten. So wird man zum Beispiel möglichst nicht nur eine Reihe von Makrobefehlen vorsehen, sondern die Sprache sollte ein leistungsfähiges Definitionsschema enthalten, mit dessen Hilfe jeweils beliebige Makrobefehle neu eingeführt werden können [72]. Übersetzungsprogramme für die Umwandlung maschinenorientierter Sprache in die Maschinensprache werden englisch häufig Assembler oder Autocoder genannt. Die Benutzung dieser Ausdrücke innerhalb der deutschen Programmierungs-Fachsprache ist — von sprachlichen Gesichtspunkten ganz abgesehen — unseres Erachtens nicht sehr zu empfehlen, weil es mit sehr unterschiedlicher Bedeutung verwendet wird. Es ist nicht genau gegen das Wort Compiler abgegrenzt, das für die Übersetzung mehr problemorientierter Sprachen verwendet wird und gleichfalls nicht genau definiert ist [73], 9.2 Der interne Befehlscode der Z 22 In den Programmbeispielen haben wir uns bislang auf einen Befehlscode der Z 22 bezogen, der einer maschinenorientierten Sprache entspricht. Die Verwendung des eigentlichen Befehlscodes der Z 22 (des Maschinencodes) ist, abgesehen von den im Dualsystem dargestellten Adressen, extern normalerweise indiskutabel, weil er als Einzelbit-Code für den Menschen recht unhandlich ist. Er ist auch arithmetisch sehr elementar (selbst die Multiplikation ist nicht als Intern-Befehl vorgesehen, sondern muß erst init einem Unterprogramm aufgerufen werden). Die Z 22 wird, wie alle Maschinen dieser Art, erst durch die Verwendung einer geeigneten maschinenorientierten Sprache für den gewöhnlichen Rechenbetrieb praktisch brauchbar. Für bestimmte Aufgaben bietet aber der Maschinencode oder ein Extern-Code, der sich dem Maschinen-Code sehr eng anschließt, ausgesprochene Vorteile. Es handelt sich dabei um Aufgaben, bei denen die Informationen bitweise verarbeitet werden müssen; Beispiele sind Schaltalgebra, Sprachübersetzung und Simulierung von Rechenanlagen. Wir wollen hier den Intern-Code der Z 22 als Beispiel besprechen, um das Verhältnis von Maschinensprache und maschinenorientierter Sprache deutlich zu machen.

Der interne Befehlscode der Z 22

257

Befehlsliste: Alle Transporte benötigen eine Wortzeit 1 Ausnahme: O. Alle angeführten Wirkungen geschehen gleichzeitig j Bit Nr.

Name

Bedeutung bzw. Wirkung Bit 1 Bit 2

Kennzeichen für die Wortart: PP P

QQ Q Y

0 0 1 1

0 1 0 1

Wortart Positive Zahl Klartextwort Befehl Negative Zahl

^ 0 Befehl wird nur ^ 0 ausgeführt wenn: 4 2-->4 V -^4

0 1 1 Wirkung

->BR;




+1'

BZ

+->4; ^w;

->BR

< 4 > A ->4;

< « . > wird vor Ausführung des Befehls negiert. Bei CG2) wird
negiert

SA SI

F

K

KG: Siehe Bit Nr. 19 KG: Es wird nur der Schnellspeicher gemäß s gewählt. Die Trommelspeicherauswahl wird unterdrückt. K: Es wird < n > = < s > V < i > aufgerufen3) B s + t : V-^4; T s + t : ->M

H

(3)3

Stop

Z

Kombination

1. Wortzeit

2. Wortzeit

CGK

( < « > V « > ) , - * < G, s werden gelöscht. GK, s werden gelöscht. CGK, s werd. gelöscht. « 3 > +t)t->t

CG

wie

G GK G

in allen 4 Fällen

+

t

-+S

G, s werden gelöscht.

CGK +1'^BZ

Befehl wird mit den restlichen Op.-Zeichen und der geänderten Adresse ausgeführt.

') A V / bedeutet: Bei Ä oder I . ') CO bedeutet: Wenn der Befehl außerdem C, aber nicht gleichzeitig 0 enthält. ') < « > V und < 4 > wird als VLLR: I Wort doppelter Länge gemeinsam verschoben.

s

S chnellspeicheradresse

t

Trommelspeicheradresse

21 •

25 26 •

38 Bemerkungen zum B e f e h l s c o d e der Z 22 Zu Bit 1 und 2 Diese zwei Bits eines jeden Wortes kennzeichnen die Wortart; sie geben also an, ob es sich um eine positive oder negative Zahl handelt oder ob das Wort einen Befehl oder ein Klartextwort darstellt. Diese Kennzeichnung der Wortart ist besonders wertvoll für das Ausprüfen von Programmen, bei der Programmirrläufer häufig daran erkannt werden können, daß Befehle an Speicherplätzen stehen, wo Zahlen oder Klartextwörter hingehören und umgekehrt. Weiter ist die Kennzeichnung der Wortart für ProgrammÜbersetzungen wichtig, weil diese Kennzeichnung die Möglichkeit bietet, die Übersetzung auf einfache Weise auf bestimmte Wortarten zu beschränken. Die Kennzeichnung positiver bzw. negativer Zahlen durch zwei Nullen bzw. Einsen in den ersten Stellen des Wortes ist schon in Kapitel 2 beschrieben worden. Die Festlegung über die Kennzeichnung von Befehlen und Klartextwörtern ist willkürlich. Befehle erscheinen also im Zusammenhang mit den Bedingungsabfragen P ,PP, Q und QQ als negativ. Bei den Klartextwörtern handelt es sich um Wörter mit willkürlichen Null-Eins-Mustern. Es ist dabei besonders an Wörter gedacht, die sieben Fernschreibzeichen zu je fünf Bits enthalten. Zu Bit 3 bis 7 Die Bedingungen sind bereits früher eingeführt worden. Hinzu kommt lediglich Y, das für die Multiplikation von Dualzahlen benötigt wird. Die 17«

260

Maschinenorientierte Sprachen und deren Verhältnis zur Maschinensprache

Multiplikation wird, wie wir schon erwähnt haben, durch Programme erledigt. Sie geht nach folgendem Schema vonstatten: Das Produkt wird durch wiederholte Addition des Multiplikanden {MD) aufgebaut. Dabei wird der Aufbauwert (^1) jeweils um eine Stelle nach rechts verschoben. Der Additionsvorgang wird durch den Ziffernwert der einzelnen Stellen des Multiplikators {MB) gesteuert. Ist eine Multiplikatorstelle gleich eins, so wird MD zu A addiert, sonst nicht. MB wird im Schnellspeicher 3 untergebracht und mit jedem Schritt um eine Stelle nach rechts verschoben, so daß in der letzten Stelle jeweils die Multiplikatorstelle steht, die entscheidet, ob addiert wird oder nicht. Für A und MB genügt zusammen das Schnellspeicherpaar 3 und 4, weil im gleichen Maße, wie die Stellenzahl von A wächst, diejenige von MB durch die Rechtsverschiebung abnimmt. 3 und 4 sind daher als gemeinsam verschiebbare Doppelregister ausgelegt (vgl. V). Wir wollen ein vereinfachtes Beispiel für die Multiplikation zweier Mantissen von Gleitkomma-Zahlen angeben. Dabei haben wir der Einfachheit halber statt 31 Stellen nur 8 Stellen aufgeschrieben. Die Kommastellung ist durch dünne vertikale Linien angedeutet: Multplikand 00011011 Aufbauwert

Multiplikator

00 000000

00 10110 1 Addieren

00 011011 00 001101

10 010110

.Rechtsverschieben

00 000110

11 001011

B A

00 100001 00 010000

11 100101

B A

00 101011 00 010101

11 110010

B

00 001010

11 111()01

B A

00 100101 00 010010 Produkt

11 111] 0 0

B

Der interne Befehlscode der Z 22

261

Die Bedingung Y trägt also wesentlich zur Beschleunigung des Multiplikationsprogrammes bei1). Bei bedingten O-Befehlen werden die Adressenänderungen auch dann ausgeführt, wenn die Ausführung des eigentlichen Befehls auf Grund der Bedingung unterbunden wird. Es ist auch erlaubt, in einem Befehl mehrere Bedingungszeichen unterzubringen. Die resultierende Bedingung setzt sich dann konjunktiv aus den Einzelbedingungen zusammen. Das heißt, es müssen jeweils alle zu den einzelnen Bedingungszeichen gehörenden Bedingungen erfüllt sein, damit der Befehl ausgeführt wird. Eine Ausnahme bildet die Kombination PPQQ, mit der geprüft werden kann, ob der Akkumulatorinhalt gleich Null ist. Zu Bit 8 CE kann in Verbindung mit dem Handschalter „Bedingter Stop" zur Realisierung eines vom Bedienungspult gesteuerten Maschinenstops benutzt werden (vgl. Schnellspeicher 17, Seite 268). Dabei wird der Umstand ausgenutzt, daß der Rechner bei eingelegtem Handschalter jedesmal, weim ein nicht durch das entsprechende Kennzeichen für die Wortart ordnungsgemäß als Befehl gekennzeichnetes Wort in das Befehlsregister gelangt, anhält. Schreiben wir einen Befehl CE n in das Programm, so wird
= n und = E n + 1 (siehe Bit 12 und 13, Seite 262). Ist der Handschalter nicht eingelegt, so wird als nächstes der in n + 1 stehende Befehl ausgeführt (Sprung auf n + 1). Ist der Handschalter eingelegt, so führt
— n zu Stop. Wird der Rechner wieder gestartet, so springt das Programm ebenfalls auf n + 1. Zu Bit 10 Bei der Linksverschiebung werden am rechten Wortende Nullen nachgezogen, während die links über die Wortgrenze hinaustretenden Ziffern verlorengehen. Das heißt, jede Linksverschiebung stellt eine vorzeichenrichtige Multiplikation mit zwei dar, solange bei positiven Zahlen keine Eins und bei negativen Zahlen keine Null in die Vorzeichenstellen einwandert. Zu Bit 11 Bei der Rechtsverschiebung wird links jeweils eine Null oder eine Eins nachgeschoben, je nachdem, ob vor der Verschiebung die oberste (Vorzeichen-) Stelle eine Null oder eine Eins war. Bei positiven Zahlen werden 1 ) Will man die Multiplikation noch weiter beschleunigen, so muß man dafür sorgen, daß nur die Addition, nicht dagegen die Rechtsverschiebung, bedingt wird. Damit benötigt die Multiplikation nur noch einen Befehl pro Hultiplikatiorstelle [74].

262 Maschinenorientierte Sprachen und deren Verhältnis zur Maschinensprache

also von links Nullen und bei negativen Zahlen Einsen nachgeschoben. Die rechts über die Wortgrenze hinauswandernden Ziffern gehen verloren. Das bedeutet, daß bei der Rechtsverschiebung vorzeichenrichtig mit 1 / 2 multipliziert wird, wobei durch den Verlust der niedrigsten Stelle jeweils nach unten gerundet wird. Allerdings wird bei negativen Zahlen nie exakt < 4 > = 0 erreicht, weil beim Auswandern der letzten Null stets < 4 > = 1 1 ... 11 erhalten bleibt. Diese Information entspricht der kleinsten negativen Zahl, die überhaupt darstellbar ist. Zu Bit 12 und 13 Bit 12 und 13 sind im Gegensatz zu den meisten übrigen Bits des Operationsteiles verschlüsselt; denn die vier Befehle E, A, U und I schließen sich gegenseitig aus. Wir wollen hier die Vorgänge im Befehlswerk etwas näher beschreiben. Es soll dabei insbesondere klar werden, auf welche Weise es erreicht wird, daß die Befehle, mit Ausnahme der Sprungbefehle, die Reihenfolge durchlaufen, in der sie im Speicher stehen. Die Zeichen A, U und I haben außer der Wirkung auf das Rechenwerk auch einen Einfluß auf das Leitwerk, der bewirkt, daß bis zum Auftreten eines Sprungbefehls (E), die Befehle in der Reihenfolge aufgerufen und ausgeführt werden, in der sie auf der Trommel gespeichert sind. Durch einen Sprungbefehl wird diese Folge unterbrochen und statt dessen die Abwicklung einer neuen Befehlsfolge eingeleitet. Dabei liefert die Adresse des Sprungbefehls den Anfangspunkt für die neue Folge. Bei den meisten Rechenmaschinen ist zu diesem Zweck ein besonderer Zähler, der sogenannte Befehlszähler, vorgesehen, der durch die Adresse der Sprungbefehle eingestellt und jeweils nach der Ausführung eines jeden Befehls um eins weiter geschaltet wird. Dieser Zähler steuert dann die Speicherauswahl und bewirkt, daß die Befehle in der vorgesehenen Reihenfolge dem Speicher entnommen und dem Leitwerk zugeführt werden. Eine andere Möglichkeit ist von van der Poel [12], [13] angegeben und auch in der Z 22 benutzt worden. Bei dieser Anordnung ist kein besonderer Zähler vorgesehen, sondern ein Sprungbefehl kreist dauernd von BR nach BZ und zurück. Das zwischen BR und BZ eingebaute Addierwerk (vgl. das Blockschaltbild auf Seite 17) erhöht die Adresse der von BR nach BZ transportierten Befehle stets um eins, so daß der umlaufende Sprungbefehl nach jedem Durchlauf mit einer um eins weitergeschalteten Adresse im Befehlsregister steht und auf diese Weise einen Befehl nach dem anderen aus dem Speicher holt.

263

Der interne Befehlscode der Z 22

Diese Befehle werden auch jeweils mit Adressenerhöhung nach BZ gebracht, wandern aber nur dann zurück nach BR, wenn sie Sprungbefehle sind. In diesem Falle ist die ursprüngliche Befehlsfolge unterbrochen, und von nun an beginnt der eingeschriebene Sprungbefehl einen eigenen Zyklus B R ^ B Z ^ B R usw. Dieser Ablauf sei an einem einfachen Beispiel noch einmal erläutert. Speicher

Ablauftdbelle

Nummer

300 301 302

BR

BZ

B 517

E 301

E

301

B 518

S

526

E 302

E 302

S 527

¿—10 (sei ^ 0)

E 303

i— 10

\ E 601

i— 10

Inhalt

B 517 526 8 PPE 600

PPE 600 B 511

517

i

526

10

600

B

E

601

\

/

B 512

Akkumulator

2 4,6. Zu Bit 21 bis 2-5 Die Stellen 21 bis 25 dienen zur Adressierung der Schnellspeicher. Da mit fünf Bits 32 Adressen (0 bis 31) gebildet werden können, erfassen diese Stellen nicht nur die von uns bisher benutzten 16 Schnellspeicher (0 bis 15), sondern auch die sogenannte Schnellspeichererweiterung (16 bis 31). Wir wollen hier noch einmal die schon bekannte Sonderstellung einiger Schnellspeicher sowie die noch nicht besprochenen Ein- und Ausgabe-Befehle, die auch mit Schnellspeicheradressen arbeiten, zusammenstellen. Schnellspeicher 0 Unter der Adresse 0 ist die Zahl Null (eine Folge von 38 Nullen) zu erreichen. In diese Speicherzelle kann nichts eingeschrieben werden. Schnellspeicher 1 Unter der Adresse 1 ist die — an sich nicht zugelassene — Festkommazahl 2, oder besser gesagt, der Befehl E 0 zu erreichen. Auch in die Zelle 1 kann nichts eingeschrieben werden.

Der interne Befehlscode der Z 22

267

Schnellspeicher 2 Schnellspeicher 2 ist ein Prüfspeicher, auf dessen Inhalt sich die beiden Bedingungen P und Q beziehen. Er besitzt außerdem normale Speicherfunktionen. Schnellspeicher 3 Schnellspeicher 3 fungiert als ,,rechte" oder „untere" ,,Akkumulatorhälfte''. Das heißt, 3 kann zusammen mit 4 als ein Akkumulator von zweifacher Wortlänge aufgefaßt werden. Das hat den Zweck, bei der Multiplikation zweier Wörter das Produkt doppelter Länge einfach zu bilden und zur Weiterverarbeitung aufzubewahren. Zu dieser Sonderstellung wird 3 durch die Operationszeichen H, Y und V befähigt. Außerdem hat die Zelle 3 normale Speicherfunktionen. Schnellspeicher 4 Schnellspeicher 4 ist der eigentliche Akkumulator bzw. — im Gegensatz zu 3 — die „linke1' oder „obere" „Akkumulatorhälfte". 4 hat normale Speicherfunktionen, wird aber dadurch ausgezeichnet, daß sich die meisten Befehle auf seinen Inhalt beziehen. Außerdem dient er wie 2 als Prüfspeicher (Bedingung PP, QQ, PPQQ). Schnellspeicher 5 Schnellspeicher 5 dient in Verbindung mit F zur Speicherung der Ablaufnotierung. Außerdem hat er normale Speicherfunktionen. Schnellspeicher 6 Schnellspeicheri-elle 6 dient im Zusammenhang mit einigen Rufbefehlen (wie + , —, X, : usw.) als ein ausgezeichnetes Register. Diese Sonderstellung ist aber mir das Ergebnis einer Programm-Vereinbarung. Das heißt, die Unterprogramme, die durch diese Rufbefehle aufgerufen werden, sind so abgefaßt, daß sie einen Operanden aus 6 beziehen und das Ergebnis dort niederlegen. Technisch bzw. durch den Maschinencode ist Speicherzelle 6 in keiner Weise ausgezeichnet. Sie hat nur normale Speicherfunktionen. Schnellspeicher 16 Unter dieser Adresse ist der Schnellspeicher 5 erreichbar. Es kann aber nur gelesen werden. Diese Verdoppelung von 5 hat den Zweck, Zählvor-

268

Maschinenorientierte Sprachen und deren Verhältnis zur Maschinensprache

gänge, wie sie in der Anmerkung 4 des 21. Programm-Beispieles (Seite 269) beschrieben werden, auch in dem Fall zu benutzen, daß der Sprungbefehl, der aus dem Zyklus hinausführt, eine im Schnellspeicher 5 stehende Ablaufnotierung ist. Würden wir 5 direkt verwenden, so müßten wir bei jedem Rücksprung im Zyklus den Akkumulator räumen, um den entsprechenden Sprungbefehl dort hinzubringen. Schnellspeicher 17 Unter dieser Adresse wird ein Handschalter am Bedienungspult erreicht. Ist dieser Schalter eingelegt, so führt ein Stop-Befehl (Z) mit der Schnellspeicheradresse 17 zu einem Maschinenstop. Ist der Handschalter in der Stellung aus, so wird der Befehl übergangen. Schnellspeicher 19 und 20 Diese Schnellspeicheradressen kennzeichnen die Ein- und Ausgabegeräte: Als Eingabe sind bei der Z 22 5-Kanal-Lochstreifensender (also Lochstreifenleser) vorgesehen, während als Ausgabe 5-Jianal-Fernschreib-Blattschreiber mit angekuppelten Lochstreifenempfängern (also Lochstreifenstanzern) dienen. Die normale Ein- und Ausgabe benutzt mechanische Geräte (mit etwa 10 Zeichen pro Sekunde), während als Schnelleingabe auch ein photoelektrischer Lochstreifensender (mit etwa 200 Zeichen pro Sekunde) angeschlossen werden kann. Die mechanischen Geräte sind über die Schnellspeicheradresse 20 und der photoelektrische Lochstreifensender über die Schnellspeicheradresse 19 erreichbar. Für die Eingabe wird der Befehl A 19 oder A 20 (bzw. B 19 oder B 20) benutzt. Er bewirkt, daß jeweils ein Fernschreibzeichen aus einem 5-BitPufferregister durch einen vollen (38-Bit-)Worttransport an das Ende des Akkumulators transportiert und gleichzeitig ein Lochstreifentransport zum folgenden Fernschreibzeichen bewirkt wird. Sobald die nächste 5-LochKombination an den Lesefühlern des Lochstreifensenders angekommen ist, wird das neue Fernschreibzeichen in den Puffer übernommen. Von dort kann es durch einen neuen Lesebefehl übernommen werden. Bei der Ausgabe werden mit Hilfe eines Befehls U 20 (bzw. T 20) durch einen vollen Worttransport die obersten fünf Bits des Akkumulatorinhalts in ein Pufferregister transportiert und der Druck- bzw. Stanz-Vorgang ausgelöst. Sobald der Blattschreiber wieder druckbereit (und der Lochstanzer nach dein anschließenden Streifentransport wieder stanzbereit) ist, kann ein neues Zeichen ausgegeben werden.

Der interne Befehlscode der Z 22

269

Tritt im Programm ein neuer Lese- oder Druckbefehl auf, bevor das Pufferregister wieder abgabe- bzw. aufnahmebereit ist, wartet die Z 22 mit der Ausführung des Befehls so lange, bis dem Leitwerk die Lese- bzw. Druck bereitschaft gemeldet worden ist. Als Beispiel für die Benutzung der Maschinensprache wollen wir folgendes Programm-Beispiel betrachten, aus dem hervorgeht, wie vielfältige Möglichkeiten der Interncode eines flexiblen Rechners dem Programmierer bietet, das aber auch zeigt, daß die Benutzung dieses Codes recht umständlich ist 1 ). 21.

Programm-Beispiel:

E s sollen nach folgendem bei [76] angegebenen Verfahren Pseudozufallszahlen berechnet werden: xi+i xi ( 2 ° + 1) + c mod 2 3 5 mit a ^ 2 und ungeradem c. Wir wollen ein Programm mit a = 7 und c = 3 angeben 2 ). Als Anfangswert benutzen wir x0 = 3141592703.

Weiter geben wir einen Bereich B (etwa 0 < B < 109) an, in dem die gewünschte Zufallszahl yk+l liegen soll (k = 0, 1, 2, ...): 0 Hyk+1 .1

n' für Pol -> .2

Sicherstellen der Ablaufnotierung Sprung nach Programm Nr. 13 Pol x2 B{a n } — n', später — i '

Parameter für Pol

Ablaufnotierung ->-11

.1

6 11+0 3|

x x Pol (x2, a, 4)

-sin(x)

11+0 4 11 + 1

.3

Rücksprung auf das übergeordnete Programm

1 — 0,16667 0,0082517 — 0,00019619 0,0000025771 19 Oüntsch, Digitale Rechenautomaten 2. Aufl.

290

Maschinenorientierte Sprachen und deren Verhältnis zur Maschinensprache

Nummer

Befehl Op.

p = 13: Programm Pol, mit Lp = 2

.2 = 13 B T GKB

u 1 = 2 =

T

IIP T GKB Ilz X CGKB Ilz

+

5 11 11 + 1 oll 2 + .1 Uli 6 11+0 2 II 2 + 8191 3 II

GKB Ilz CA GKU Ilz QQE

11+2 4 II 1 11+2 5 II .2

B GKT Ilz GKE

6 11+0 6 II 11+3

. = 31 1,06938 0,03 0,630 0,00275

Bemerkungen

Adr.

Ablaufnotierung ->-11 B{an}^

2,.l

an -s>6

x x p + a-»•

p

i —1

wenn — i' < 0 dann Sprung nach .3

Rücksprung auf das übergeordnete Programm p — 31: Zahlenfolge xt

Problemorientierte Sprachen

Befehl

Nummer

Op.

291

Bemerkungen

Adr.

— 0,6570 . = 97

p = 91: Zahlenfolge sin(xi)

. . 81

Prüfung auf Vollständigkeit der Liste der symbolischen Adressen Sprung auf Programm Nr. 81

10 Problemorientierte Sprachen1) Die problemorientierten Programmsprachen sind nicht mehr an bestimmte Rechner gebunden. Sie sind vielmehr den Erfordernissen eines bestimmten Aufgabengebietes angepaßt und berücksichtigen vor allem, daß die Programme von Menschen mit der Hand oder einer Schreibmaschine niedergeschrieben werden müssen. In der Einleitung haben wir bereits bemerkt, daß die aufgabenorientierten Sprachen entweder operative (oder Verjahrens-)Sprachen oder deskriptive

Sprachen

sein können. Das heißt, daß sie mehr für die Beschreibung von Lösungsverfahren oder mehr für die Beschreibung einer bestimmten Aufgabenstellung gedacht sind. In jedem Fall sind sie in ihrer Struktur wesentlich komplizierter als die maschinenorientierten Sprachen, in denen im allgemeinen die Formulierung und Wirkung der einzelnen Befehle unabhängig von anderen Befehlen festgelegt ist (Kommandosprache). Da sich aber der Mensch, wie die natürlichen Sprachen und die weitverbreiteten mathematischen Kalküle beweisen, ') Siebe hierzu das Übersichtsreferat [71] von F. L. Bauer und K. Samtlson, sowie die Darstellung von 21. Boüenbruch [1]. 19*

292

Problemorientierte Sprachen

unter bestimmten Voraussetzungen gerade in solchen komplizierten Sprachen besonders wirksam ausdrücken kann, bedeutet es einen erheblichen praktischen Vorteil, wenn der Programmierer eine solche problemorientierte Sprache statt der primitiven maschinengebundenen Sprache benutzen kann. Dies leuchtet unmittelbar ein, wenn man vergleicht, wie einfach für jeden etwas Vorgebildeten ein arithmetischer Ausdruck zu begreifen ist, wenn er in einer der üblichen Formelsprachen vorliegt. Dagegen empfinden wir es als unbequem, ja geradezu unzumutbar, einen komplizierten arithmetischen Ausdruck in Form eines Maschinenprogrammes aufzunehmen. Es ist daher schon heute abzusehen, daß in wachsendem Umfang kompliziertere Sprachen verwendet werden. Damit kommt diesem Arbeitsgebiet eine ganz besondere Bedeutung zu. 10.1 Operative Sprachen Die ersten Arbeiten auf dem Gebiet der problemorientierten Sprachen sind von K. Zuse durchgeführt worden. Er entwickelte bereits in den Jahren 1938—1945 einen sogenannten Plankalkül, eine Verfahrenssprache, die dazu bestimmt war, Rechenprozesse allgemeiner Art präzise und ohne Bezug auf einen bestimmten Rechner zu formulieren [3], [4], [8]. Dieser Kalkül unterscheidet, wie moderne Verfahrens-Sprachen, die Datenbeschreibung von der eigentlichen Verfahrensbeschreibung. Obgleich einige Elemente dieses Kalküls, wie zum Beispiel das Ergibtzeichen, allgemein gebräuchlich geworden sind, haben sich die Programmsprachen — orientiert an der Erfahrung im praktischen Einsatz der Rechner — in etwas anderer Richtimg entwickelt. Insbesondere hat man statt der großen Allgemeinheit des Plankalküls die Sprachen von vornherein stark festgelegt, so daß sie wesentlich bequemer benutzt werden können. Der erste Schritt zu einer praktischen Lösimg, der mit der Formulierung und vor allem der automatischen "Übersetzung von Algorithmen zusammenhängenden Aufgaben wurde von H. Butishauser getan, der sich vor allem mit der Übersetzung arithmetischer Ausdrücke, der sogenannten Formelübersetzung, befaßt hat [5]. 10.11 Formelübersetzung Bei der Formelübersetzung handelt es sich darum, einen durch Klammern gegliederten Ausdruck (Klammerausdruck) abzubauen und die zugehörige lineare Befehlsfolge aufzustellen. Diese Aufgabe wird bei Butishauser dadurch gelöst, daß jedem Element des Klammerausdruckes bestimmte Be-

Operative Sprachen

293

gleitwerte zugeordnet werden, die die Art der Elemente kennzeichnen (z. B. Befehle für Operatoren und Adressen für Operanden) und außerdem jeweils den Verschachtelungsgrad des Elementes angeben. Diese Begleit werte werden dann in mehreren Reduktionsschritten so abgearbeitet, daß die am stärksten verschachtelten Teilausdrücke aufgesucht und die zugehörigen Teilprogramme bestimmt werden. Dabei wird für die Zwischenergebnisse eine fortlaufende Folge von Speicherzellen bereitgestellt. Beispiel: Der Abbau des arithmetischen Ausdrucks a — ((& + c) x d — e)// + (g — h) x i kann folgendermaßen veranschaulicht werden: Wir verklammern den Ausdruck vollständig und fügen ein Kennzeichen für das Ende des Ausdrucks e hinzu 1 ): a — ((((& + c) x d) — e)lf) + ((g — h)x

i) e

Weiter zeichnen wir über den Ausdruck einen Polygonzug, der die den Verschachtelungsgrad der einzelnen Elemente kennzeichnenden Begleitwerte repräsentiert. Verschachtelungsgrad 5

U 3 2

1 0 a

- ( ( ( ( b + c ) * d ) - e ) / f ) + ( ( g - h ) * i ) E

Bei Operanden und öffnenden Klammern wird jeweils ein Schritt nach oben gemacht, während der Polygonzug bei Operatoren, schließenden Klammern und beim Schlußzeichen um eine Stufe absinkt. *) In der bisher von uns benatzten algorithmischen Sprache kann das Ende eines Ausdrucks, wenn er als rechte Seite einer Ergibt-Anweisung steht, zum Beispiel durch ein Semikolon oder das Wort Ende erkannt werden. In anderen Fällen lassen sich jeweils andere Merkmale fQr das Ende eines Ausdrucks angehen.

294

Problemorientierte Sprachen

Reduziert wird in acht Schritten. Die jeweils bei einem Schritt auftretenden Veränderungen des Ausdrucks sowie seines Polygonzuges zeichnen wir nacheinander auf und schreiben rechts daneben, welches Programmstück bei diesem Schritt entstanden ist. Wir benutzen den Code der Z 22 und haben in diesem Beispiel angenommen, daß für die Zwischenergebnisse Zv Z2.. .Z1 die Speicherzellen 2001, 2002 ...2007 vorgesehen sind.

Operative Sprachen

295

Das Rutishausersche Verfahren geht davon aus, daß der ganze Ausdruck geschlossen im Speicher des Rechners vorliegt, ehe der Übersetzungsprozeß beginnt. Es sind später vor allem von K. Samekon und F. L. Bauer [81 ] verbesserte Verfahren angegeben worden, die es gestatten, solche Ausdrücke in einem Durchgang abzubauen. Man nennt dies Verfahren sequentielle Formelübersetzung. Dazu haben Samelson und Bauer die Stapelmethoden eingeführt, die

296

Problemorientierte Sprachen

wir schon bei der rekursiven Unterprogrammtechnik (Kap. 6.3) kennengelernt haben [82], Da die Übersetzung algorithmischer Sprachen neben den bereits behandelten Adressierungsmethoden vor allem die bei der Übersetzung arithmetischer Ausdrücke benötigten Verfahren benutzt, wollen wir auf die sequentielle Übersetzung arithmetischer Ausdrücke etwas genauer eingehen. Wir folgen dabei im wesentlichen der Darstellung bei [81]. Um die wichtigsten Dinge besser herauszuarbeiten, beschränken wir uns auf die Übersetzung arithmetischer Ausdrücke, die nur durch Klammern gegliederte und durch die arithmetischen Operatoren + > —, x und / verbundene Variable enthalten. + und — sollen dabei stets mit zwei Operanden verwendet werden. Im Gegensatz zum letzten Beispiel, bei dem wir neben der Zweistelligkeit der Operatoren auch die vollständige Verklammerung benützt haben, sollen hier die Prioritäten zwischen den arithmetischen Operatoren auch ohne Klammern berücksichtigt werden. Die Namen der Variablen sollen jeweils aus einem Zeichen bestehen, und das Ende des Ausdrucks soll wieder durch ein Schlußzeichen s erkannt werden. Der Übersetzungsprozeß läuft nun so ab, daß alle Zeichen des Ausdrucks — zxnn Beispiel während der Eingabe in die Rechenmaschine — von links nach rechts gelesen und verarbeitet werden. Dabei werden alle Zeichen, die nicht sofort ausgewertet werden können, in einem Zeichenstapel Z abgelegt. Z wird von einer Zählgröße £ (f = 0 , 1 , 2 . . . ) gesteuert. Die jeweils zuoberst liegende, also unmittelbar erreichbare Zelle, innerhalb Z nennen wir Zr. Das bei der Übersetzung entstehende Maschinenprogramm benutzt für die Auswertung des Ausdrucks auch einen Stapel, den Operandenstapel Q. Er wird durch eine Größe CD (cd = 0 , 1 , 2 . . . ) gesteuert. Die oberste Zelle in Q nennen wir wieder Q m . Q nimmt die während der Berechnung des Ausdrucks auftretenden Operanden und Zwischenergebnisse auf. Die Zählgrößen f und tu treten explizit nur während des Übersetzungsprozesses auf. m bestimmt dabei die Adressenteile der Befehle, die später bei der Berechnung des Ausdrucks die Operanden und Zwischenergebnisse nach Q bringen oder sie von dort entnehmen. Es gibt allerdings Rechner mit stapelndem Akkumulator [83],[84],[85] 1 ), bei denen für Q keine besonderen Adressen benötigt werden. Ein stapelnder Akkumulator besteht — ähnlich wie die stapelnden Indexregister (vgl. Seite 225) — aus mehreren Stufen, von denen jeweils die oberste als der Akku*) Andere Vorschläge für maschinelle Vorrichtungen zur Formelübersetzung bei [86] bis [89].

Operative Sprachen

297

mulator des Befehlscodes fungiert. Das Herauf- oder Hinunterschalten des Stapels erfolgt durch geeignete Zusätze in den Operationsteilen der Befehle. I n diesem Fall brauchen bei der Übersetzung für den Umgang mit Q keine Adressen berechnet zu werden. Das laufende Herauf- und Hinunterschalten des Operandenstapels wird als Zusatzanweisung in die bei der Übersetzung erzeugten Befehle übernommen. Noch weitergehende Stapelvorrichtungen sind stapelnde Speicher, bei denen nicht nur mehrere Stufen eines Registers (etwa des Akkumulators), sondern konsekutive Speicherzellen angesprochen werden. Ein Ausführungsbeispiel [90] besteht aus zwei Registerstufen (A) und (B), die (wegen der Zugriffszeit) dem Eingang zum eigentlichen Speicherstapel vorgelagert sind. Ein besonderes Adressenregister (S) enthält zuerst den Anfangswert des Speicherstapels und registriert später die jeweils aktiven Speicherstufen.

Wir nennen die beim Übersetzungsprozeß jeweils gelesenen Zeichen T und unterscheiden hinsichtlich ihrer Behandlung zwei Hauptgruppen: die Namen (N) und die übrigen Zeichen; das sind —, x , /, (, ) und e. Wir wollen hier kurz die in diesem Abschnitt verwendeten Bezeichnungen zusammenstellen: Z c Zr Q

Zeichenstapel Zählgröße für Z oberste Zelle in Z Operandenstapel

298

Problemorientierte Sprachen

a>

r

N M z

Zählgröße für Q oberste Zelle in Q Jeweils gelesene Zeichen Namen Übergangsmatrix Ein < Z f > entsprechender Z22-Befehl (sofern ein Operator ist).

Bei jedem auftretenden Namen wird zu dem bereits vorliegenden Teilprogramm ein Programmstück hinzugefügt, das bei seiner späteren Ausführung bewirkt, daß der Inhalt der durch den Namen bezeichneten Speicherzelle1) nach Qm transportiert wird. Außerdem wird et) um eins erhöht. Legen wir für das Maschinenprogramm den Code der Z 22 zugrunde, so können wir die Tätigkeit des Übersetzungsprogramms beim Auftreten von N im Flußdiagramm auf Seite 300 durch den die Verzweigung r £ N bei ja verlassenden Programmzweig darstellen. Tritt eine Klammer, ein Operationszeichen oder ein Schlußzeichen auf, so wird für das Übersetzungsprogramm eine Fallunterscheidung gemacht, die sich auf den Vergleich von r und dem in Z c abgelegten Zeichen gründet. Wir stellen diese Fallunterscheidung am besten in Form einer Übergangsmatrix M dar. Die Spalten von M entsprechen den T7, die Zeilen entsprechen < Z r > , und die einzelnen Matrixelemente bezeichnen die Fälle 1, 2 ... 5. M lautet folgendermaßen: gelesene Zeichen (T) leer + — x / ( zuoberst gestapelte Zeichen ():

leer

+



X

/

( )

e

1 2 2 5 5 3 F F

1 2 2 5 5 3 F F

1 3 3 2 2 3 F F

1 3 3 2 2 3 F F

1 3 3 3 3 3 F F

)

e

F 5 5 5 5 4 F F

F 5 5 5 5 F F F

In den einzelnen Fällen werden vom Übersetzungsprogramm folgende Operationen ausgeführt: 1 ) Die Zuordnung zwischen Kamen (symbolische Adresse) und echter Adresse haben wir bereitB in Kapitel 0 besprochen.

Operative Sprachen

299

Fall 1: Fall 1 kennzeichnet die Situation der Verschachtelungsstufe 0, bei der kein vorangegangenes Element des Ausdrucks berücksichtigt werden muß. Der zugehörige Wert des Ausdrucks (erster Operand, Zwischenergebnis oder Endergebnis) steht bei der späteren Ausführung des Programms immer in Q1 (vgl. Ausgang 1 der Verzweigung Fallunterscheidung M im Flußdiagramm auf Seite 300). Fall 2: r ist ein Operator und folgt unmittelbar (das heißt nur durch einen Operanden und nicht durch eine Klammer getrennt) auf einen Operator gleicher Stufe (also -f- oder — auf + oder — beziehungsweise x oder / auf x oder /). Identifizieren wir - f , —, x und / mit den Z 22-Befehlen - f , —, X und : und nennen wir den entsprechenden Befehl z, so erhalten wir im Flußdiagramm auf Seite 300 den Programmzweig am Ausgang 2 der Verzweigung Fallunterscheidung M. Fall 3 : r führt zu einer Erhöhung des Verschachtelungsgrades (das heißt: r ist eine öffnende Klammer oder/ 1 ist ein beliebiger Operator, wählend eine öffnende Klammer ist, oder ist + oder — während T x oder / ist). Damit erhalten wir den Programmzweig am Ausgang 3 der Verzweigung Fallunterscheidung M des Flußdiagramms auf Seite 300. Fall 4 : R ist eine schließende Klammer und ZT enthält eine öffnende Klammer. Das Übersetzungsprogramm hat also den Stapel lediglich um eins zu erniedrigen (Ausgang 4 der Verzweigung Fallunterscheidung M). Fall 5:

r = s v r = ) A

(v[T= + v r = —] A [ < Z ( > = x V < z t >

= /]. Das gelesene Zeichen setzt den Verschachtelungsgrad herab. Der Unterschied zu Fall 4, bei dem auch der Verschachtelungsgrad herabgesetzt wird, ist der, daß noch das zu einer Operation gehörige Programmstück erzeugt werden muß. Damit erhalten wir den 5. Ausgangszweig der Verzweigung Fallunterscheidung M des folgenden Flußdiagramms. Fall F: Die mit F markierten Stellen der Matrix bezeichnen Situationen, die bei ordnungsgemäßer Notierung eines Klammerausdruckes nicht auftreten dürfen. F keimzeichnet also einen Formfehler, der im folgenden Flußdiagramm für die Übersetzung eines arithmetischen Ausdruckes zu einem besonderen Ausgang führt:

Problemorientierte Sprachen

300

U>

(0

«e tí

t?

ee tí

IO

M



M

•A

•s tí



N

>a

1

1









+ +

+ +

+

+ + +

+

U

«FH

ss o

m



S

P

t-l

»

Ed

co

tei

©

1

£ io

D

0)

X

t ® ü o CO tei

X

-

N u» tí

X

©

io