Magic Disk 64

home to index to html: MD9403-KURSE-ASSEMBLER_KURS_2_(TEIL_5).html
          Assembler-Kurs Teil 5         
Das Thema, das  wir  diesmal  behandeln,
wird Sie sicherlich nicht in  Verzückung
geraten  lassen,  aber  es  ist   leider
notwendig: Das Rechnen in ASSEMBLER.    
Wie Sie sicher  schon  ahnen,  wird  die
Sache etwas komplizierter als in BASIC. 
Mit einer Zeile, wie C = A + B ist es in
ASSEMBLER leider nicht getan. Um  diesen
Kursteil nicht unnötig zu  komplizieren,
werden  wir  uns  heute  nur   mit   der
Addition  und  Subtraktion   von   ganz-
zahligen Werten (genannt: Integers)  be-
schäftigen. Dabei kommt  man  allerdings
um die Kenntnis der Flaggen des  Status-
registers (bekannt aus Kursteil 3) nicht
herum.                                  
Bevor wir munter  addieren  und  subtra-
hieren,  sollten  Sie  vielleicht   doch
erstmal  einen  Blick  auf  die   dualen
Zahlendarstellungen des C64 werfen.  Das
Verlassen des erlaubten  Zahlenbereiches
kann einige unschöne Nebeneffekte haben.
Unser  Computer  kennt  die  ganzzahlige
Werte von -  128  bis  +127  bei  8-Bit-
Zahlen und von  -32768  bis  +32767  bei
16-Bit-Zahlen. Positive Dualzahlen  sind
für uns ja kein Problem, aber wie stellt
man den negative Zahlen dar?            
Das soll an dem Beispiel  der  Zahl  -18
erklärt werden:                         
Die  Zahl  +18  wird   bekanntlich   als
00010010 kodiert. Um die  negative  Zahl
zu erhalten, muß man das Komplement  der
Zahl bilden (d.h. die Zahl  wird  inver-
tiert: aus jeder 0 wird eine 1 und umge-
kehrt) und +1 dazuaddieren. Das  Komple-
ment von +18 ist 11101101. Nun muß  noch
+1 dazuaddiert werden und man  kommt  zu
11101110, was der Zahl -18 entspricht.  
Das äußerste rechte Bit  (Bit  7)  nennt
man  das  Vorzeichenbit,  wobei  0  eine
positive und 1 eine negative Zahl  kenn-
zeichnet.  Diese  Darstellungsform,  bei
der  die  negativen  Zahlen  umgewandelt
werden, die positiven aber  wie  gewohnt
aussehen, nennt man ZWEIERKOMPLEMENT.   
ADC (ADd with Carry)                    
--------------------                    
Wenn zwei Zahlen  addiert  werden,  dann
muß die eine im Akkumulator stehen,  die
zweite kann unmittelbar oder als  Inhalt
einer Speicherstelle gegeben  sein.  Das
Ergebnis   der   Rechenoperation   steht
wieder im Akkumulator.  Dies  gilt  auch
für die Subtraktion. Das Ergebnis sollte
aus  dem  Akkumulator  schnell  in  eine
Speicherstelle geschrieben werden, da es
sonst   beim   weiteren   Programmablauf
verlorengehen könnte.                   
Unser  neuer  Befehl  ADC  addiert  aber
nicht nur zwei Zahlen, sondern auch noch
den Wert des  Carry-Bits  (was  uns  bei
8-Bit-Additionen gar  nicht  recht  sein
kann). Daher sollte vor dem  ADC  zuerst
der  Befehl  CLC  stehen,  mit  dem  das
Carry-Bit gelöscht  wird.  Nun  erhalten
wir  auf   jeden   Fall   des   richtige
Ergebnis.                               
Dualzahlen werden fast wie Dezimalzahlen
addiert:                                
0 + 0 = 0                               
0 + 1 = 1                               
1 + 0 = 1                               
1 + 1 = 0 und zusätzlich enthält hier   
          das Carry-Bit den Übertrag 1, 
          der bei der nächsten Stelle   
          nicht berücksichtigt wird.    
Ein kleines Beispiel:                   
 CLC                                    
 LDA #$5D        01011101   (Dez. 93)   
 ADC #$0E      + 00001110   (Dez. 14)   
 STA $1500     ----------               
                 01101011   (Dez. 107)  
Das Ergebnis #$6B (=107) steht jetzt  im
Akkumulator und  in  der  Speicherstelle
$1500.                                  
Ein weiteres Rechenbeispiel:            
  115         01110011                  
 + 14       + 00001110                  
-----        ---------                  
  129         10000001                  
