Datentransportbefehle
MVI r, xx
move immediate to register
Das Register r mit dem Datenwort XX laden.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
MVI r, xx | 3E xx | 06 xx | 0E xx | 16 xx | 1E xx | 26 xx | 2E xx |
Taktzyklen: 7
MVI m, xx
move immediate to memory
Eine Speicherzelle mit dem Datenwort xx laden. Die Adresse der Speicherzelle steht im Registerpaar HL
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
MVI m, xx | 36 xx |
Taktzyklen: 10
LXI rp, xxyy
load register pair immediate
Das Registerpaar rp mit dem 16-Bit-Wert xxyy laden (Doppelwortoperation). Das im zweiten Byte stehende Wort yy gelangt dabei in das untere Register (C, E, L, bzw. untere Hälfte des Stackpointers), und das im dritten Byte stehende Wort xx ins obere Register (B, D, H, bzw. obere Hälfte des Stackpointers).
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | B (C) | D (E) | H (L) | SP |
LXI rp, xxyy | 01 xxyy | 11 xxyy | 21 xxyy | 31 xxyy |
Taktzyklen: 10
Beispiel
CLEAR MVI C,18 ; Schleifenzaehler auf 24
LXI H,2FE0 ; Anfangsadresse nach HL
LOOP MVI m,00 ; 00 in den RAM uebertragen
INX H ; Adresszeiger erhoehen
DCR C ; Schleifenzaehler -1
JNZ LOOP ; nicht Null? Weiter mit Schleife
...
MOV z, r
move to register z from register r
In das Zielregister z den Inhalt des Ursprungsregister r transportieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
A | B | C | D | E | H | L | |
MOV A, r | 7F | 78 | 79 | 7A | 7B | 7C | 7D |
MOV B, r | 47 | 40 | 41 | 42 | 43 | 44 | 45 |
MOV C, r | 4F | 48 | 49 | 4A | 4B | 4C | 4D |
MOV D, r | 57 | 50 | 51 | 52 | 53 | 54 | 55 |
MOV E, r | 5F | 58 | 59 | 5A | 5B | 5C | 5D |
MOV H, r | 67 | 60 | 61 | 62 | 63 | 64 | 65 |
MOV L, r | 6F | 68 | 69 | 6A | 6B | 6C | 6D |
Taktzyklen: 4
MOV r, m
move to register from memory
Den Inhalt einer Speicherzelle ins Regsister r transportieren. Die Adresse der Speicherzelle sthet im Registerpaar HL
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
MVI r, m | 7E | 46 | 4E | 56 | 5E | 66 | 6E |
Taktzyklen: 7
MOV m, r
move to memory from regsiter
Den Inhalt des Registers r in eine Speicherzelle transportiren. Die Adrees der Speicherzelle steht im Registerpaar HL
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
MOV m, r | 77 | 70 | 71 | 72 | 73 | 74 | 75 |
Taktzyklen: 7
Beispiel
Es soll der Adressbereich 2901 … 2A00 um eine Adresse nach unten verschoben werden
MOVE: LXI H,2A00 ; oberste Adresse nach HL
MVI A,00 ; Vorbereitung fuer Endabfrage
MOV B,m ; erste RAM-Zelle nach B
LOOP: DCX H ; Adresszeiger - 1
MOV C,m ; naechste RAM-Zelle nach C
MOV m,B ; alten Wert an neuen Platz
MOV B,C ; neuen Wert nach B
CMP L ; ist A(=00) gleich L?
JNZ LOOP ; weiter mit Schleife
...
LDA xxyy
load accumulator direct
Den Inhalt der Speicherzelle xxyy in den Akkumulator transportieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | |||||
LDA xxyy | 3A yy xx |
Taktzyklen: 13
STA xxyy
store accumulator direkt
Den Inhalt des Akkumulators in die Speicherzelle xxyy transportieren.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | ||||||
STA xx yy | 32 yy xx |
Taktzyklen: 13
Beispiel
Die Speicherzelle 2FCF dient in einem Anwendungsbeispiel als Indikator dafür, wenn in einem programm von der einen Betriebsart (Mode 1) auf eine andere (Mode 2) umgeschaltet werden soll. Mode 1 ist für das Programm daran erkennbar, dass in der Speicherzelle 2FCF das Bit 0 auf High ist, während im Mode 2 das Bit 1 auf High gesetzt ist.
Zur Umschaltung von einer Betriebsart auf eine andere, holt das Programm den Inhalt der Speicherzelle 2FCF, löscht das eine uns setzt das andere Bit. Anschließend transportiert es den modifizierten Inhalt zurück nach 2FCF.
CHANGE: LDA 2FCF ; Mode-Anzeige holen
ANI FC ; Bits 0 und 1 loeschen
ORI 01 ; Bit 0 (Mode 1) setzen
STA 2CFC ; Mode-Anzeige zurueck ins RAM
...
LDAX rp
load accumulator indirect
Den Inhalt einer Speicherzelle in den Akkumulator transportieren. Die Adresse der Speicherzelle steht im Registerpaar rp.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | B | D | |||||
LDAX rp | 0A | 1A |
Taktzyklen: 7
Beispiel
Um in einem Mikrocomputer eine Siebensegmentanzeige anzusteuern, müssen die binär vorliegenden Daten derart umcodiert werden, dass sie zur Ansteuerung der Leuchtbalken geeignet sind. Das zu codierende Datenwort steht im Beispiel hier in der Speicherzelle 2FCC. Es wird mit Hilfe der indirekten Adressierung über B und C (LDAX B Befehl) in den Akkumulator geholt, wo zunächst die obere Hälfte unterdrückt (auf Null gesetzt) wird (ANI-Befehl)
Die Codes für die Zeichen 0..F stehen in den 16 Zeilen der Tabelle DISTAB, zu deren Adressierung das Registerpaar DE dient. Der in A stehende Wert 0..F gibt an, wie weit der zu holende Code vom Tabellenanfang entfernt steht. Addiert man den Akkumulator-Inhalt zur Tabellen-Anfangsadresse (hier in DE), dann zeigt Registerpaar DE genau auf diejenige Speicherzelle, aus der der zum augenblicklichen Akkumulator-Inhalt passende Code geholt werden muss (indirekte Adressierung über DE, LDAX D Befehl).
CODE: LXI B,2FCC ; Adresse fuer das Datenwort
LXI D,DISTAB ; Lade DE mit Adresse von Tabellenanfang
LDAX B ; Datenwort in den Akku laden
ANI 0F ; obere 4 Bits loeschen
ADD E ; Akku und E addieren
MOV E,A ; Ergebnis zurueck in E
; DE ergeben nun aktuellen Tabellenzeiger
LDAX D ; Code aus der Tabelle laden
OUT 10 ; DisplayCode auf EA-Kanal ausgeben
...
DISTAB: 3F ; Displaycode fuer 0
06 ; Displaycode fuer 1
xx
71 ; Displaycode fuer F
STAX rp
store accumulator indirect
Den Inhalt des Akkumulators in eine Speicherzelle transportieren. Die Adresse der Spiecherzelle steht im Registerpaar rp
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | B | D | |||||
STAX rp | 02 | 12 |
Taktzyklen: 7
PUSH rp
psuh register pair to stack
Den Inhalt des Registerpaares rp in den Stack transportieren (Doppelwort-Operation). PSW beinhaltet den Akkumulator und das Status-Register (Register F)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | B | C | H | PSW | |||
PUSH rp | C5 | D5 | E5 | F5 |
Taktzyklen: 12
Beispiel
Beim Sprung in ein Unterprogramm könnten dort Registerinhalte verändert werden, die anschließend in der alten Form benötigt werden. Um dies zu verhindern, überschreibt man vor dem Sprung ins Unterprogramm sämtliche Registerinhalte (paarweise) in den Stack (PUSH-Befehl) und holt diese nach der Rückkehr ins Hauptprogramm von dort wieder zurück (POP-Befehl).
Da die zuletzt in den Stack eingeschriebene Information als erstes wieder ausgelesen wird, müssen die korrespondierenden PUSH-und POP-Befehle genauso angeordnet sein wie ineinander verschachtelte Klammern in der Algebra.
SAVE PUSH B ; BC in den Stack
PUSH D ; DE in den Stack
PUSH H ; HL in den Stack
PUSH PSW ; Akku und Flags in den Stack
CALL SUBROUT ; Unterprogramm, verändert Register
POP PSW ; Akku und Flags zurueckholen
POP H ; HL zurueckholen
POP D ; DE zurueckholen
POP B ; BC zurueckholen
...
POP rp
pop regsiter pair from stack
Den Inhalt der beiden durch den Stackpointer adressierten Speicherzellen in das Registerpaar rp transportieren (Doppelwort-Operation). PSW beinhaltet den Akkumulator und das Status-Register (Register F)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | x | x | – | x | x | x |
Varianten und Hexcode
r = | B | D | H | PSW | |||
POP rp | C1 | D1 | E1 | F1 |
Taktzyklen: 10
Beispiel
Man kann durch die Kombination verschiedener PUSH- und POP-Befehle den Inhalt von Registerpaaren vertauschen. So existiert beispielsweise kein Befehl, um auf den Inhalt des FLAG-Registers mit den Zustandsbits zuzugreifen. Auf dem Umweg über die folgende Sequenz ist durch dennoch möglich.
READFLAG: PUSH PSW ; Akku und Flag in den Stack
POP H ; Stack in Registerpaar HL laden
; Akku und Flags in HL (Akku -> H, Flag -> L)
XCHG
exchange HL with DE
Die Inhalte der Registerpaare HL und DE miteinander vertauschen (Doppelwort-Operation).
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | – | ||||||
XCHG | EB |
Taktzyklen: 4
Beispiel
Wegen der sehr effektiven Zugriffsmöglichkeiten zu den im Stack gespeicherten Daten (PUSH/POP-Befehle) kann man außer dem System-Stack ohne weiteres auch einen weiteren Stack-Bereich definieren, etwas um sämtliche Register mit dort abgelegten Datensätzen zu laden. Angenommen im Registerpaar DE steht eine Variable (kleiner als 1FFF), die mit Acht zu multiplizieren ist, um auf eine tabelle im RAM zu zeigen. Dann lassen sich mit der folgenden Sequenz alle Register mit den in der Tabelle enthaltenen Daten laden.
LOAD: XCHG ; DE und HL tauschen
DAD H ; HL verdoppeln (x2)
DAD H ; HL verdoppeln (x4)
DAD H ; HL verdoppeln (x8)
SPHL ; HL in den Stackpointer
POP B ; RAM-Daten nach BC
POP D ; RAM-Daten nach DE
POP H ; RAM-Daten nach HL
POP PSW ; RAM-Daten nach A/F
...
LHLD xxyy
load HL direct
Den Inhalt der Speicherzelle xxyy nach L und den Inhalt der Speicherzelle xxyy + 1 nach H transportieren (Doppelwort-Operation).
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | ||||||
LHLD xxyy | 2A yy xx |
Taktzyklen: 16
Beispiel
Zahlreiche Operationen mit indirekter Adressierung laufen über das Registerpaar HL ab. Um dieses Registerpaar nicht ständig zu blockieren, kann man seinen Inhalt (direkt adressiert) im RAM ablegen bzw. von dort zurückholen.
Im Beispiel hier steht in den Speicherzellen 2FE0 und 2FE1 eine 16-Bit-Adresse. Sie wird deshalb nicht als Absolutadresse angegeben, weil sie von anderen Programmteilen modifiziert werden kann. Dies Adresse wird ins Registerpaar HL abgeholt (LHLD-Befehl), wo sie beim anschließenden indirekten Datentransport (MOV-Befehl) als Zieladresse dient.
Wenn in den Speicherzellen 2FE0 und 2FE1 beispielsweise der Inhalt 27B4 steht, dann bewirkt die folgende Sequenz einen Datentransport des Akkumulator-Inhalts in die Speicherzelle 27B4.
STORE: LHLD 2FE0 ; Inhalt von 2FE0 und 2FE1 in Registerpapr HL laden
; Beispielsweise 27B4
MOV m,A ; Akkumulator in 27B4 speichern
...
SHLD 2FE0 ; Registerpaar HL in 2FE0/2FE1 ablegen
...
SHLD
store HL direct
Den Inhalt von Register H an der Speicherzelle xxyy +1 und den Inhalt des Registers L in der Speicherzelle xxyy transportieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
SHLD xxyy | 22 yy xx |
Taktzyklen: 16
XTHL
exchange HL with top of stack
Den Inhalt des Regsiterpaares HL mit dem Inhalt derjenigen Speicherzelle vertauschen, die durch den Stackpointer adressiert wird (Doppelwort-Operation).
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
XTHL | E3 |
Taktzyklen: 16
Beispiel
Bei RETURN-Befehl wird die Programmausführung bei derjenigen Adresse fortgesetzt, die im Stack abgelegt ist und auf die der Stackpointer zum Zeitpunkt der Befehlsausführung zeigt. Um bei einer anderen Adresse fortzusetzen (etwas resultierend aus einer vorangegangenen Operation), kann man diese Zieladresse beispielsweise ins Registerpaar HL transportieren (LXI-Befehl) und mit dem XTHL-Befehl an diejenige Stelle im Stack übertragen, an der zuvor die ursprüngliche Rücksprungadresse gestanden hat. Bei Erreichen des Returnbefehls erfolgt dann die Verzweigung zu der neu eingegebenen Adresse (hier 2A61).
BRANCH: LXI H,2A61 ; neue Zieladresse in HL laden
XTHL ; HL und Inhalt des Stack austauschen
...
..
RET ; "Rücksprung" nach 2A61
SPHL
move HL to stackpointer
Den Inhalt des Regsiterpaares HL in den Stackpointer transportieren (Doppelwort-Operation).
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
SPHL | F9 |
Taktzyklen: 6
Daten Ein-/ Ausgabe
IN xx
input from port
Dei am E/A-Kanal xx anliegende Information in den Akkumulator transportieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | ||||||
IN xx | DB xx |
Taktzyklen: 10
Beispiel
Periphere Stellen (z.B. Tastatur oder Anzeigen) lassen sich in einem Mikrocomputer ohne weiteres genauso ansprechen (adressieren) wie Speicherzellen (Memory Mapped IO), einschließlich der damit verbundenen Vorteile wie z.B. die indirekte Adressierung. Der Nachteil dieses Verfahrens besteht darin, dass dadurch Teile des verfügbaren Adressraumes für die Peripherie verloren gehen.Darum gibt es den IN- und OUT-Befehl. Die beiden enthalten eine 8-Bit breite Adresse um damit (zusätzlich zum 64K Adressraum) weitere 256 Ziele ansprechen zu können (I/O-Mapped)
Bei den folgenden Sequenzen werden in einer Endlosschleife die Daten vom Eingabekanal EC gelesen und an den Ausgabekanal 00 invertiert wieder ausgegeben.
INOUT: IN EC ; EA-Kanal EC in den Akku laden
CMA ; Inhalt des Akkus invertieren
OUT 00 ; Akku auf EA-Kanal 00 wieder ausgeben
JMP INOUT ; Endlosschleife
OUT xx
output to port
Den Inhalt des Akkumulators an den E/A-Kanal xx transportieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | ||||||
OUT xx | D3 xx |
Taktzyklen: 10
RIM
read interrupt mask
Den Pegel des seriellen CPU-Eingangs SID ins MSB des Akkumulators transportieren und die drei zu den Unterbrechungseingängen RST 5.5, RST 6.5 sowie RST 7.5 gehörenden Masken-Bits in die drei unteren Akkumulator-Bits transportieren.
Nach der Ausführung des RIM-Befehls stehen im Akkumulator folgende Informationen:
- In den unteren drei Bits 0..2 stehen die mit den Unterbrechungseingängen RST 5.5, RST 6.5 und RST 7.5 korrespondierenden Bits des Interrupt-Masken-Registers. High bedeutet, dass der betreffende Unterbrechungseingang gesperrt ist.
- In den Bits 4..6 ist der Zustand der Eingänge RST 5.5, RST 6.5 und RST 7.5 ablesbar, unabhängig davon, welche Maskenbits gesetzt sind.
Beim Interrupt-Eingang RST 7.5 genügt ein kurzer Impuls (Flankengetriggert) - Bit 7 hat den selben Pegel wie der serielle CPU-Eingang SID
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | ||||||
RIM | 20 |
Taktzyklen: 4
Die Befehle RIM und SIM haben eine Doppelfunktion. Sie dienen einerseits zum Datenverkehr zwischen dem Akkumulator und den seriellen CPU-Anschlüssen SID und SOD und andererseits lesen bzw. laden sie das Interrupt-Masken-Register. In diesem Register wird festgelegt, welcher der drei CPU-Unterbrechungseingänge RST 5.5, RST 6.5 und RST 7.5 für externe Unterbrechungen vorbereitet (maskiert) wird.
Bei der Aktivierung eines der CPU-Unterbrechungs-Eingänge TRAP, RST 7.5, RST 6.5 RST 5.5 und INTR unterbricht der Prozessor nach Beendigung des augenblicklich in der Ausführung befindlichen Befehls sein laufendes Programm und springt zu einer festen Zieladresse.
Voraussetzung für jede Programmunterbrechung ist es, dass Interrupts generell freigegeben worden sind. (Siehe auch Enable Interrupt EI). Für die Unterbrechungseingänge RST 7.5, RST 6.5 und RST 5.5 ist zusätzlich noch das zugehörige Maskenbit im Interrupt-Masken-Register auf Low zu setzen.
Beispiel
Um den Pegel am serillen CPU-Eingang SID per Programm abzufragen, kann man ihn beispielsweise ins MSB des Akkumulators und von dort ins Carry-Bit transportieren um danach einen bedingten Sprung anzufügen.
SIDIN: RIM ; SID Pegel der CPU in den Akku laden (MSB)
NOP ; weiter mit naechsten Befehl
RLC ; Akku nach links verschieben, MSB in das C-Bit
JC SIDCTE ; Carry bzw. SID = 1: weiter mit SIDCTE
xxx
SIM
set intrrupt mask
Den MSB-Pegel es Akkumulators zum seriellen CPU-Ausgang SOD transportieren. Dazu muss das Bit 6 (zweithöchste Bit) auf HIGH sein.
Zusätzlich: Die Möglichkeit, die drei Unterbrechungseingänge RST 5.5, RST 6.5 und RST 7.5 freizugeben (zu maskieren), indem das korrespondierende Bit 0..2 auf LOW gesetzt wird. Zu diesem Setzvorgang muss das Bit 3 auf HIGH sein.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | ||||||
SIM | 30 |
Taktzyklen: 4
Siehe Details bei dem Befehl RIM
Beispiel
Der Pegel des höchstwertigen Akkumulator-Bits (MSB) erscheint nach dem SIM-Befehl am seriellen CPU-Ausgang SOD. Dazu muss das Akkumulator-Bit 6 auf High sein. Um beispielsweise den von SID eingelesenen Pegel invertiert wieder an SOD auszugeben, bedient man sich folgender Sequenz:
SIDNOT: RIM ; SID-Pegel in den Akku laden (MSB)
CMA ; Akku invertieren
ANI 80 ; Bit 0..6 loeschen
ORI 40 ; Bit 6 setzen
SIM ; Akku (MSB) an SOD ausgeben
JMP SIDNOT ; Endlosschleife
Arithmetrische / Logische Befehle
INR r
increment register
Den Inhalt des Registers r um Eins erhöhen
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | – |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
INR r | 3C | 04 | 0C | 14 | 1C | 24 | 2C |
Taktzyklen: 4
INR M
increment memory
Den Inhalt einer Speicherzelle um Eins erhöhen. Die Adresse der Speicherzelle steht im Registerpaar HL
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | – |
Varianten und Hexcode
r = | |||||||
INR m | 34 |
Taktzyklen: 10
Beispiel
Ein in der Speicherzelle 2B9F stehender Wert soll so weit vergrößert werden, dass er gleich groß ist wie der Akkumulator-Inhalt. Dabei ist die Randbedingung einzuhalten, dass das Erhöhen nach maximal zehn Schritten abzubrechen ist, um beispielsweise in einem Regelkreis überschwinger zu vermeiden.
COUNT: LXI H,2BF9 ; Adresse in HL laden
MVI C,0A ; Schrittzaehler in Register C
LOOP: CMP m ; Akku mit Speicherzelle [HL] vergleichen
JZ COUNTCTE ; gleich: weiter mit COUNTCTE
INR m ; sonst Inhalt von 2BF9 erhoehen
DCR C ; Schrittzaehler verringern
JNZ LOOP ; nicht Null: weiter mit Schleife
COUNTCTE: ...
INX rp
increment register pair
Den Inhalt des Registerpaares rp um Eins erhöhen (Doppelwort-Operation).
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | B | D | H | SP | |||
INX rp | 03 | 13 | 23 | 33 |
Taktzyklen: 6
Beispiel
Bei einer Datenübertragung (Ausgabe über Port 00) stehen im Registerpaar HL die Anfangs- und im Registerpaar DE die Endadresse des zu übertragenden Speicherbereichs. Nach jeder Ausgabe eines Datenbytes wird der Inhalt von HL um Ein erhöht und im Unterprogramm COMPARE mit dem Inhalt von DE verglichen, um das Übertragungsende zu erkennen. Beim Rücksprung au COMPARE ist das Zero-Bit High, wenn die Inhalte der Registerpaare DE und HL gleich sind.
SERIEL: LXI H,2800 ; Anfangsadresse in das Registerpaar HL
LXI D,2AFF ; Endadresse in DE
LOOP: MOV A,m ; erstes Datenwort in den Akku
OUT 00 ; Akku auf EA-Kanal 00 ausgeben
INX H ; Adresse erhöhen
CALL COMPARE ; Endadresse erreicht?
JNZ LOOP ; nein: weiter mit Schleife
...
DCR r
decrement register
Den Inhalt des Registers r um Eins verringern
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | – |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
DCR r | 3D | 05 | 0D | 15 | 1D | 25 | 2D |
Taktzyklen: 4
DCR m
decrement memory
Den Inhalt einer Speicherzelle um Eins verringern. Die Adresse der Speicherzelle steht im Registerpaar HL
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | – |
Varianten und Hexcode
r = | |||||||
DCR m | 35 |
Taktzyklen: 10
DCX rp
decrement register pair
Den Inhalt des Registerpaares rp um Eins verringern (Doppelwort-Operation).
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | B | D | H | SP | |||
DCX rp | 0B | 1B | 2B | 3B |
Taktzyklen: 6
ADI xx
add immediate
Zum Inhalt des Akkumulators des Datenwort xx addieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | ||||||
ADI xx | C6 xx |
Taktzyklen: 7
Beispiel
Ein zuvor errechneter Wert, der in der Speicherzelle 2937 steht, ist um den konstanten Betrag von (dezimal) 18 zu erhöhen, bevor er weiterverarbeitet wird. Tritt bei der Addition jedoch ein Überlauf auf, so ist der Maxmialwert „FF“ weiterzubegeben.
ADDIER: LDA 2937 ; Speicherzelle in den Akku laden
ADI 12 ; 18 zum Akku Addieren
JNC ADDCTE ; kein Ueberlauf: weiter
MVI A,FF ; Maximalwert in den Akku
ADDCTE: STA 2937 ; Neuer Wert in Speicherzelle schreiben
...
ACI xx
add immediate with carry
Zum Inhalt des Akkumulators des Datenwort xx addieren sowie das C-Bit (Carry-Flag) addieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
ACI xx | CE xx |
Taktzyklen: 7
ADD r
add register
Zum Inhalt des Akkumulators den Inhalt des Registers r addieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
ADD r | 87 | 80 | 81 | 82 | 83 | 84 | 85 |
Taktzyklen: 4
Beispiel
Es sollen die Inhalte der Registerpaare BC und DE addiert werden (Ergebnis in DE). Das Registerpaar HL ist dabei nicht frei.
Die Addition erfolgt in zwei Teilen, beginnend mit den unteren Hälften der Summanden (Inhalte der Register C und E: ADD_Befehl). Da hierbei ein Übertrag auftreten kann (Carry-Bit High), muss die Addition der oberen Hälften der Summanden den Zustand des C-Bits mit einbeziehen (ADC-Befehl). Nach diesem Schema lassen sich Additionen mit belieb langer Wortlänge durchführen.
ADDRP: MOV A,E ; untere Hälfte des ersten Summanden in den Akku laden
ADD C ; Register C zum Akku addieren
MOV E,A ; untere Ergebnishälfte nach E
MOV A,D ; obere Hälfte des ersten Summanden nach Akku
ADC B ; B und Carry zum Akku addieren
MOV D,A ; obere Ergebnishälfte nach D
...
ADC r
add register with carry
Zum Inhalt des Akkumulators den Inhalt des Registers r addieren sowie das C-Bit (Carry-Flag) addieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
ADC r | 8F | 88 | 89 | 8A | 8B | 8C | 8D |
Taktzyklen: 4
ADD m
add memory
Zum Inhalt des Akkumulators den Inhalt einer Speicherzelle addieren. Die Adresse der Speicherzelle steht im Registerpaar HL
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
ADD m | 86 |
Taktzyklen: 7
Beispiel
Ein zuvor errechneter Wert, der in der Speicherzelle 2937 steht, ist um den konstanten Betrag von (dezimal) 18 zu erhöhen, bevor er weiterverarbeitet wird. (indirekte Adressierung über das Registerpaar HL) Tritt bei der Addition jedoch ein Überlauf auf, so idte der Maximalwert „FF“ weiterzugeben.
ADDIER2: LXI H,2937 ; Adress in HL
MVI A,12 ; Summand in den Akku laden
ADD m ; Speicherinhalt mit dem Akku addieren
JNC ADD2CTE ; kein Ubertrag: weiter
MVI A,FF ; Maximalwert in den Akku
ADD2CTE: MOV m,A ; neuer Wert in die Speicherzelle
...
ADC m
add memory with carry
Das Register r mit dem Datenwort XX laden
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
ADC m | 8E |
Taktzyklen: 7
DAD rp
add register pair to HL
Den Inhalt des Registerpaares rp zu HL addieren (Doppelwort-Operation)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | x |
Varianten und Hexcode
r = | B | D | H | SP | |||
DD rp | 09 | 19 | 29 | 39 |
Taktzyklen: 10
Beispiel
Der im Register E stehende Wert soll mit Fünf multipliziert werden. Ein eventuell auftretender Übertrag ist im Register D abzulegen. Das Ergebnis steht somit im Registerpaar DE.
MULT: MVI C,05 ; Multiplikator 05 in C-Register laden
LXI H,0000 ; Ergebnisregister loeschen
MVI D,00 ; obere Halefte von DE loeschen
LOOP: DAD D ; DE und HL addieren
DCR C ; Schleifenzaehler verringern
JNZ LOOP ; nicht null: Schleife
XCHG ; Ergebnis von HL in DE uebertragen
Es existiert zwar ein Befehl, um den Inhalt des Registerpaares HL in den Stack-Pointer zu transportieren. Die umgekehrte Instruktion (Inhalt des Stackpointers in ein Registerpaar transportieren) gibt es allerdings nicht. Auf folgenden Umweg kommt man dennoch an den Inhalt des Stack-Pointers heran:
LOADSP: LXI H,0000 ; HL loeschen
DAD SP ; SP (Stackpointer) zu HL addieren
; in HL steht nun der Inhalt des Stackpointers
...
DAA
decimal adjust accumulator
Dezimalkorrektur des Akkumulators nach einer arithmetischen Operation (Umsetzung in zwei BCD-Digits). Dazu wird zum Inhalt des Akkumulators hexadezimal 06 addiert. Wenn die unteren vier Bits größer als 9 (binar 1001) sind. Sind die oberen vier Akkumulator-Bits größer als 9 wird hexadezimal 60 addiert.
Die Addition von hexadezimal 06 (bzw. 60) erfolgt auch dann, wenn resultierend aus einer vorhergehenden Befehlsausführung das AC-Bit (bzw. C-Bit) gesetzt ist.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
DAA | 27 |
Taktzyklen: 4
Beispiel
Der Akkumulator-Inhalt soll nicht hexadezimal sondern in der Form von zwei BCD-Digits hochgezählt werden (also z.B. von 29 auf 30 statt auf 2A).
ADJUST: MVI A,29 ; Akku mit 29 laden
INR A ; Akku um 1 erhoehen
DAA ; Dezimalkorrektur
...
Info: Bei der Ausführung des DAA-Befehls im Beispiel hier erfolgt eine Deimalkorrektur (übertragung von der unteren zur oberen Hälfte des Akkumulators), so dass dadurch das AC-Bit (Aux Carry) gesetzt wird. Würde man hinter den ersten einen weiteren DAA-Befehl setzen (was programmtechnisch keinen Sinn ergäbe), würde der Akkumulator-Inhalt dadurch auf 36 erhöht werden, weil aufgrund einer vorangegangenen Operation (erster DAA-Befehl) das AC-Bit auf High liegt und demzufolge 06 zum Akkumulator-Inhalt addiert wird
Im Zusammenhang mit dem DAA-Befehl ist daher darauf zu achten, dass das Carry- oder AC_Bit durch keinen andrer als den INR-A-Befehl modifiziert wird.
SUI xx
subtract immediate
Vom Inhalt des Akkumulators das Datenwort xx subtrahieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
SUI xx | D6 xx |
Taktzyklen: 7
Beispiel
Ein zuvor errechneter Wert, der in der Speicherzelle 2937 steht, ist um den konstanten Betrag von (dezimal) 18 zu verringern, boevor er weiterverarbeitet wird. Tritt bei der Subtraktion jedoch ein (negativer) Übertrag auf, so ist der Minimalwert „00“ weiterzugeben
SUBTRAC: LDA 2937 ; Speicherinhalt laden
SUI 12 ; von A 18 abziehen
JNC SUBCTE ; kein Uebertrag, Ergebnis nicht negativ
; weiter im Programm
MVI A,00 ; Minimalwert in den Akku
SUBCTE: STA 2937 ; Neuer Wert in die Speicherzelle
...
SBI xx
subtract immediate with borrow
Vom Inhalt des Akkumulators das Datenwort xx, sowie das C-Bit subtrahieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
SBI xx | DE xx |
Taktzyklen: 7
SUB r
subtract register
Vom Inhalt des Akkumulators das Register r subtrahieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
SUB r | 97 | 90 | 91 | 92 | 93 | 94 | 95 |
Taktzyklen: 4
Beispiel
Es soll der Inhalt des Registerpaares BC vom Inhalt des Registerpaares DE subtrahiert werden (Ergebnis in DE).
Die Subtraktion erfolgt in zwei Teilen. Beginnend mit dem unteren Hälften der Operanden (Inhalte der Register C und E; SUB-Befehl). Da hierbei ein negativer Übertrag auftreten kann (Carry-Bit auf High), muss die Subtraktion der oberen Hälfte der Operanden den Zustand des C-Bits mit einbeziehen. (SBB-Befehl). Nach diesem Schema lassen sich Subtraktionen mit beliebig langer Wortlänge durchführen.
SUBRP: MOV A,E ; untere Hälfte des Minuenden nach A
SUB C ; C von A subtrahieren
MOV E,A ; untere Ergebnishälfte nach E
MOV A,D ; Obere Ergebnishälfte des Minuenden nach A
SBB B ; B und Carry-Bit von A subtrahieren
MOV D,A ; obere Ergebnishälfte nach D
...
SBB r
subtract register with borrow
Vom Inhalt des Akkumulators das Register r, sowie das C-Bit subtrahieren
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
SBB r | 9F | 98 | 99 | 9A | 9B | 9C | 9D |
Taktzyklen: 4
SUB m
subtract memory
Vom Inhalt des Akkumulators den Inhalt der Speicherzelle subtrahieren. Die Adresse der Speicherzelle steht im Registerpaar HL
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
SUB m | 96 |
Taktzyklen: 7
Beispiel
Ein zuvor errechneter Wert der in der Speicherzelle 2937 steht, ist um den konstanten Betrag von (dezimal) 18 zu verringern, bevor er weiterverarbeitet wird. Tritt bei der Subtraktion jedoch ein negativer Übertrag auf, so ist der Minimalwert 00 weiterzugeben
SUBTR2: LXI H,2937 ; Adresse nach HL
MOV A,m ; Minuend in den Akku
MVI m,12 ; Subtrahend in die Speicherzelle
SUB m ; RAM-Inhalt von A subtrahieren
JNC SUBCTE ; kein Uebertrag, Programm fortsetzen
MVI A,00 ; Minimalwert in Akku
SUBCTE: MOV m,A ; neuer Wert nach 2937
...
SBB m
subtract memory with borrow
Vom Inhalt des Akkumulators den Inhalt der Speicherzelle sowie das C-Bit subtrahieren. Die Adresse der Speicherzelle steht im Registerpaar HL
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
SBB m | 9E |
Taktzyklen: 7
Bit-Manipulation
CMA
complement accumulator
Den Inhalt des Akkumulators invertieren.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
CMA | 2F |
Taktzyklen: 4
Beispiel
Gelegentlich werden pegelzustände durch Leuchtdioden dargestellt. Wenn die Treiberschaltung nichtinvertierend sind, muss der ansteuernde Pegel zuvor invertiert werden. Beim Akkumulator-Inhalt kann man dies mit dem Einwortbefehl CMA bewerkstelligen. Zum selben Ergebnis, allerdings mit einem Zweitwortbefhl, führt die Exklusiv-Oder-Verknüpfung des Akkumulators mit FF (XRI FF)
LDA 2937 ; Lade Speicherzelle in den Akku
CMA ; Invertiere Akku für Pegelwandlung
OUT 02 ; Ausgabe an E/A-Kanal
STC
set carry
Das C-Bit wird auf High gesetzt.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | x |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
STC | 37 |
Taktzyklen: 4
Beispiel
Als Indikator für ein bestimmtes Ergebnis, das die Zustandsbits nicht beeinflusst hat, soll ein Unterprogramm an das übergeordnete Hauptprogramm das Carry-Bit definiert übergeben. Zum setzen dient der Befehl STC. Zum Löschen muss dem STC-Befehl die Anweisung CMC (Carry-Bit invertieren) nachgestellt werden.
STC
CMC
complement carry
Den Zustand des C-Bits invertieren.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | 0/1 |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
CMC | 3F |
Taktzyklen: 4
ANI xx
AND immediate
Den Inhalt des Akkumulators mit dem Datenwort xx logisch UND-verknüpfen
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
ANI xx | E6 xx |
Taktzyklen: 7
Beispiel
Nach dem Transport des SID-Pegels ins MSB des Akkumulators (RIM-Befehl) soll dieser Zustand invertiert am seriellen CPU-Ausgang SOD ausgegeben werden (SIM-Befehl).
Damit die bei SIM möglichen anderen Auswirkungen unterbleiben (Beeinflussung des Interrupt-Masken-Registers), werden die Akkumulator-Bits 0..6 mit dem ANI-Befehl gelöscht. Bit 7 wird hierdurch nicht verändert, weil das korrespondierende Bit 7 im Operanden 80 auf High liegt.
SERINOT: RIM ; SID-Pegel in den Akku transportieren
CMA ; Akku invertieren
ANI 80 ; Bits 0..6 loeschen
ORI 40 ; Bit 6 setzen
SIM ; Akku, MSB an SOD ausgeben
...
ANA r
AND register
Den Inhalt des Akkumulators mit dem Register r logisch UND-verknüpfen
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
ANA r | A7 | A0 | A1 | A2 | A3 | A4 | A5 |
Taktzyklen: 4
ANA m
AND memory
Den Inhalt des Akkumulators mit dem Inhalt der Speicherzelle logisch UND-verknüpfen. Die Adresse der Speicherzelle steht im Register HL
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
ANA m | A6 |
Taktzyklen: 7
ORI xx
OR immediate
Den Inhalt des Akkumulators mit dem Datenwort xx logisch ODER-verknüpfen.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
ORI xx | F6 xx |
Taktzyklen: 7
ORA r
OR register
Den Inhalt des Akkumulators mit dem Register r logisch ODER-verknüpfen.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
ORA r | B7 | B0 | B1 | B2 | B3 | B4 | B5 |
Taktzyklen: 4
ORA m
OR memory
Den Inhalt des Akkumulators mit dem Inhalt einer Speicherzelle logisch ODER-verknüpfen. Die Adresse der Speicherzelle steht im Registerpaar HL.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
ORA m | B6 |
Taktzyklen: 7
XRI xx
XOR immediate
Den Inhalt des Akkumulators mit dem Datenwort xx logisch Exklusiv-ODER-verknüpfen.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
XRI xx | EE |
Taktzyklen: 7
Beispiel
Bei einem Verfahren der Anlag/Digital-Umsetzung (Sukzessive Approximation) wird der Akkumulator-Inhalt zunächst gelöscht (hier mit XRA A). Dann wird der Akkumulator-Inhalt mit einem Bit-Zeiger (Datenwort mit nur einem High-Bit, hier im Register B) ODER-Verknüpft und an den Digital/Analog-Umwandler ausgegeben (Ausgabekanal 27). Wenn der so gebildete Analogwert größer oder ist als der zu digitalisierende (Abfrage eines Komperators am Eingabekanal 28), muss das zuletzt gesetzte Bit wieder gelöscht werden (XRA B-Befehl)
ADCONVERT: XRA A ; Akku löschen
MVI B,80 ; Bit-Zeiger laden (MSB High)
LOOP1: ORA B ; MSB-Bit im Akku setzen
MOV C,A ; Akku in C uebertragen
OUT 27 ; Akku an den DA-Wandler ausgeben
IN 28 ; Komparator-Ausgang einlesen
RLC ; MSB in das C-Bit uebertragen
MOV A,C ; alten Wert in den Akku zurueckholen
JC ADCTE ; dig. Wert zu klein: ADCTE
XRA B ; gesetztes Bit wieder loeschen
ADCTE: MOV A,B ; B in den Akku uebertragen
RRC ; rechtsverschieben (:2)
MOV B,A ; Bit-Zeiger zurueck nach B
MOV A,C ; aktuellen Wert zurueckholen
JNC LOOP1 ; noch nicht fertig: Schleife
...
XRA r
XOR register
Den Inhalt des Akkumulators mit dem Register r logisch Exklusiv-ODER-verknüpfen.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
XRA r | AF | A8 | A9 | AA | AB | AC | AD |
Taktzyklen: 4
XRA m
XOR memory
Den Inhalt des Akkumulators mit Inhalt einer Speicherzelle logisch Exklusiv-ODER-verknüpfen. Die Adresse der Speicherzelle steht im Registerpaar HL.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
XRA m | AE |
Taktzyklen: 7
RLC
rotate left
Den Inhalt des Akkumulators zyklisch um ein Bit links verschieben.
Das MSB gelangt ins C-Bit und ins LSB-Bit
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | x |
Varianten und Hexcode
r = | A | ||||||
RLC | 07 |
Taktzyklen: 4
Beispiel
Um den Pegel am seriellen CPU-Eingang SID per Programm abzufragen, kann man ihn beispielsweise mit dem RIM-Befehl ins MSB des Akkumulators transportieren und anschließend mit einem Links-Schiebebefehl ins Carry-Bit bringen um einen bedingten Sprung (JC / JNC) auszuführen.
SIDIN: RIM ; SID-Pegel in den Akku
NOP ; weiter mit naechsten Befehl
RLC ; Akku: MBS ins C-Bit verschieben
JC SIDCTE ; SID = High weiter im Programm
JMP SIDIN ; Schleife
SIDCTE: ...
RAL
rotate left through carry
Den Inhalt des Akkumulators unter Einbeziehung des C-Bits zyklisch um ein Bit links verschieben.
Das MSB gelangt ins C-Bit und ins LSB-Bit
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | x |
Varianten und Hexcode
r = | A | ||||||
RAL | 17 |
Taktzyklen: 4
RRC
rotate right
Den Inhalt des Akkumulators zyklisch um ein Bit rechts verschieben.
Das MSB gelangt ins C-Bit und ins LSB-Bit
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | x |
Varianten und Hexcode
r = | A | ||||||
RRC | 0F |
Taktzyklen: 4
Beispiel
Um den Akku-Inhalt mit Vielfachen von Zwei zu multiplizieren (bzw. zu dividieren), brauchts man ihn ur entsprechend oft (pro Zweierpotenz einmal) nach links bzw. rechts zu verschieben
LDA 2973 ; Lade Speicherzelle in den Akku
RRC ; Verschiebe den Inhalt des Akkus um ein Bit nach rechts
RRC ; -> entspricht Akku / 2
STA 2973 ; neuen Wert in Speicherzelle transportieren
RAR
rotate right through carry
Den Inhalt des Akkumulators unter Einbeziehung des C-Bits zyklisch um ein Bit rechts verschieben.
Das MSB gelangt ins C-Bit und ins LSB-Bit
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | x |
Varianten und Hexcode
r = | A | ||||||
RAR | 1F |
Taktzyklen: 4
Vergleiche
CPI xx
compare immediate
Den Inhalt des Akkumulators mit dem Datenwort xx vergleichen.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
CPI xx | FE xx |
Taktzyklen: 7
Beispiel
Eine Tastatur liefert über den Eingabekanal 04 den Tastencode „42“ (ASCII für B) an den Mikrocomputer. Das zugehörige Programm muss jede Eingabe daraufhin überprüfen, ob ein B angekommen ist, weil dann zum Programmteil CTEB verzweigt werden soll.
Die Abfrage nach einem beliebigen Bitmuster (Datenwort) erfolgt über den CPI-Befehl, nach dessen Ausführung das ZERO-Bit High ist, wenn der Akkumulator-Inhalt und das zum Vergleich herangezogene Datenwort gleich sind.
KEYIN: IN 04 ; Tastencode in den Akku laden
CPI 42 ; Akku mit 42 vergleichen
JZ CTEB ; Zero = 1 bei Akku = 42
; weiter mit CTEB
...
Ein Unterprogramm soll den Inhalt der Registerpaare DE und HL miteinander vergleichen, um beispielsweise festzustellen, ob bei einer Datenübertragung die Endadresse erreicht ist.
Beim Rücksprung aus dem hier aufgeführten Unterprogramm COMPARE ist das ZERO-Bit auf High, wenn die Inhalte beider Registerpaare gleich sind.
COMPARE: MOV A,E ; Register E in den Akku
CMP L ; Akku und Register L vergleichen
RNZ ; Zero = 0, ungleich: Ruecksprung
MOV A,D ; Register D in den Akku
CMP H ; Akku und Register H vergleichen
RET ; Ruecksprung, Zero = 1 wenn beide Register gleich sind
CMP r
compare register
Den Inhalt des Akkumulators mit dem Register r vergleichen.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
CMP r | BF | B8 | B9 | BA | BB | BC | BD |
Taktzyklen: 4
CMP m
compare memory
Den Inhalt des Akkumulators mit dem Inhalt einer Speicherzelle xx vergleichen. Die Adresse der Speicherzelle steht im Registerpaar HL.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
x | x | – | x | – | x | – | x |
Varianten und Hexcode
r = | A | ||||||
CMP m | BE |
Taktzyklen: 7
Beeinflussung des Programmablaufs
PCHL
move HL to PC
Den Inhalt des Registerpaares HL in den Programmzähler (PC) transportieren (unbedingter indirekter Sprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
PCHL | E9 |
Taktzyklen: 6
Beispiel
In einem Programmteil kann der Akkumulator die Werte 0..3 annehmen. Resultierend hieraus soll das Programm zu einer der vier Adressen 012F, 02BD, 030A bzw. 0479 verzweigen (PCHL-Befehl). Die Zieladressen stehen nacheinander in einer Sprungtabelle JMPTAB. Die untere Adresshälfte steht dabei jeweils zuerst im Speicher.
BRANCH: LXI H,JMPTAB ; Anfangsadresse der Sprungtabelle ein HL
ADD A ; A verdoppeln
ADD L ; 2 * A zur Tabellenanfangsadresse addieren
MOV L,A ; A+L zurueck nach L
MOV E,m ; Zieladresse (untere Haelfte)
INX H ; Adresszeiger erhoehen
MOV D,m ; Zieladresse (obere Haelfte)
; DE = Adresse Sprungziel
XCHG ; DE nach HL (tausch)
PCHL ; Zieladresse in den Programmzaehler (unbedingter Sprung)
JMPTAB: 2F ; Erstes Ziel, untere Haelfte
01 ; Erstes Ziel, obere Haelfte
BD ; ...
02
0A
03
79
04
NOP
no operation
Programmfortsetzung beim nächsten Befehl
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
NOP | 00 |
Taktzyklen: 4
HLT
halt
Programmausführung bis zu einem Interrupt oder Hardwarereset stoppen. Nach der Ausführung ds HLT-Befehls gehen sämtliche Busleitungen in den hochohmigen Zustand.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
HTL | 76 |
Taktzyklen: 5
Beispiel
Ein Programm soll zum Akkumulator-Inhalt des Inhalt des Registers B addieren und das Ergebnis am Ausgabekanal 00 bereitstellen. Weitere Aktitvitäten werden nicht verlangt, so dass der Prozessor anschließend mit dem HLT-Befehl in den Wartezustand gebracht werden kann. Aus diesem Zusatnd kommt er nur durch einen Interrupt oder Hardware-Reset wieder heraus.
WAIT: ADD B ; A und B addieren
OUT 00 ; A ueber den E/A-Kanal 00 ausgeben
HLT ; Prozessor anhalten
EI
enable interrupt
Externe Programmunterbrechung erlauben.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
EI | FB |
Taktzyklen: 4
Beispiel
Nach einem Hardware-Reset sind im Interrupt-Masken-Register die unteren drei Bit 0..2 auf High, d.h. die drei Unterbrechungseingänge RST 5.5, RST 6.5 und RST 7.5 sind, wie auch die übrigen Interrupt-Eingänge, automatisch gesperrt.
ENINT: MVI A,0A ; RAT 5.5 und RST 7.5 freigeben
SIM ; Akku ins Interrupt-Masken-Register schreiben
EI ; vom Uebernaechsten Befehl an
; Interrupts zulassen
...
DI
disable interrupt
Externe Programmunterbrechung sperren.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
DI | F3 |
Taktzyklen: 4
Beispiel
Wenn bestimmte Stellen eines Programmes nicht durch einen Interrupt unterbrochen werden sollen, wird mit dem Befehl DI das interne IE-Flip-Flop zurückgestellt, wodurch sämtliche Interrupts gesperrt sind. Am Zustand des Interrupt-Masken-Registers ändert sich dadurch nichts.
Der Interrupt TRAP lässt sich durch DI allerdings nicht sperren und wird folglich immer ausgeführt (Sprung zu Adresse 0024).
RST n
restart
Einwort-Unterprogramm-Aufruf mit fester Zieladresse (n * 8).
Die acht Restart-Befehle sind Einwort-Sprungbefehle ins Unterprogramm, bei denen die Zieladresse implizit enthalten ist. Auch hierbei wird, wie bei allen Unterprogramm-Aufrufen, die Adresse des nächsten Befehls in den Stack überschrieben, damit bei dieser Adresse fortgesetzt werden kann.
Diese Befehle können ohne weiteres im Anwenderprogramm verwendet werden, obwohl sie primär für die Verarbeitung externer Programmunterbrechungen am CPU-Eingang INTR vorgesehen sind. Als Reaktivierung auf eine Aktivierung an diesem Eingang unterbricht die CPU die laufende Programmausführung, liest die auf dem Datenbus anliegende Information ein und verarbeitet sie als Befehl. Wenn die periphere, unterbrechende Stelle zu diesem Zeitpunkt einen Restart-Befehl auf den Datenbus schaltet, lassen sich ohne großen Hardwareaufwand acht verschiedene Sprungziele unterscheiden, zu denen als Reaktion auf einen Interrupt verzweigt werden soll.
Um die Unterbrechungseingänge RST 5.5, RST 6.5 und RST 7.5 gezielt freizugeben oder sperre zu können (SIM-Befehl auf den Umweg über den Akkumulator) , muss man die drei unteres Bits im Interrupt-Masken-Register löschen (entspricht „freigeben“) oder setzen (entspricht „sperren“). Zu dieser Modifikation muss Bit 3 auf High sein, unabhängig davon, welcher der Unterbrechungseingänge freigegeben oder gesperrt ist.
Eine RST 7.5-Auslösung kann mit High-Pegel in Bit 4 wieder gelöscht werden, unabhängig davon, welche Maskenbits gesetzt sind.
Die Bits 5..7 beeinflussen den seriellen CPU-Ausgang SOD. Im hier betrachteten Fall sollten sie daher auf Low bleiben.
Um beispielsweise den RST 5.5 und den RST 7.5-Interrupt-Eingang freizugeben, sind die Bits 0 und 2 im Interrupt-Masken-Register auf Low zu setzen.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
n = | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
RST n | C7 | CF | D7 | DF | E7 | EF | F7 | FF |
Adresse | 0000 | 0008 | 0010 | 0018 | 0020 | 0028 | 0030 | 0038 |
Taktzyklen: 12
Beispiel
Sofern im Programm der Befehl EI (Enable Interrupt) durchlaufen wurde, akzeptiert die CPU externe Programmunterbrechungen, die durch High-Pegel an den Unterbrechungseingängen ausgelöst werden.
Wenn beispielweise vier externe Stellen zum INTR-Eingang Zugriff haben (über Hardware-ODER-Verknüpfung), können diese mit einfachen Mitteln einen Interrupt-Vektor (Sprungziel für die Interrupt-Service-Routine) erzeugen.
Nach der Aktivierung des INTR-Eingangs erzeugt der Prozessor (Außer dem INTA-Signal) einen RD-Impuls, mit dem die Information vom Datenbus gelesen und als Befehl verarbeitet wird.
Liegen zu diesem Zeitpunkt alle Datenbits auf Highg (z.B. über hochohmige Pull-Up-Widerstände), wird „FF“ eingelesen, was dem RST 7-Befehl entspricht (festes Sprungziel 0038 für eine der unterbrechenden Stellen).
Legt die unterbrechende Stelle zeitgleich mit dem RD-Impuls eins der Datenbits 3,4,oder 5 auf Low, liest die CPU entsprechend F7, EF oder DF ein. Dies entspricht dann den Befehlen RST 6, RST 5 bzw. RST 3 mit dem zugehörigen Sprungzielen für drei weitere unterbrechende Stellen.
ENINT: MVI A,0A ; Bits 0 und 2 auf Low
SIM ; Akku-Inhalt in da Maskenregister
EI ; Interrupts freigeben
...
Sprünge (Bedingte / unbedingte)
JMP xxyy
jump
Sprung zur Adresse xxyy (unbedingter Sprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
JMP xxyy | C3 yy xx |
Taktzyklen: 7
JZ xxyy
jump on zero
Sprung zur Adresse xxyy wenn das Z-Bit gesetzt ist (bedingter Sprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
JZ xxyy | CA yy xx |
Taktzyklen: 7
JNZ xxyy
jump on not zero
Sprung zur Adresse xxyy wenn das Z-Bit nicht gesetzt ist (bedingter Sprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
JNZ xxyy | C2 yy xx |
Taktzyklen: 7
Beispiel
CLEAR: MVI C,18 ; Schleifenzaehler = 24
LXI H,2FE0 ; Anfangsadresse nach HL
LOOP: MVI m,00 ; 00 in die Speicverzelle
INX H ; Zeiger erhoehen
DCR C ; Schleifenzaehler verringern
JNZ LOOP ; Nicht null: Schleife
...
JC xxyy
jump on carry
Sprung zur Adresse xxyy wenn das C-Bit gesetzt ist (bedingter Sprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
JC xxyy | DA yy xx |
Taktzyklen: 7
JNC
jump on not carry
Sprung zur Adresse xxyy wenn das C-Bit nicht gesetzt ist (bedingter Sprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
JNC xxyy | D2 yy xx |
Taktzyklen: 7
JPE xxyy
jump on parity even
Sprung zur Adresse xxyy wenn das P-Bit gesetzt ist (bedingter Sprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
JPE xxyy | EA yy xx |
Taktzyklen: 7
JPO
jump on parity odd
Sprung zur Adresse xxyy wenn das P-Bit nicht gesetzt ist (bedingter Sprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
JPO xxyy | E2 yy xx |
Taktzyklen: 7
JM xxyy
jump on minus
Sprung zur Adresse xxyy wenn das S-Bit gesetzt ist (bedingter Sprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
JM xxyy | FA yy xx |
Taktzyklen: 7
Beispiel
SIDIN: RIM ; SID-Pegel der CPU in den Akku
ANI 80 ; Bits 0..6 loeschen
JM SIDCTE ; MSB = HIgh weiter zu SIDCTE
...
Dazu kann man beispielsweise den SID-Pegel ins MSB des Akkumulators bringern (RIM-Befehl, alle übrigen Bits löschen (ANI-Befehl) und bei gesetzten MSB zu SIDCTE verzweigen.
Resultierend aus dem Pegel am seriellen CPU-Eingang SID soll ein Programm unterschiedliche Reaktionen ausführen. Bei High-Pegel an SID soll es zur symbolischen Adresse SIDCTE springen und bei Low mit dem nächsten Befehl fortfahren.
JP xxyy
jump on plus
Sprung zur Adresse xxyy wenn das S-Bit nicht gesetzt ist (bedingter Sprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
JP xxyy | F2 yy xx |
Taktzyklen: 7
CALL xxyy
call
Sprung zu dem bei Adresse xxyy beginnenden Unterprogrammes (unbedingter Unterprogramm-Aufruf)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
CALL xxyy | CD yy xx |
Taktzyklen: 18
Beispiel
Beim Unterprogramm-Aufruf wird das aufrufende Programm nur vorübergehend verlassen, d.h. nach dem Durchlauf des Unterprogrammes erfolgt automatisch der Rücksprung ins aufrufende Programm. Dazu wird (automatisch) vor dem Sprung ins Unterprogramm diejenige Adresse in den Stack überschrieben, bei der die Programmausführung anschließend fortgesetzt werden soll (Programmbefehl nach dem CALL-Befehl).
SERIELL: LXI H,2800 ; Anfangsadresse nach HL
LXI D,2AFF ; Endadresse nach DE
LOOP: MOV A,m ; Datenwort aus Speicher holen
OUT 00 ; Akku ueber EA-Kanal ausgeben
INX H ; Adresse erhoehen
CALL COMPARE ; Unterprogramm: Endadresse erreicht
JNZ LOOP ; nein: weiter in Schleife
...
CZ xxyy
call on zero
Sprung zu dem bei der Adresse xxyy beginnenden Unterprogramm, wenn das Z-Bit gesetzt ist (bedingter Unterprogramm-Aufruf)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
CZ xxyy | CC yy xx |
Taktzyklen: 9 / 18
Beispiel
Das Programm DIV führt eine Division durch, bei der der Divisor im Registerpaar HL steht. Dieses Unterprogramm prüft dabei ab, ob eine Division durch 0 vorliegt und verzweigt in diesem Fall in ein dafür vorgesehenes Unterprogramm.
DIV: MOV A,L ; untere Divisor-Haelfte in den Akku
ORA H ; mit oberer Haelfte ODER-Verknuepfen
; dadurch beeinflussung der Status-Flags
CZ ZERO ; nur die Zero (0) das Unterprogramm
; ZERO aufrufen (Div. durch 0)
...
CNZ xxyy
call on not zero
Sprung zu dem bei der Adresse xxyy beginnenden Unterprogramm, wenn das Z-Bit nicht gesetzt ist (bedingter Unterprogramm-Aufruf)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
CNZ xxyy | C4 yy xx |
Taktzyklen: 9 / 18
Beispiel
CLEAR: MVI C,18 ; Schleifenzaehler = 24
LXI H,2FE0 ; Anfangsadresse nach HL
LOOP: MVI m,00 ; 00 in die Speicverzelle
INX H ; Zeiger erhoehen
DCR C ; Schleifenzaehler verringern
JNZ LOOP ; Nicht null: Schleife
...
CC xxyy
call on carry
Sprung zu dem bei der Adresse xxyy beginnenden Unterprogramm, wenn das C-Bit gesetzt ist (bedingter Unterprogramm-Aufruf)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
CC xxyy | DC yy xx |
Taktzyklen: 9 / 18
Beispiel
Die einzelnen Bits im Akkumulator steuern seriell nacheinander eine Peripherieschaltung an Ausgabekanal 80.
Bei High-Pegel benötigt die periphere Schaltung zum Einschwingen doppelt so lange wie bei Low-Pegel. Je nach Pegel wird das Unterprogramm zur Zeitverzögerung ein- oder zweimal aufgerufen.
OUTSLW: LXI H,02A00 ; Anfangsadresse nach HL
MOV A,m ; Speicherinhalt in Akku
OUT 80 ; Akku ueber EA-Kanal 80 ausgeben
RLC ; MSB ins Carry-Bit schieben
CC DELAY ; nur bei gesetzten Carry-Bit
; Unterprogramm aufrufen
CALL DELAY ; Zeitverzoegerung (normal)
DELAY: MVI A,8E ; 1 msec Laufzeit (bei 4MHz)
DELAY1: DCR A ; Akku verringern
JNZ DELAY1 ; nicht null: Schleife durchlaufen
RET ; ansonsten ruecksprung
CNC
call on not carry
Sprung zu dem bei der Adresse xxyy beginnenden Unterprogramm, wenn das C-Bit nicht gesetzt ist (bedingter Unterprogramm-Aufruf)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
CNC xxyy | D4 yy xx |
Taktzyklen: 9 /18
CPE xxyy
call on parity even
Sprung zu dem bei der Adresse xxyy beginnenden Unterprogramm, wenn das P-Bit gesetzt ist (bedingter Unterprogramm-Aufruf)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
CPE xxyy | EC yy xx |
Taktzyklen: 9 /18
CPO
call on parity odd
Sprung zu dem bei der Adresse xxyy beginnenden Unterprogramm, wenn das P-Bit nicht gesetzt ist (bedingter Unterprogramm-Aufruf)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
CPO xxyy | E4 yy xx |
Taktzyklen: 9 /18
CM xxyy
call on minus
Sprung zu dem bei der Adresse xxyy beginnenden Unterprogramm, wenn das S-Bit gesetzt ist (bedingter Unterprogramm-Aufruf)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
CM xxyy | FC yy xx |
Taktzyklen: 9 / 18
Beispiel
SIDIN: RIM ; SID-Pegel der CPU in den Akku
ANI 80 ; Bits 0..6 loeschen
JM SIDCTE ; MSB = HIgh weiter zu SIDCTE
...
Dazu kann man beispielsweise den SID-Pegel ins MSB des Akkumulators bringern (RIM-Befehl, alle übrigen Bits löschen (ANI-Befehl) und bei gesetzten MSB zu SIDCTE verzweigen.
Resultierend aus dem Pegel am seriellen CPU-Eingang SID soll ein Programm unterschiedliche Reaktionen ausführen. Bei High-Pegel an SID soll es zur symbolischen Adresse SIDCTE springen und bei Low mit dem nächsten Befehl fortfahren.
CP xxyy
call on plus
Sprung zu dem bei der Adresse xxyy beginnenden Unterprogramm, wenn das S-Bit nicht gesetzt ist (bedingter Unterprogramm-Aufruf)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
CP xxyy | F4 yy xx |
Taktzyklen: 9 /18
Rücksprung
RET
return
Rücksprung aus dem Unterprogramm (unbedingter Rücksprung). Der Return-Befehl schließt in der Regel jedes Unterprogramm ab. Bei sein Ausführung wird (automatisch) diejenige Adresse aus dem Stack geholt, die beim Sprung ins Unterprogramm dorthin abgelegt wurde. Diese Adresse wird in den Programmzähler geladen, woraufhin die Programmausführung dort fortgesetzt wird.
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
RET | C9 |
Taktzyklen: 10
Beispiel
Der am Schluss eines Unterprogrammes (dazu gehört auch jede Interrupt-Service-Routine stehende Befehl RETURN bewirkt den automatischen Rücksprung ins übergeordnete, aufrufende Programm. Das geschieht dadurch, dass der Inhalt der zu diesem Zeitpunkt vom Stack-Pointer adressierten Speicherzellen direkt in den Programmzähler transportiert wird, was zur Programmfortsetzung bei dieser Adresse führt.
Den oben geschilderten Sachverhalt kann man auch für einen völlig anderen Zweck nutzen. Im Beispiel verzweigt das Programm zu einer von vier möglichen Zieladressen, ohne (wie bei einem Unterprogramm) zu einem zentralen Punkt zurückzukehren, an dem ich alle möglichen Sprungziele wieder treffen.
Wenn man vor Errechnen des Sprungziels die Adresse des Fortsetzungspunktes (hier CTE332) in den Stack überträgt (PUSH-Befehl). kann man die vier Programmzweige mit RETURN abschließen. Bei Ausführung dieses RET-Befehls erfolgt dann dort die Programmfortsetzung.
BRANCH: LXI H,CTE332 ; Fortsetzungsadresse in HL laden
PUSH H ; CTE332 Adresse in den Stack laden
LXI H,JMPTAB ;
.. ; Adressberechnung
..
PCHL
CTE332: .. ; Programmfortsetzung nach
; Rueckkehr aus den vier Teilen
Die vier Programmteile, zu denen das Hauptprogramm mit dem PCHL-Befehl verzweigen kann, müssen in diesem Fall mit dem Befehl RET abgeschlossen werden.
RZ
call on zero
Rücksprung aus dem Unterprogramm, wenn das Z-Bit gesetzt ist (bedingter Rücksprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
RZ | C8 |
Taktzyklen: 6 / 12
Beispiel
Das Programm DIV führt eine Division durch, bei der der Divisor im Registerpaar HL steht. Dieses Unterprogramm prüft dabei ab, ob eine Division durch 0 vorliegt und verzweigt in diesem Fall in ein dafür vorgesehenes Unterprogramm.
DIV: MOV A,L ; untere Divisor-Haelfte in den Akku
ORA H ; mit oberer Haelfte ODER-Verknuepfen
; dadurch beeinflussung der Status-Flags
CZ ZERO ; nur die Zero (0) das Unterprogramm
; ZERO aufrufen (Div. durch 0)
...
RNZ
call on not zero
Rücksprung aus dem Unterprogramm, wenn das Z-Bit nicht gesetzt ist (bedingter Rücksprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
RNZ | C0 |
Taktzyklen: 6 /12
Beispiel
Nach dem Unterprogramm COMPARE soll das Zero-Bit auf High gesetzt sein, wenn die Inhalte der Registerpaare HL und DE gleich sind.
Diese Bedingung ist nur dann erfüllt, wenn beide Teilvergleiche (Inhalt der Register E und L sowie Inhalt der Register D und H gleich) positiv ausfallen.
Führt bereits der erste Vergleich z einem negativen Reslutat (d.h. ungleiche Register-Inhalte), wird das Programm vorzeitig verlassen (RNZ). Am Low-Zustand des Zero-Bits erkennt das Hauptprogramm anschließend dass keine Gleichheit vorliegt.
Nach dem zweiten Teilvergleich (CMP) kann unmittelbar der Rücksprung erfolgen. Diese Stelle wird nur dann erreicht, wenn der erste Teilvergleich positiv ausgefallen ist. Ist dies auch beim zweiten Teilvergleich der Fall, erfolgt der Rücksprung mit gesetztem Zero-Bit, andernfalls ist das Z-Bit Low. Das aufrufende Hauptprogramm bekommt auf diese Weise die geforderte Information über Gleichheit bzw. Ungleicheit der Registerinhalte.
COMPARE: MOV A,E ; Register E in den Akku
CMP L ; Vergleich mit L
RNZ ; ungleich: Ruecksprung Z-Bit = 0
MOV A,D ; Register D in den Akku
CMP H ; Vergleich mit H
RET ; nur bei Gleichheit in Z-Bit = 1
RC
call on carry
Rücksprung aus dem Unterprogramm, wenn das C-Bit gesetzt ist (bedingter Rücksprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
RC | D8 |
Taktzyklen: 6 /12
Beispiel
Die einzelnen Bits im Akkumulator steuern seriell nacheinander eine Peripherieschaltung an Ausgabekanal 80.
Bei High-Pegel benötigt die periphere Schaltung zum Einschwingen doppelt so lange wie bei Low-Pegel. Je nach Pegel wird das Unterprogramm zur Zeitverzögerung ein- oder zweimal aufgerufen.
OUTSLW: LXI H,02A00 ; Anfangsadresse nach HL
MOV A,m ; Speicherinhalt in Akku
OUT 80 ; Akku ueber EA-Kanal 80 ausgeben
RLC ; MSB ins Carry-Bit schieben
CC DELAY ; nur bei gesetzten Carry-Bit
; Unterprogramm aufrufen
CALL DELAY ; Zeitverzoegerung (normal)
DELAY: MVI A,8E ; 1 msec Laufzeit (bei 4MHz)
DELAY1: DCR A ; Akku verringern
JNZ DELAY1 ; nicht null: Schleife durchlaufen
RET ; ansonsten ruecksprung
RNC
call on not carry
Rücksprung aus dem Unterprogramm, wenn das C-Bit nicht gesetzt ist (bedingter Rücksprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
RNC | D0 |
Taktzyklen: 6 /12
RPE
call on parity even
Rücksprung aus dem Unterprogramm, wenn das P-Bit gesetzt ist (bedingter Rücksprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
RPE | E8 |
Taktzyklen: 6 /12
RPO
call on parity odd
Rücksprung aus dem Unterprogramm, wenn das P-Bit nicht gesetzt ist (bedingter Rücksprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
RPO | E0 |
Taktzyklen: 6 /12
RM
call on minus
Rücksprung aus dem Unterprogramm, wenn das S-Bit gesetzt ist (bedingter Rücksprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | |||||||
RM | F8 |
Taktzyklen: 6 /12
Beispiel
Das Unterprogramm BINBC setzt eine im Akkumulator stehende Binärzhal (die kleiner ist als Dezimal 1000) in zwei BCD-Digits um.
Dazu subtrahiert es vom Akkumulator-Inhalt so oft 0A (dezimal 10), bis das Ergebnis dadurch negativ wird. In diesem Fall erfolgt der Rücksprung ins Hauptprogramm (RM) mit der Zehnerstelle in Register B und der Einer-Stelle in Register C.
BINBC: MVI B,00 ; Zehnerstelle loeschen
LOOP: MOV C,A ; Akku nach C uebertragen
SUI 0A ; vom Akku 10 abziehen
ENDSUB: RM ; bei negativen Ergebnis (S=1) ruecksprung
INR B ; B erhoehen
JMP LOOP ; und weiter subtrahieren
...
RP
call on plus
Rücksprung aus dem Unterprogramm, wenn das S-Bit nicht gesetzt ist (bedingter Rücksprung)
Details
Flag
S (7) | Z (6) | X5 (5) | AC (4) | 0 (3) | P (2) | V (1) | CY (0) |
---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Varianten und Hexcode
r = | A | B | C | D | E | H | L |
RP | F0 |
Taktzyklen: 6 /12