Register - oder: was ist ein Akku ("Programmieren" lernen)

  • Vorrede =6502=


    Die Beispiel beziehen sich bei mir auf 6502.

    Es wird sicher irgendwann (schnell...) an der/meiner Nichtwissensgrenze enden, aber bis dahin gilt, daß man die Sachen mit einem entsprechenden Gerät nachvollziehen kann. Hier wäre das, und ich empfehle das auch generell als Plattform für diese CPU, erstmal der 6502 in einem C16 bzw. Commodore Plus/4.

    Der Grund dafür ist folgender: 1.) Ich mag den. ;) und 2.) wichtiger: die Reihe hat einen eingebauten Monitor, der jederzeit zur Verfügung steht. 3.) es gibt prima Emulatoren dafür


    Zum direkten Nachvollziehen der Beispiele installiere man sich z.B. den VICE Emulator ( unter Linux auch "xplus4") oder den "minus4" und bemühe die ROMs von der zimmers.net Seite. (KERNEL und BASIC reichen erstmal)


    Die ganz basalen Sachen kann man aber mit jedem Monitor auch auf einem C64, VC20 usf. nachvollziehen.

    Wichtig ist, daß es dort eine Statusausgabe gibt.

    -- 1982 gab es keinen Raspberry Pi , aber Pi und Raspberries

  • Viele Computer habe irgendwie ganz im tiefsten Inneren eine Art Speicherstelle, die sie benutzen, um damit zu rechnen. Manche habe davon eine, manche habe drei davon, andere vier, wieder andere sechzehn. Ganz viele solche gibt es z.B. bei SUN Computern.

    Bei den mechanischen Rechnern ist das einfach ein Rädchen, was man drehen kann und auf dem die Ziffern 0-9 stehen - und daneben noch ein solches und evtl. noch ein paar weitere. Ansehen kann man sich das schön, wenn man sich bei ebay eine alte Brunsviga holt oder eine Archimedes von Pöthig oder, wenn man gut unterwegs ist eine Pascaline (Bild Pascaline).


    So ein Rädchen kann man also drehen !


    Man kann es auch erstmal auf Null stellen - und dann z.B. drei Schritte weiter drehen. Und nochmal drei. Dann zeigt die Anzeige eine "6".

    Jetzt nochmal drei - eine "9". Und jetzt ? Nochmal drei weiter ?


    Klar, dann kommt erst eine "0", dann eine"1" und nach drei Schritten eine "2". Also 9+3 = 2 !

    Das ist offensichtlich noch nicht richtig.


    Wenn man aber den "Übertrag" beachtet, dann dreht man jetzt natürlich, wenn die Position "0" erreicht worden ist, das Rädchen links daneben auf die Position "1" - und als Ergebnis steht also plötzlich eine "1" "2" , eine 12 ...

    und 9+3 ist ja eben auch, genau, 12 ! Paßt also.


    Hat man z.B. eine "998" eingestellt und dreht um drei Schritte weiter, passiert schon was Spannendes


    998 - eins weiter - gibt 999

    noch eins weiter gibt 990, was natürlich nicht sein kann, weils ja weniger geworden ist ( 990 < 999 ), aber man hat sich ja den Übertrag gemerkt und dreht darum das Rädchen links daneben auch eins weiter

    also 990 - eins weiter in mittlerer Position gibt 900

    der gemerkte Übertrag ist jetzt schon addiert, aber weil das zweite Rädchen von 0 auf 9 gewechselt hat, gibt es wieder einen neuen, den man nun auf das Rädchen ganz links übergibt

    also 900 - eins weiter ganz links gibt 000 ...


    Super Ergebnis, oder ? ;)


    Aber da ist ja noch der Übertrag ! Also drehen am vierten Rädchen noch weiter links und plötzlich steht da

    1000

    und alle gemerkten Überträge sind "verbraucht"/"addiert"


    Nun kommt nochmal ein Schritt Rädchen drehen (998+3), wieder ganz hinten am ersten

    also 1000 - eins weiter - gibt 1001 und das Ergebnis stimmt anscheinend auch.



    Register sind nun eigentlich nicht groß anders organisiert, als solche Rädchen !

    (total triviale Vereinfachungen sind immer richtig ...)


    Sie sind quasi Rädchen/Speicher, die ein bestimmte Zahlenmenge aufnehmen können.

    Wenn sie dabei über ihre größte Zahl "gedreht" werden, haben sie aber die schöne Eigenschaft, daß sie bzw. der Prozessor das bemerken und einem mitteilen. ( Es wird dann das Überlaufflag gesetzt. )

    Was man mit dieser Information macht, ist einem selbst überlassen.


    Man kann also in einem Register eine Zahl speichern !

    Man kann diese Zahl dort drin dann auch verändern !

    Man kann, sinnvollerweise, diese Zahl dort auch wieder herausholen ! Und z.B. im RAM abspeichern.


    Und außerdem gibt es bestimmte Zustände der Zahl, die der Mikroprozessor bemerkt und einem mitteilt -z.B. daß ein Überlauf stattgefunden hat, wenn die Zahl vom größten Wert durch Addtion auf 0 gesetzt wird, aber auch wenn z.B. 2 oder 5 dabei herauskommt und - eben - ein Überlauf stattfand.

    -- 1982 gab es keinen Raspberry Pi , aber Pi und Raspberries

  • =6502=


    im 6502 gibt es quasi ein einziges vollwertiges Register !

    Na ja, eigentlich gibt es schon insgesamt drei Register, aber davon ist halt eines das Hauptrechenregister. Und damit das einen Namen bekommt hat man es AKKUMULATOR genannt, kurz AKKU.


    Das ist quasi das Rädchen der Pascaline.

    Wenn man es eins weiterdreht, wird der Wert eins größer !


    Und damit mal was zu sehen ist, hier mal die erste Übung :


    (bitte den Plus/4 Emulator anwerfen und starten, da sollte das Startbild kommen und der Cursor blinken)


    der Befehl MONITOR + Return öffnet den Maschinensprachmonitor !


    dort steht jetzt




    hübsch kryptisch ... Interessant ist erstmal nur der dritte Eintrag in der Zeile 1 : AC

    AC steht für ... ... (?) , klar AKKUMULATOR, also kurz AKKU


    Direkt untendrunter steht der aktuelle Wert - nämlich FF .


    Das ist nun nicht gerade eine normale Zahl. Zumindest keine, wie man sie gewohnt ist. Eigentlich ist es schon eine Zahl und auch keine wirklich besonders aufregende - sie ist aber auf eine komische Art aufgeschrieben: in HEXADEZIMAL !


    "Normale" Zahlen schreibt man ja eigentlich eher in DEZIMAL.

    Es gibt aber daneben auch andere Varianten Zahlen zu notieren - z.B. SEXAGESIMAL oder OKTAL oder BINÄR oder eben auch HEXADEZIMAL.


    Interessiert momentan erstmal nicht weiter.


    Der Akku ist ja ein Register. Und da kann man was hineintun. ... zum Beispiel eine andere Zahl !


    Wie wäre es mit "3" ?



    Dafür gibt es einen Befehl. Solch ein Befehl existiert vermutlich auf jeder halbwegs aktuellen Plattform und er sagt:

    Lade das Register mit einem bestimmten fixen Wert oder einfach: "tue Zahl dahinein"

    beim 6502 schreibt man dafür

    LDA - d.h. load accumulator


    und dahinter schreibt man für einen fixen Wert ein # Symbol und dann ein $ wenn man einen hexadezimalen Wert hineintun will und dann natürlich noch den Wert selber


    also bei "3":

    LDA #$03


    Wenn man das probiert, passiert irgendwie gar nichts - nur ans Ende der Zeile wird ein Fragezeichen geschrieben, was sagt, daß es einen irgendwie unklaren Fehler gab.


    Man muß also schonmal ein kleines Programm schreiben.

    Dazu sagt man, wo im Speicher das Programm anfangen soll, gibt also eine Startadresse ein und damit der Rechner weiß, wo das Programm zu Ende ist, schreibt man dahinter die Anweisung

    BRK - break


    Damit die Adresse übergeben werden kann und man Assemblerbefehle eintippen darf muß noch ein "." (Punkt) davor

    also:

    .5000 LDA #$03

    .5002 BRK

    .5003


    Man sieht, daß die Adresse automatisch mitgezählt wird, und wenn man einfach so Return drückt, die Eingabe endet.

    Die 5000 ist im Übrigen auch hexadezimal, weshalb man dann von Adress $5000 spricht. Denn $5000 ist nicht das Gleiche wie eine dezimale 5000, das sind zwei unterschiedliche Werte.


    Das Programm ansehen kann man mit

    D 5000


    Dadurch ist jetzt die Anzeige der Register weggescrollt, die holt man aber einfach mit

    R


    zurück.


    Und da steht bei AC immer noch die FF !

    Ist ja klar, bisher ist das Programm nur eingegeben und nicht gestartet.

    (Apropos FF - es ist natürlich eine hexadezimale Zahl (sieht man ja schon an den F's) und müßte darum, wenn man selbst mal irgendwo aufschreibt besser $FF heißen. $ heißt ... hexadezimale kommt dahinter )


    Starten geht mit G wie Go und natürlich der Startadresse, also

    G 5000



    Es passiert was, und als Ausgabe kommt auch was.

    Das liegt aber nur daran, daß der Editor halt automatisch die Registerzeile anzeigt, wenn das Programm mit BRK beendet wird.


    Aber es passiert auch in der Zeile allerhand !


    Schon die erste Zahl ändert sich. Vor allem aber steht unter AC jetzt eine 03 !

    Um exakt zu sein, ist das natürlich auch wieder eine $03 , weil hexadezimal. Aber eben eine 03 !


    Genau wie gewollt !


    Man kann also in einem Register eine Zahl speichern !

    Eine die man selbst festlegt !


    Zum Probieren kann man jetzt das Programm mal einen anderen Wert daheinschreiben lassen, indem man die einzige Programmzeile abändert. Etwa eine 05 oder eine 07.

    Schön wäre auch eine EA ! (LDA #$EA)

    Das geht, weil es ja - eben - eine sogenannte Hexadezimalzahl ist.

    Oder eine 04 !


    Nach jeder neuen Eingabe der Zeilen muß natürlich wieder der Zyklus mit R und G 5000 gemacht werden.

    Einfach mal ausprobieren !

    -- 1982 gab es keinen Raspberry Pi , aber Pi und Raspberries

  • Man hat also gesehen, daß man in Register, bzw. beim 6502 in den sogenannten Akkumulator, Zahlen hineinschreiben kann.


    Prinzipiell geht das auf so ziemlich jedem Gerät. Es gibt aber natürlich Unterschiede.


    Da ist natürlich der Befehl selber.

    Der heißt halt beim 6502 LDA, woanders kann er vielleicht LD heißen, oder LOAD oder MOV.


    Und genauso kann das Register einen anderen Namen haben, z.B. R0 (für Register Null) oder R12 (für Register 12) oder auch mal was ganz Abgefahrenes wie AX. Oder auch BX, CX usf.


    Viele wichtiger aber ist ja eigentlich - wenn man mal an die Rädchen von dem Additionsrechner (Pascaline) denkt - folgende Frage:


    Wie groß ist die Menge an Zahlen, die man auf dem Register speichern kann ?

    Also quasi wie oft kann man "am Rad drehen" bevor der Überlauf kommt.

    Oder noch anders: Welches ist die maximal mit solch einem Register darstellbare Zahl ?


    So ein normales Dezimales Zahlenrädchen kann genau von "0" bis "9" zählen. Hat also 10 Positionen.


    Nun könnte man natürlich hingehen und sagen, daß man genau weiß, daß man nur mit Zahlen zwischen "0" und "2500" zählen will. Da würde ja quasi ein Rädchen / Register reichen, was genau diese Zahlen alle darstellen kann.

    Leider ist das so eine Sache mit den Wünschen, und darum muß man leider das nehmen, was so da ist und damit hinkommen (es sei denn man baut selbst was).


    Was gibt es nun so ?

    Gängige/übliche maximale Zahlengrößen in Registern sind z.B. 32 Bit oder 64 Bit oder 16 Bit oder z.B. 8 Bit - wie etwa beim 6502.

    Es gibt aber durchaus Rechner mit 36 Bit oder 18 Bit und wer weiß was noch.

    Blöd ist nur, daß da jetzt schon wieder eine neue Einheit für die Zahlen steht - nämlich Größenangabe in Bit.


    Man kann aber sicher mal davon ausgehen, daß man in einem 64 Bit großen Register "MEHR" Zahl unterbringen kann, als in einem 8 Bit Register. Und in einem 16 Bit weniger als in einem 32 Bit großen.


    Dabei kann man dann gleichmal paar Zahlen auswendig lernen ( Erklärung warum genau soviel in einem anderen SubThread ) ( die meisten werden's eh wissen )


    16 Bit sind 65536 mögliche Zahlen ( was genau 2 hoch 16 sind )

    32 Bit sind gewaltige 4294967296 mögliche Zahlen ( nämlich 2 hoch 32 )

    und

    8 Bit sind exakt 256 Zahlen ( nämlich 2 hoch 8 )


    Man sieht also 3 Sachen:

    a.) man kann irgendwie nicht davon ausgehen, daß 32 Bit Register doppelt soviele Zahlen darstellen können wie 16 Bit

    b.) die gewünschte "2500" ist da irgendwie nicht mit dabei

    c.) die 8 Bit sind eigentlich schrecklich klein, was die größte mögliche Zahl im Register betrifft


    und wie groß ist dann die größte darstellbare Zahl im 8 Bit Register ?


    Das kommt darauf an - wie bei allen anderen Größen auch - wo man anfängt zu zählen !

    Es sind insgesamt 256 darstellbare Zahlen da.

    Zählt man nun bei "1" los, dann kann man logischerweise von "1" bis "256" damit zählen.

    Fängt man aber bei "0" an - tja, dann ist natürlich auch der größte Wert nur die "255" !

    Man kann eben nur insgesamt 256, und wenn die "0" schon mitzählt, dann gehts eben nur bis "255".


    Ein 8Bit Rechner ist also eine Pascaline mit Rädchen auf denen man von "0" bis "255" zählen kann !


    -- 1982 gab es keinen Raspberry Pi , aber Pi und Raspberries

    Einmal editiert, zuletzt von ThoralfAsmussen ()

  • =6502=


    Damit das mit den Rädchen noch ein bißchen anschaulicher wird, bietet es sich an genau das Hochzählen zu machen.

    Bisher konnte man einen Wert in den AKKU laden.


    Es gibt beim 6502 aber noch zwei andere Register neben dem AKKU (=Akku).

    Die heißen - warum auch immer - das X-Register und das Y-Register.


    Wichtig bei Registern war ja gar nicht so sehr der Name und auch nicht der Ladebefehl, sondern vor allem die Zahl, die man maximal speichern kann.


    Das gilt jetzt für X-Register und Y-Regsiter natürlich auch wieder.


    Es ist z.B. völlig egal, ob die auf anderen Architekturen evtl. R10 heißen oder ob der Ladebefehl LD oder MOV heißt.


    Viel wichtiger ist wieder die Bitbreite !

    Im Fall vom 6502 und seinem X bzw. Y Register sind das wieder 8 Bit !


    Sie können also ebenfalls 256 Zahlen darstellen oder, anders gesagt, von "0" bis "255" zählen.



    Man muß sich klarmachen, daß das überhaupt nicht so sein müßte !

    X und Y könnten z.B. auch 16Bit Breit sein und da der Akku aber das Hauptrechenregister wäre, würde man sowas wahrscheinlich dann trotzdem als 8Bit Rechner bezeichnen.


    Es ist aber mal so - und das bedeutet, daß man vieles was man mit dem Akku machen kann, ähnlich mit X und Y machen kann. Es gibt daneben aber eben auch feine Unterschiede - mal Sachen die mit dem Akku besser gehen, dann wieder was, was mit X und Y besser klappt.


    Eines davon ist simples Hochzählen. Das bedeutet das es einen Befehl gibt - der wieder so ein typischer Registerbefehl ist, den es auf vielen Rechnern in ähnlicher Art gibt - der das Register um genau "1" erhöht, also quasi das Rädchen einen Schritt weiterrotiert oder eben (simpel) "plus 1" rechnet.

    Sowas nennt man ein INKREMENT . (Eine Erhöhung.)


    Und dafür gibt es beim 6502 den Befehl

    INX für das X-Register und

    INY für das Y-Register


    Zunächst schaut man mal, wo man X und Y findet - natürlich in der Statusleiste, wo die Register angezeigt werden.



    Dort finden sich hinter dem Akku - also AC - die Einträge XR und YR.

    Also XR für X-Register und YR für Y-Register.


    Die Werte stehen wieder direkt darunter. Es steht das $FF für das X-Register und ebenfalls $FF für das Y-Register.


    Um das X-Register zu erhöhen macht man sich wieder ein kleines Programm (ja, ich weiß, der Name ist ein Euphemismus) und zwar so:

    .5100 INX

    .5101 BRK



    ACHTUNG ! Es ist noch was Neues passiert.

    Die Startadresse ist nicht mehr $5000, sonderm jetzt $5100.

    ( Das ist im Übrigen völlig unwichtig, aber abwechslungsreicher. Außerdem gewöhnt man sich so evtl. daran, daß es evtl. gar nicht so wichtig sein mag, wo im Speicher genau nun so eine Routine liegt.)


    Starten geht wie gehabt mit G für Go und Startadresse.

    (Das $ läßt man da einfach nur deshalb weg, weil dieser spezielle Monitor schlicht per se in hexadezimalen Werten redet, wie man auch gleich sehen wird.)


    G 5100

    bringt



    Was ist passiert ???


    Nun der erste Wert in der Statusleiste hat sich wieder verändert ...

    und das X-Register (XR) steht jetzt auf einmal auf "00", also Null, also Zero, also erste mögliche darstellbare Zahl.


    Daraus kann man nun auch - wenn man davon ausgeht, daß das mit den 8Bit und den 256 darstellbaren Zahlen, die man bei "0" zu zählen beginnt, weshalb die größte Zahl die noch darstellbar ist, eben nicht die 256 sondern die 255 (!) ist, stimmt - sofort schlußfolgern, daß die $FF für eben diese 255 steht.


    Neuer Wert zum Merken - $FF = 255 !


    Natürlich möchte man das gerne überprüfen. Dazu könnte man nun die Routine einfach entsprechend oft aufrufen. Also insgesamt noch 255 Mal um wieder bei $FF zu landen.


    Kann man ja mal probieren !

    Also einfach ein paar Mal noch G $5100 eingeben und schauen, was mit dem XR Wert passiert.


    Wer das bis "09" geschafft hat, wird danach eine spannende Zahl sehen - nämlich ein 0A und dann weiter 0B,0C,0D,0E,0F und dann erstaunlicherweise eine 10, danach wird dann fast wieder normal, mit 11, 12, bis es nach 19 wieder komisch mit 1A weitergeht.


    Alle die nur bis "05" oder so kommen, verpassen aber nichts.


    Zum Durchzählen gibt es nämlich auch eine Abkürzung - man zählt einfach immer gleich auf einen Hieb das Register um Werte hoch.

    Dafür wird jetzt, zur Abwechslung, das Y-Register benutzt. Und auch weil das ja immer noch so schön auf $FF steht.


    (Übrigens, die Zahlen sollten ja noch dastehen, es ist evtl. interessant zu bemerken, daß sich alle anderen Werte außer dem XR überhaupt nicht verändert haben. Die erste Zahl ist immer 5103, AC ändert sich nicht, YR bleibt konstant und auch die anderen Sachen - außer dem XR !)


    Nun also zum Y-Register ; schnelles Hochzählen in 8 Schritten, d.h. um 8 Werte, d.h. plus 8 ... usf


    Das Kommando ist von oben bekannt: INY - increment Y register

    Na und ums 8mal je eine Position hochzuzählen, gibt es fast nichts Einfacheres, als es einfach 8mal hinzuschreiben ! ;)


    Diesmal an Adresse $5200

    (nur zur Übung, damit man sich dran gewöhnt, daß sowas auch mal woanders stehen kann; wie gehabt)


    .5200 INY

    .5201 INY

    .5202 INY

    .5203 INY

    .5204 INY

    .5205 INY

    .5206 INY

    .5207 INY

    .5208 BRK


    was passiert bei G 5200 ?



    Der erste Wert hat sich ziemlich deutlich geändert, viel wichtiger aber:

    Das YR wechselt von $FF auf $07 !


    Vermutlich hat es also beim ersten INY, wie vorhin das XR, den Wert von $FF auf $00 geändert, und dann beim zweiten INY ist der von $00 auf $01 gestiegen, dann von $01 auf $02 und weiter über $03, $04, $05, $06 auf $07

    Insgesamt also 8mal inkrementiert !


    Man sieht also $FF + 8 = $07 , was man ja jetzt auch verstehen kann, weil

    eine Änderung zu Null und dann noch 7 weitere Schritte sind halt $07 !


    Wozu ist das nun gut ?


    Man kann jetzt SCHNELL durchzählen ! 1mal 8 Schritte sind bereits erfolgt.

    Jetzt müßten, wenn es wirklich 256 Zahlen sind, die das YR fassen kann, insgesamt noch 256 / 8 und einer weniger, den hatten wir ja gerade, Durchläufe gemacht werden, um wieder bei $FF anzukommen. Das wären also noch 32 und einer weniger, also 31 mal G 5200.

    Ganz schön viel !


    Andersherum wäre besser.


    Dafür müßte man also 32 mal ein INY hintereinander schreiben, dann ein BRK für Programmende und das Ganze 8mal starten, um insgesamt 256 Zahlen durchlaufen zu haben (nämlich 8 mal 32). Logisch, oder ?


    Nun gibt es da in der Programmliste mit den vielen INY ja nicht nur eine Adresse und den Befehl selbst, sondern auch noch so eine "C8" zwischen beiden. Und zwar bei jedem INY genau ein "C8". Das ist in dem Fall zwar auch eine hexadezimale Zahl, die aber nicht nur für einen Zahlenwert steht, sondern hier bedeutet sie den Befehl selbst, nämlich eben INY.

    INY ist also nur so eine Art Umschreibung für den eigentlichen Inhalt nämlich C8.

    Nun ist dieses C8 einfach der "echte Maschinenbefehl" des 6502, der für INY steht und sowas heißt: Opcode

    das INY ist dagegen nur die Schreibweise im Assembler, wodurch das bißchen besser lesbar wird und sowas heißt: Mnemonic


    Man könnte also das Programm mit den 8 INY Anweisungen auch dadurch schreiben, daß man einfach 8mal den Wert C8 in den Speicher schreibt. Das BRK dahintersetzt. Und das gleiche Programm bekommt, weil Opcode und Mnemonic ja quasi das Gleiche meinen.


    Nun gibt es im MONITOR die schöne Anweisung F wie FILL


    Schreibt man nun

    F 5300 5400 00

    bedeutet das, daß alles von $5300 bis einschließlich Adresse $5400 mit dem Wert $00 gefüllt wird.


    $00 ist nun aber ebenfalls nicht nur die Zahl 0, sondern, wenn der Rechner sie als Befehl liest, die bereits bekannte Anweisung BRK. $00 = Opcode, d.h. Maschinensprache und BRK = Mnemonic , d.h. Assembler


    Zurück zum Zählen. Die Idee war 8 mal das Y Register um jeweils 32 Werte hochzuzählen, also 32 INY Anweisung und dann ein BRK dahinter.


    Mit dem Wissen von eben kann man da ganz faul schreiben

    F 5300 5400 00

    F 5300 531F C8


    Da $00 ja sowieso BRK ist, braucht man das dann nicht einzeln ans Ende setzen.

    Aber, ob es 32 INY Befehle sind sollte man mal nachzählen !


    Dazu listet man das Programm auf mit D wie Disassemble


    D 5300

    und wenn die Ausgabe anhält kann man mit D + Return weitermachen.


    Wenn man dieses Programm nun 8mal startet, sollte also der Wert im Y-Register YR jeweils um 32 Werte hochgezählt werden, mithin also 8 x 32 Werte und somit um 256 Werte. Und das würde bedeuten, daß er - sofern er ein 8 Bit Wert ist, der 256 Zahlen darstellen kann - wieder bei seinem ursprünglichen Wert zu Beginn der 8 Programmläufe landen sollte.


    Wenn er also jetzt noch auf $07 steht, sollte er nach 8 solchen Runden wieder bei $07 sein.


    Also 8x

    G 5300



    Der Wert für YR landet nach 8 solchen Runden wieder beim Ausgangswert.

    Das Y-Register hält also tatsächlich 256 Zahlen, auch wenn die Bezeichungnen dafür evtl. noch bißchen komisch aussehen (..., $67, $A7, $C7, $E7)

    -- 1982 gab es keinen Raspberry Pi , aber Pi und Raspberries

    2 Mal editiert, zuletzt von ThoralfAsmussen ()

  • =Z80=


    Nachdem der Sinn und Zweck der Register jetzt ziemlich ausführlich betrachtet wurden kommt hier ein Überblick über das Registermodell des Z80.


    Auch er hat einen Akku, der ebenfalls mit A bezeichnet wird. Dort wird in der Regel gerechnet, verglichen, geschoben etc.


    Daneben gibt es folgende Register, die entweder Zwischenergebnisse speichern können oder auch schon mal spezielle Aufgaben übernehmen:


    B, C, D, E, H, L


    Diese Register sind jeweils 8 Bit breit, können aber zu 16 Bit-Registern zusammengefasst werden, die dann BC, DE und HL heißen. In der Form haben sie dann meistens Spezialaufgaben, z.B. BC als Zähler, DE und HL häufig als Pointer.


    Beispiel:

    Um einen größeren Bereich des Speicherinhalts zu verschieben lädt man DE mit der Startadresse, BC mit der Anzahl der zu verschiebenden Bytes, und HL mit der Zieladresse. Dann kann man in einer Schleife von DE lesen (d.h. den Inhalt der Speicherzelle, deren Adresse in DE steht), in die durch HL adressierte Zelle schreiben, DE und HL erhöhen, BC erniedrigen, und das ganze so lange machen bis BC bei 0 angekommen ist.

    (Netterweise hat der Z80 sogar einen Befehl, der das alles gleichzeitig macht - das ist einer der großen Vorteile des Z80, im Rahmen eines allgemeinen Programmierkurses aber eher ablenkend).


    Dann gibt es noch zwei weitere 16 Bit Register IX und IY, die ausschließlich als Index-Register für einige Spezialbefehle verwendet werden können, aber eben auch den gesamten Adressraum abdecken.


    Dazu gibt es die internen Spezialregister, über die im Wesentlichen der Prozessor alleine herrscht:


    F - das Flag-Register

    PC - der Programmzähler

    SP - der Stackpointer


    Die gibt es in vergleichbarer Form auch bei fast jedem anderen Prozessor, wobei das Flag-Register (in dem verschiedene "Signalbits" zusammengefasst werden) wieder etwas besonderes ist, weil es vom Programmierer in engen Grenzen wie ein 8-Bit-Register genutzt werden kann.


    (Signalbits dienen dazu, bestimmte Situationen und Zustände zu signalisieren, z.B. den schon erwähnten Überlauf beim Addieren, oder auch die Tatsache, dass der Akku den Wert 0 enthält).


    So, und weil es so schön ist, hat der Z80 das Ganze zwei mal! Der gesamte (*) Registersatz existiert noch ein zweites Mal im Hintergrund. Auf diese kann aber nicht direkt zugegriffen werden; statt dessen werden die beiden Sätze mit einem Befehl komplett ausgetauscht. Das ist ganz hilfreich bei der Bearbeitung von Unterbrechungen (Interrupts) oder parallel laufenden Prozessen. In der Praxis wird das aber eher selten verwendet.


    (*) Ich muss zugeben, dass ich momentan nicht genau weiß, ob das auch den PC und SP betrifft. Eher nicht....

    • Offizieller Beitrag

    Der gesamte (*) Registersatz existiert noch ein zweites Mal im Hintergrund.


    (*) Ich muss zugeben, dass ich momentan nicht genau weiß, ob das auch den PC und SP betrifft. Eher nicht....

    SP und PC gibt's nur einmal.

    Sonst würde bei einem Registertausch die Programmausführung plötzlich ganz woanders weiter gehen (PC ändert sich).


    Ausserdem ist der Registertausch fuer AF und BC, DE, HL getrennt.


    Zur Vollstaendigkeit sind beim Z80 noch die Register R und I zu erwähnen.

    R = Refresh Counter Register

    I = Interrupt Vektor Register


    Das I betrifft die Interrupt Möglichkeiten des Z80 und sollte dann besprochen werdn.

    Das R ist ein Zähler für den Refresh.


    Nach einem Opcode Fetch (das Laden eines Befehls aus dem Speicher) macht der Z80 einen Refresh Cycle. Hierbei wird der Refresh Counter auf den Adressbus gelegt. Dies dient dem Refresh welches bei dynamischen RAMs nötig (DRAMs) ist. Der Refresh Cycle vereinfacht den Hardwareaufwand bei DRAMs

    Aber das ist eigenes Thema.

    • Offizieller Beitrag

    Dann gibt es noch zwei weitere 16 Bit Register IX und IY, die ausschließlich als Index-Register für einige Spezialbefehle verwendet werden können, aber eben auch den gesamten Adressraum abdecken.

    Spezialbefehle würde ich das nicht nennen.

    Mit den IX und IY Befehlen kann ich alles machen, was ich auch mit dem (HL) (in Klammern als Pointer) machen kann.

    Speziell schon weil IX und IY über jeweils einen Prefix angesprochen werden.

    Z.B.:


    Code
      ld a,(hl)
    
      ld a,(ix+0)


    machen das gleiche wenn in HL und IX der gleiche Inhalt ist.