Hier ist offensichtlich etwas  schiefge-
gangen. Das Ergebnis hätte  +129  lauten
sollen;herausgekommen ist aber 10000001,
was der Zahl  -127  im  Zweierkomplement
entspricht.Das  diese   Rechnung   nicht
korrekt  ist,  liegt  am  Verlassen  des
erlaubten Zahlenbereiches. Der  Computer
gibt uns hier zwar  keine  Fehlermeldung
aus,  er  warnt  uns  jedoch   vor   dem
Ergebnis, indem er die  V-Flagge  setzt.
Diese Overfolw-Flagge  wird  immer  dann
gesetzt,   wenn   ein   unbeabsichtigter
Übertrag in das Vorzeichenbit stattfand.
Die gesetzte N-Flagge (Vorzeichenflagge)
sagt uns, daß das Ergebnis eine negative
Zahl ist.                               
Die V-Flagge wird eigentlich automatisch
gesetzt oder gelöscht. Dennoch  gibt  es
den Befehl CLV, mitdem man die  V-Flagge
auch selbst  wieder  löschen  kann,  und
somit das Warnsignal unterdrückt.       
Bisher  wurde  nur  die   Addition   von
1-Byte- (8-Bit) Zahlen geschildert.     
Die Addition von 2-Byte- (16-Bit) Zahlen
wird noch etwas  komplizierter,  da  der
Akkumulator nur 8 Bits aufnehmen kann.  
Des Rätsels Lösung: Man addiert zunächst
nur die niederwertigen Bytes der 16-Bit-
Zahlen. Sollte dort  ein  Übertrag  über
das 8. Bit hinaus vorliegen, so  gelangt
dieser ins  Carry-Bit.  Nun  werden  die
beiden höherwertigen Bytes addiert,  und
der Inhalt des Carry-Bits hinzugezählt. 
Das Abspeichern  der  beiden  Bytes  muß
ebenfalls  getrennt  erfolgen.   Erwähnt
sei noch, daß bei 16-Bit-Zahlen das  Bit
15 das Vorzeichen enthält.              
Beispiel für eine 16-Bit-Addition:      
 $1000/$1001 enthalten die erste Zahl   
 $1100/$1101 enthalten die zweite Zahl  
 $1200/$1201 sollen das Ergebnis        
             enthalten                  
Das Programm dafür sieht folgendermaßen 
aus:                                    
 CLC                                    
 LDA $1000                              
 ADC $1100  ; Addition des niederwerigen
 STA $1200    Bytes                     
 LDA $1001                              
 ADC $1101  ; Addition des höherwertigen
 STA $1201    Bytes ohne CLC            
SBC (SuBtract with Carry)               
-------------------------               
Dieser Befehl,  wer  hätte  es  gedacht,
subtrahiert  zwei  Zahlen   voneinander.
Das Dumme ist nur: Unser Prozessor  kann
überhaupt nicht  subtrahieren,  er  kann
nur addieren!  Um  dennoch  Zahlen  von-
einander abziehen zu können,  wendet  er
einen Trick an. Eine der  beiden  Zahlen
wird einfach  zu  einer  negativen  Zahl
gemacht und  dann  werden  beide  Zahlen
addiert. Diese Uwandlung nimmt  uns  der
Befehl SBC jedoch schon ab. Es  wird  zu
dem  ersten  Operanden  nicht  nur   das
Zweierkomplement   der   zweiten   Zahl,
sondern auch  noch  das  Komplement  des
Carry-Bits addiert. D.h. wenn das Carry-
Bit das  Ergebnis  bei  der  Subtraktion
nicht verfälschen soll, muß es zuvor ge-
setzt sein. Dazu dient  der  Befehl  SEC
(SEt Carry), der vor  jedem  SBC  stehen
sollte.                                 
Ein Beispiel:                           
 SEC                                    
 LDA #$7D                               
 SBC #$0A                               
 STA $1500                              
Per Hand sieht die Rechnung so aus:     
 Dezimal              Binär             
   125               01111101           
 -  10            +  11110110           
 -------          -----------           
   115           (1) 01110011           
Das Ergebnis $73  (115)  steht  im  Akku
und in der Speicherstelle $1500.        
Wie Sie sehen, erhalten wir das richtige
Ergebnis. Das Vorzeichen  der  Zahl  ist
positiv, da die N-Flagge  nicht  gesetzt
ist.  Das  gesetzte  "9.Bit"  steht   im
Carry und wird bei der 8-Bit-Subtraktion
nicht benötigt. Auch bei der Subtraktion
signalisiert  die  V-Flagge  ein  ubeab-
sichtigtes Verlassen des Zahlenbereichs.
Der SBC-Befehl hat also  große  Ähnlich-
keit mit dem ADC, und so  ist  es  nicht
verwunderlich, daß eine  16-Bit-Subtrak-
tion  einer  16-Bit-Addition  auch  sehr
verwandt ist.                           
Beispiel für eine 16-Bit-Subtraktion:   
 $1000/$1001 enthalten die erste Zahl   
 $1100/$1101 enthalten die zweite Zahl  
 $1200/$1201 sollen das Ergebnis        
             enthalten                  
Das Programm sieht folgendermaßen aus:  
 SEC                                    
 LDA $1000                              
 SBC $1100  ; Subtraktion der           
 STA $1200    niederwertigen Bytes      
 LDA $1001                              
 SBC $1101  ; Subtraktion der höher-    
 STA $1201    wertigen Bytes ohne SEC   
