; Zusammen mit dem Kode von ; ggT.scm; findet sich dieses Programm in ; ; ggT-demo.scm; . ; \begin{hiddenweb} ; Register werden durch globale Schemevariablen dargestellt. ; Die Eingabe erfolgt übrigens, indem der Benutzer vor ; dem Start der Maschine die Inhalt bestimmter Register setzt. ; Würde man die Maschine tatsächlich aus digitalen Bausteinen ; zusammenlöten, könnte man dies z.~B.\ mit Konsolenschaltern ; oder DIP-switches realisieren. ; (define a 0) (define b 0) (define t 0) (define flag 0) ; Passive Bauteile sind solche, die einfach aus ihren Ausgängen ; bestimmte Funktionen berechnen, und diese (ständig) an ihren ; Ausgängen darstellen. Wir können solche Bauteile durch ; Schemfunktionen darstellen, der Aufruf einer solchen Funktion ; korrespondiert zum Auslesen des Ausgangs des betreffenden ; Bauteils. ; (define diff ; t-b (lambda () (- t b))) ; ; (define less ; '<' im script (lambda () (if (< t b) 1 0))) ; ; (define equal ; '=0' im script (lambda () (if (= b 0) 1 0))) ; Datenpfade sind Eingänge von Registerbausteinen, welche mit den ; Ausgängen anderer Bausteine (passive Operationen oder ; Ausgänge anderer Register) verschaltet sind. In Hardware ; korrespondiert zu jedem solchen Eingang eine Kontrollleitung ; (in der Vorlesung als {\em Knopf} bezeichnet), ; deren Betätigung bewirkt, dass das betreffende Register seinen ; Inhalt vom entsprechenden Eingang lädt und {\em festhält\/}. ; Wir können das Betätigen einer Kontrollleitung offenkundig durch ; ein ; set!; modellieren. Der Übersichtlichkeit halber kapseln ; wir dieses noch in Funktionen, die so heissen, wie die Datenpfade. ; (define a<-b (lambda () (set! a b))) ; ; (define b<-t (lambda () (set! b t))) ; ; (define t<-a (lambda () (set! t a))) ; ; (define t<-diff (lambda () (set! t (diff)))) ; ; (define flag<-equal (lambda () (set! flag (equal)))) ; ; (define flag<-less (lambda () (set! flag (less)))) ; Die Aufgabe des Controllers ist es die Abläufe (Auslösen der ; Datenpfade) entsprechend gewissen Kriterien (Flags) zu steuern. ; In Hardware handelt es sich um eine Blackbox, die nun wesentlich ; weniger kompliziert ist, als die ganze Registermachine, und welche ; auch weniger inneren Zustand besitzt (bei uns erst mal lediglich ; einen Programmzähler). ; ; Man kann das Verhalten des Controllers unabhängig von seiner ; realen Implementation durch ein {\em Assemblerprogramm\/} ; beschreiben. Hier sei noch erwähnt, dass es sich hierbei ; eigentlich um das {\em Mikroprogramm\/} der CPU handelt. ; Dieses Programm wurde in der Vorlesung bereits entwickelt. ; Uns bleibt lediglich die Umsetzung in ein Schemeprogramm. ; Wir stellen dabei jede Assemblerinstruktion durch ; eine Prozeduranwendung dar (nämlich genau die Prozedur, ; die den entsprechenden Datenpfad repräsentiert), ; und verpacken die einzelnen Zweige des Conrollerprogramms ; in separate Schemeprozeduren, die wir dann gegenseitig ; endrekursiv aufrufen (um ; goto; zu emulieren). ; ; Die weiteren Regeln für den Controller sind einfach: Es ist nur das ; Auslösen der Datenpfade erlaubt und lesender Zugriff auf ; ; flag; . ; ; (define start-controller (lambda () (label-test-b))) ; ; (define stop-controller (lambda () #t)) ; ; (define label-test-b (lambda () (flag<-equal) (if (= 1 flag) ; branch on flag (stop-controller) (begin (t<-a) (label-rem-loop))))) ; ; (define label-rem-loop (lambda () (flag<-less) (if (= 1 flag) ; branch on flag (label-rem-done) (begin (t<-diff) (label-rem-loop))))) ; ; (define label-rem-done (lambda () (a<-b) (b<-t) (label-test-b))) ; Die folgenden Demonstrationsroutinen erlauben das Programm zu testen: ; (set! a (* 3423434 34545)) ; Benutzer setzt Register (set! b (* 36238 34545)) ;(mit DIP Switches) (newline) (display "Berechnung des ggT durch eine Registermachine") (newline) (display "a = ")(display a)(newline) (display "b = ")(display b)(newline) (display "-- running --")(newline) (start-controller) ; Danach ist Ergebnis in a (display "-- done --")(newline) (display "Ergebnis in a = ")(display a)(newline) (if (not (= 69091)) (display "INCORRECT RESULT")(newline)) (newline)