Abschließend möchte ich noch zeigen, daß
es dem Programmierer  selbst  überlassen
bleibt, ob er die  Zahlen  wirklich  als
vorzeichenbehaftet   ansieht,   wie   es
eigentlich vorgesehen ist,  oder  ob  er
die Zahlen als vorzeichenlos betrachtet.
Dazu ein Beispiel:                      
 Dezimal                Binär           
   -6                 11111010          
  + 2               + 00000010          
 ----               ----------          
   -4                 11111100          
Das Ergebnis ist bei vorzeichenbehaftet-
en Zahlen richtig, da -6  ($FA)  und  -4
($FC) im Zweierkomplement gegeben sind. 
Nun vergessen Sie mal das  Zweierkomple-
ment und betrachten Sie die  Zahlen  als
vorzeichenlos. Dann hätten wir $FA + $02
= $FC (also  dezimal  250  +  2  =  252)
gerechnet.  Auch  dieses  Ergebnis   ist
korrekt. Dieses Beispiel zeigt,  daß  es
am  Programmierer  liegt,  welches   der
beiden Ergebnisse er beabsichtigt.      
BCD-Darstellung (Binary Coded Decimals) 
--------------------------------------- 
Da die Befehle ADC  und  SBC  sowohl  im
Binär-,   als   auch   im   Dezimalmodus
arbeiten, muß es wohl Befehle geben, die
zwischen  den  beiden  Modi  umschalten.
Wenn  es  nicht  vom  Programm  geändert
wurde, ist  automatisch  der  Binärmodus
angeschaltet.                           
CLD: schaltet den Binärmodus an         
SED: schlaten auf Dezimalmodus um       
Bei  deisen  "binär-kodierten"  Dezimal-
zahlen gibt es nur  die  Ziffern  0  bis
9. Es wird also jede  Dezimalstelle  für
sich  getrennt  kodiert.  Um  diese   10
Ziffern kodieren zu können, benötigt man
4 Bits, mit denen bis zu 16 Kombination-
en  möglich  wären.  Sechs  der   Kombi-
nationsmöglichkeiten bleiben daher unge-
nutzt. Die Dezimalzahl 0 wird als  0000,
die 9 als  1001  kodiert.  Die  BCD-Dar-
stellung der Zahl 128 lautet z.B.:      
 0001   0010   1000       binär         
  1      2      8         dezimal       
Da jede Ziffer 4 Bits in Anspruch nimmt,
fasst man je zwei BCD-Ziffern  in  einem
Byte  zusammen.  Die  Zahl   128   liegt
folgendermaßen imnm  SPeicher:  00000001
00101000.  Die  BCD-Zahlen  seien   hier
jedoch nur am Rande erwähnt, da Sie  nur
sehr selten  verwendet  werden.  Rechnen
werden wir nicht mit diesen Zahlen.     
Das richtige Verständnis für die diesmal
erlernten Befehle werden Sie erst  durch
eigenes  Ausprobieren   erhalten.   Also
nichts wie  hingesetzt  und  losprogram-
miert. Auch diesmal gibt  es  selbstver-
ständlich wieder ein Begleitprogramm  zu
dem Kurs auf  Diskette.  Es  nennt  sich
"ASSEMBLER-KURS  5"  und  enthält  neben
einer Joystickabfrage in ASSEMBLER  auch
noch einige  nützliche  Anwendungen  der
neuen Befehle.                          
Zusammenfassung der Befehle:            
---------------------------             
ADC (ADd with Carry)                    
--------------------                    
Zwei  Zahlen  werden  zusammen  mit  dem
Inhalt  des  Carry-Bits   addiert.   Das
Ergebnis steht  wieder  im  Akkumulator.
Dieser  Befehl  gilt  sowohl   für   die
binäre, als auch für die dezimale  (BDC)
Addition.  Der   ADC-Befehl   kann   die
Flaggen N, V, Z und C beeinflussen.     
SBC (SuBtract with Carry)               
-------------------------               
Zwei Zahlen  werden  subtrahiert,  indem
das Zweierkomplement der zweiten Zahl zu
der ersten dazuaddiert wird. Das Ergebis
der Operation steht im Akkumulator. Auch
SBC kann sowohl im Binär-, als  auch  im
Dezimalmodus arbeiten.                  
CLC (CLear Carry)                       
-----------------                       
Löscht  die  Übertragungsflagge.  Dieser
Befehl  sollte  immer  vor   einem   ADC
benutzt werden.                         
SEC (SEt Carry)                         
---------------                         
Setzt die  Übertragsflagge.  SEC  sollte
vor jedem SBC stehen.                   
CLD (CLear Decimal mode)                
------------------------                
Löscht die  Dezimalflagge  und  schaltet
somit den Binärmodus ein.               
SED (SEt Decimal mode)                  
----------------------                  
Setzt die Dezimalflagge auf  1.  Dadurch
werden   alle    Rechenoperationen    im
Dezimalmodus ausgeführt.                
CLV (CLear oVerflow flag)               
-------------------------               
Löscht die Überlaufflagge.              
                     (Ralf Trabhardt/wk)



Valid HTML 4.0 Transitional Valid CSS!