CALM-Assembler CALM
Was ist CALM ?
CALM steht für Common Assembly Language for Microprocessors, oder
auf Deutsch: allgemeine Assemblersprache für Mikroprozessoren.
CALM ist keine neue Programmiersprache, sondern eine andere,
einheitliche und prozessorunabhängige Schreibweise von
Assemblerbefehlen. Heutzutage ist es so, dass jeder Hersteller für
seinen Mikroprozessor eine eigene Assemblersprache definiert. Auch die
verwendete Terminologie hängt stark vom Mikroprozessor ab. Aber eine
einheitliche Schreibweise von Befehlen, die funktionell gesehen 100%
identisch sind, vermisst man heute noch immer.
CALM nützt nun die Tatsache aus, dass eben viele Befehle - auch auf
den unterschiedlichsten Mikroprozessoren - genau dieselbe Operation
ausführen. Liegt es in solchen Fällen nicht auf der Hand, die gleiche
Schreibweise - unabhängig vom Prozessor - für diese Befehle
festzulegen?
Was definiert CALM ?
CALM definiert eine einheitliche, prozessorunabhängige Syntax für
Befehle und Pseudobefehle. Aufgrund langjähriger Erfahrung und
Erprobung an über 20 Mikroprozessoren hat es sich gezeigt, dass fast
alle Befehle eines Mikroprozessors durch die von CALM definierten
Befehle und deren Schreibweise ausgedrückt werden können.
CALM definiert aber auch eine einheitliche Assemblerterminologie.
Und es wird ein Konzept angeboten, das aufzeigt, wie ein Befehl
zusammengesetzt ist. Der Benutzer versteht, warum ein Befehl in CALM
so und nicht anders geschrieben wird. Ausserdem wird eine einheitliche
Schreibweise für Operationscodes, Adressierungsarten, Adressen- und
Datenangaben, usw. definiert.
CALM propagiert eine einzige Schreibweise der Befehle für alle
(Mikro)prozessoren. Dieses Ziel erfüllt CALM in rund 95% der Befehle
eines Mikroprozessors. Der Rest entfällt auf prozessorspezifische
Eigenheiten, die von einer allgemeinen Assemblersprache nicht
abgedeckt werden können. Aber es ist in vielen Fällen vorteilhaft,
dass sich diese Besonderheiten auch in der Schreibweise unterscheiden.
Welche Vorteile ergeben sich für den Benutzer ?
Eine einheitliche Schreibweise der Befehle und insbesondere der
Adressierungsarten vermittelt ein objektives Bild von der
Leistungsfähigkeit eines Mikroprozessors. Daher sind auch objektive
Vergleiche von Mikroprozessoren möglich.
Erstmalig können sich Programmierer unterschiedlicher
Mikroprozessoren verständigen. Bisher scheiterten sie an der untersten
Stufe, den verschiedenen Schreibweisen.
Prozessorwechsel werden wesentlich vereinfacht, da sich die
Schreibweise der Befehle nicht ändert. Nur die allgemeine Struktur und
einige Besonderheiten des neuen Prozessors müssen erlernt werden.
CALM eignet sich nicht nur für Mikroprozessoren, sondern auch für
Miniprozessoren, Grossrechner und mikroprogrammierte Rechner. CALM ist
in allen Stufen erweiterbar und daher nicht nur auf 8, 16 und 32 Bit
Prozessoren beschränkt.
Und welche Nachteile ?
CALM definiert nur den Softwareteil eines Prozessors. Benötigt man
aber Hardwareinformationen (Ausführungszeit, Befehlscode, Pinbelegung,
elektrische Belastbarkeit, Angaben zu eingebauten Funktionen wie
Timer, DMA-Einheiten, usw.), dann ist die Herstellerdokumentation
unumgänglich. Der Benutzer muss daher zeitweise beide Schreibweisen
der Befehle kennen: die von CALM und die des Herstellers.
Beispiele
Folgende Seite zeigt anhand der Mikroprozessoren 8080, iAPX86 und
68000 die Schreibweise der Befehle in CALM und die des Herstellers.
CALM-Assembler CALM
; 8080: Multiplikation: RESULTAT.16 = MUL1.8 * MUL2.8
; modifiziert: A, B, D, E, H, L, F
MULT: MULT:
MOVE MUL1,A LDA MUL1
MOVE A,E MOV E,A
MOVE #0,D MVI D,0
MOVE MUL2,A LDA MUL2
MOVE #0,HL LXI H,0
MOVE #8,B MVI B,8
SCHLAUFE$: SCHLAUFE:
ADD HL,HL DAD H
RLC A RAL
JUMP,CC WEITER$ JNC WEITER
ADD DE,HL DAD D
WEITER$: WEITER:
DEC B DCR B
JUMP,NE SCHLAUFE$ JNZ SCHLAUFE
MOVE HL,RESULTAT SHLD RESULTAT
RET RET
; iAPX86: übersetzt eine EBCDIC Zeichenfolge in ASCII-Codes (
; beendet). Annahme: ES = DS, [DS] ist gleichbedeutend mit {DS}*16
; modifiziert AL, BX, CX, DI, SI, F
EBCDIC_ASCII: EBCDIC_ASCII: PROC NEAR
MOVE.16 #CONV_TAB,BX MOV BX,OFFSET CONV_TAB
MOVE.16 #EBCDIC_ZEICHEN,SI MOV SI,OFFSET EBCDIC_ZEICHEN
MOVE.16 #ASCII_ZEICHEN,DI MOV DI,OFFSET ASCII_ZEICHEN
MOVE.16 [DS]+ASCII_LAENGE,CX MOV CX,SIZE ASCII_LAENGE
AUTOINC CLD
SCHLAUFE$: SCHLAUFE:
MOVE.8 [DS]+{SI!},AL LODS EBCDIC_ZEICHEN
MOVE.8 [DS]+{BX}+{AL},AL XLAT CONV_TAB
MOVE.8 AL,[ES]+{DI!} STOS ASCII_ZEICHEN
COMP.8 #16'D,AL CMP AL,0DH
LOOP,NE SCHLAUFE LOOPNE SCHLAUFE
RET.16 RET ; EQ: CR gefunden
; 68000: Division: D4 = D5D4 / D3, Rest in D5, CS falls Fehler
DIV64: DIV64
TEST.32 D3 TST.L D3
JUMP,ZS R8^DIV_NULL$ BEQ.S NULL
PUSH.32 D0 MOVE.L D0,-(A7)
MOVE.32 #32-1,D0 MOVEQ #32-1,D0
DIV_SCHLAUFE$: SCHLAUFE
SETX ORI #$10,CCR
RLX.32 D4 ROLX.L D4
RLX.32 D5 ROLX.L D5
JUMP,CS R8^DIV_UEBER$ BCS.S UEBER
SUB.32 D3,D5 SUB.L D3,D5
JUMP,HS R8^DIV_OK$ BCC.S OK
ADD.32 D3,D5 ADD.L D3,D5
TCLR.32 D4:#0 BCLR #0,D4
DIV_OK$: OK
DJ.16,NMO D0,DIV_SCHLAUFE$ DBRA D0,SCHLAUFE
POP.32 D0 MOVE.L (A7)+,D0
CLRC ANDI #$FE,CCR
RET RTS
DIV_UEBER$: UEBER
POP.32 D0 MOVE.L (A7)+,D0
DIV_NULL$: NULL
SETC ORI #$1,CCR
RET RTS
CALM-ASSEMBLER - Produktbeschreibung (PC/MS-DOS, Atari ST, Smaky)
Der CALM-Assembler besteht aus mehreren Programmen und Dateien:
Die Assemblerprogramme
ASCALM: Der eigentliche Assembler. Er funktioniert wie alle anderen
Assembler auch. Einziger Unterschied: Die Programme müssen in der
herstellerunabhängigen Assemblersprache CALM geschrieben werden.
Vorteil: Diese Assemblersprache unterscheidet sich nicht von Prozessor
zu Prozessor. Mit den entsprechenden Modulen wird der Maschinencode
ohne Binder/ Linker für fast alle Mikroprozessoren erzeugt (siehe
Liste). Assemblerleistungen: Marken (32 Zeichen signifikant),
lokale Marken, Ausdrücke mit 32 Bit Genauigkeit, bedingte
Assemblierung (.IF/.ELSE/.ENDIF), bedingte Auflistung
(.LIST/.ENDLIST), Einfügen beliebig grosser Dateien (.INS), aktuelle
Systemzeit und -datum über Konstanten aufrufbar, Einfügen der
Fehlermeldungen (Sprache wählbar) direkt in die Quelldatei,
Querverweislistengenerator, Makros, u.v.m. Makroleistungen: bis zu
acht Parameter sowie eine Datenangabe können bei einem Makroaufruf
übergeben werden. Die Länge eines Parameters ist nur durch die
Zeilenlänge beschränkt. Parameter können vordefiniert werden. Beim
Makroaufruf kann man zwischen vordefinierten und übergebenen Para-
metern unterscheiden. Makros können andere Makros aufrufen (Schachtel-
tiefe: 10). Ausserdem können mit speziellen Funktionen die übergebenen
Parameter analysiert werden (Vergleich, Kopieren, Zeichen testen,
usw.). Somit können leistungsfähige Makros erstellt werden, die bsw.
die Befehle von der Herstellerschreibweise in die CALM-Schreibweise
übersetzen. Maschinencode-Ausgangsformat: MUFOM (siehe unter MUFBIN).
MUFBIN: Wandelt die vom Assembler erzeugten Objektdateien
(MUFOM-Format) in die Formate binär (.BIN/.COM), hex, Intel hex
(.HEX), Motorola S Format (.FRS), PC/MS-DOS (.EXE) und Atari ST
(.TOS/.TTP/.PRG) um.
Debugger für 8086 (DBGCALM, PC/MS-DOS) oder 68000 (DEBUG68, Atari
ST und Smaky). Mit Disassembler (CALM-Schreibweise).
Die Hilfsprogramme
CALMMENU präsentiert ein einfaches Menü.
FORMCALM formatiert (verschönert) eine CALM-Assemblerquelldatei.
LSTTOASM wandelt Auflistungen in Quelldateien um.
PFED ein Programmeditor (mit Makros!).
PROCSET ändert die Vorgabe in *.PRO-Modulen.
SPACETAB ersetzt Leerzeichen durch Tabulatoren.
TABSPACE ersetzt Tabulatoren durch Leerzeichen.
TESTLIST überprüft eine Auflistungsdatei.
Dateien zu einem Prozessor
*.DOK CALM-Befehlsliste für den Prozessor * , z.B. Z80.DOK.
*.PRO das Modul für den Prozessor * , z.B. Z80.PRO.
B*.TXT Beschreibung zum Prozessormodul, z.B. BZ80.TXT.
C*.TXT Befehlsvergleich (Herstellerschreibweise ->
CALM-Schreibweise).
D*.EXE CALM-Disassembler für den Prozessor *, z.B. DZ80.EXE.
I*.TXT Liste von Maschinencodes mit CALM-Schreibweise
(Disassemblierung).
ST*.ASM Befehlsliste in der CALM-Schreibweise (alphabetisch
geordnet).
S_*.ASM Programmbeispiele (oder E*.ASM oder *.ASM).
T*.ASM Testdatei (Liste der Befehle).
xxx_CALM Übersetzer (Herstellerschreibweise -> CALM)
CALM_xxx Übersetzer (CALM -> Herstellerschreibweise)
Hinweis: je nach Prozessor fehlen einige der obigen Dateien.
Bemerkungen zum CALM-Assembler
Objektcode ohne Binder
Der CALM-Assembler erzeugt ohne Binder (Linker) einen Objektcode im
sogenannten MUFOM-Format. Damit erhält der Benützer nach Umwandlung
des MUFOM-Formats in das Binärformat direkt ein lauffähiges Programm.
Dies ist in vielen Fällen ausreichend. Auch benötigt die
Kombination Assembler-Binder, die relokative Programmteile erzeugt und
bindet, oft mehr Zeit als ein Assembler, der jeweils das ganze
Assemblerprogramm assembliert und direkt den Maschinencode erzeugt.
Dazu sollte ein Minimum an leistungsfähiger Hardware vorhanden sein
(z.B. Festplatten und emulierte Laufwerke im Hauptspeicher).
Die Art der Programmierung hängt natürlich von den Anforderungen
ab. Programme für einfache 8-Bit-Mikroprozessoren (6502, 6800, 8080,
Z80) und Mikrocomputer sind relativ klein. Ausserdem basieren diese
Prozessoren auf Betriebssystemen, die das Anwenderprogramm immer an
der gleichen Adresse laden und ausführen.
Bei leistungsfähigeren Mikroprozessoren (6809, iAPX86, 68000,
NS32000) und Betriebssystemen sind die Anforderungen höher: Programme
müssen an beliebiger Speicheradresse ausgeführt werden können und
Programme sind in Programm-, Daten- und Stapelsegmente aufzuspalten.
Beide Anforderungen sind dank leistungsfähigen Adressierungsarten
(relative Adressierung, indirekte Adressierung mit beliebigen
Abstandswerten (Offset)), usw., ohne weiteres möglich.
Beim CALM-Assembler kann der Programmierer die Adressierungsart
frei wählen. Will er positionsunabhängige Programme erzeugen (die an
einer beliebigen Adresse ausgeführt werden können ohne Relokation),
dann darf er nur noch die relative Adressierung verwenden. Auf Daten-
und Stapelsegmente kann nur noch mittels indirekter Adressierung
zugegriffen werden. Lohn dieser Einschränkungen: das generierte
Programm ist direkt ohne umständliche Relokation an beliebiger
Speicherstelle ausführbar.
Man muss auch berücksichtigen, dass sich das Programmierumfeld
gewandelt hat. Niemand adressiert heute in einem Arbeitsspeicher von
einem MByte und mehr Programme und Daten direkt mittels der absoluten
Adressierung. Dieses Konzept erfordert somit eine gewisse Disziplin
vom Programmierer, da einige Adressierungsarten nicht mehr verwendet
dürfen. Wird diese nicht aufgebracht, ist ein Assembler/Binder nötig.
Objektcode im MUFOM-Format
Der CALM-Assembler erzeugt ein Objekt im sogenannten MUFOM-Format.
Dieses Format hat gegenüber den Formaten .HEX (Intel) und S-Format
(Motorola) einige Vorteile: Zusätzlich zu den Eigenschaften der beiden
"Standard"-Formate wie Prüfsumme, Datenadressen, Startadresse,
ASCII-Zeichen, Editierfähigkeit, usw., sind folgende Informationen
vorhanden: Assembler- und Modulversion (Prozessorbeschreibung),
Dateiname, Datierung, verwendeter Prozessortyp (.PROC), Angaben zur
Prozessorarchitektur, sowie sämtliche .TITLE- und .CHAP-Zeigenfolgen
erscheinen ebenfalls in diesem Format. Alle diese Angaben sind
unkodiert (ASCII-Zeichen) und daher mit dem Kommando TYPE lesbar.
Ausserdem ist das MUFOM-Format auch für bindbare Objekte
verwendbar, mit dem Vorteil, dass das MUFOM-Format prozessorunabhängig
ist. Zur Zeit werden nur jene MUFOM-Befehle benutzt, die für nicht
bindbare Objekte notwendig sind.
Prozessordokumentation
Die zur Zeit mitgelieferte CALM-Dokumentation zu einem Prozessor
reicht im Normalfall nicht aus, um einen Prozessor in all seinen
Einzelheiten zu verstehen. Dies gilt insbesondere für Mikroprozessoren
und Mikrocomputer mit eingebauten Funktionen (wie RAM, DMA, E/A). Es
ist daher in fast allen Fällen mindestens die entsprechende
Dokumentation des Herstellers zum betreffenden Prozessor notwendig.
Die CALM-Dokumentation enthält daher auch Vergleichslisten, z.B.
Hersteller- zu CALM-Schreibweise.
CALM-Befehlslisten
CALM-Befehlsliste
In einer CALM-Befehlsliste (engl.: CALM reference card) sind alle
Befehle eines Mikroprozessors in der herstellerunabhängigen
Assemblerschreibweise CALM übersichtlich aufgeführt. Auf wenigen
Seiten erhalten Sie einen umfassenden Überblick.
Nutzen einer CALM-Befehlsliste
CALM-Befehlslisten sind in erster Linie als Hilfe im täglichen
Programmiereinsatz gedacht: Welche Adressierungsarten sind bei AND
erlaubt? Welche Bedingungsbits werden bei COMP verändert? usw.
Aber auch wenn Sie sich nicht für den CALM-Assembler interessieren,
so kann eine CALM-Befehlsliste für Sie doch nützlich sein: Wenn Sie
beispielsweise:
- den eigenen Mikroprozessor durch andere Darstellungsweise
besser kennenlernen wollen
- eine herstellerunabhängige Beschreibung aller Mikroprozessor-
befehle bekommen wollen
- Mikroprozessoren vergleichen und nicht nur auf Hersteller-
angaben angewiesen sein wollen
- einen neuen, besseren Mikroprozessor suchen
- die Leistungsfähigkeit eines Mikroprozessors beurteilen sollen
- sagen sollen, ob ein Mikroprozessor einen bestimmten Befehl/
Operationscode/Adressierungsart/Datentyp besitzt
- CALM zuerst kennenlernen wollen
Aufbau einer CALM-Befehlsliste
Die CALM-Befehlslisten sind alle nach dem gleichen Schema
zusammengestellt. Dies ergibt einerseits ein einheitliches Aussehen
und andererseits sind direkte Vergleiche möglich.
Ausserdem werden unter den CALM-Operationscodes jeweils die
Herstelleroperationscodes angegeben.
Die CALM-Befehlslisten sind in Englisch abgefasst.
Lieferumfang einer CALM-Befehlslistendokumentation
Eine CALM-Befehlslistendokumentation besteht aus:
- CALM-Befehlsliste
- Vergleich Herstellerschreibweise -> CALM-Schreibweise der
Befehle
- Beispiel (in CALM- und Herstellerschreibweise)
- alphabetisch geordnete Liste aller Operationscodes in der CALM
Schreibweise
- alphabetisch geordnete Liste aller Befehlscodes mit den
entsprechenden Befehlen in der CALM-Schreibweise
Beispiel einer CALM-Befehlsliste
Auf den folgenden Seiten ist die CALM-Befehlsliste für den 8080/5
dargestellt.
8080/8085 - 1
8080/8085
CALM REFERENCE CARD
8080/8085 Description
Programming Model
15 8 7 0
-----------------------------------------------------------------
A [ accumulator | N . Z . x . H . 0 . P . v . C ] F
-----------------------------------------------------------------
B [ | ] C
-----------------------------------------------------------------
D [ | ] E
-----------------------------------------------------------------
H [ | ] L
-----------------------------------------------------------------
15 0
-----------------------------------------------------------------
[ stack pointer ] SP
-----------------------------------------------------------------
[ program counter ] PC
-----------------------------------------------------------------
General
Address: 16 bit
Data: 8 bit (8085: data multiplexed with addresses A0-A7)
Abbreviations used
v 16'0, 16'8, 16'10, 16'18, 16'20, 16'28, 16'30, 16'38
r8 A B C D E H L
s8 B C D E H L
r16 BC DE HL SP
i8 {BC} {DE} {HL}
VAL8 8-bit value
VAL16 16-bit value
cc EQ NE CS CC MI PL PO PE
Modifications versus CALM Standard
8 Bit: All transfers are 8 bits wide, except those determined by
register names (1 letter = 8 bit, 2 letters = 16 bits).
Flag v Unspecified 8085 flag: 2's complement overflow (in arithmetic
8-bit and 16-bit operations). 8080: flag is always 1. (U8085)
Flag x Unspecified 8085 flag: sign(op1)*sign(op2) + sign(op1)*sign
(result)(U8085) + sign(op2)*sign(result). For COMP and SUB,
invert sign(op2). 8080: flag is always 0.
Remarks
- flag equalities: EQ=ZS, NE=ZC, CS=LO, CC=HS, MI=NS, PL=NC.
- Reset: IOFF
JUMP 16'0
- Interrupt: IOFF
CALL v
Additional interrupt addresses for 8085: 16'2C, 16'34, 16'3C. (8085)
- NMI: IOFF (8085)
CALL 16'24
- CALM - Intel register names: equal except: F=PSW and 16 bit names.
- CALM - Intel flag names: N=S, Z=Z, H=AC, P=P, C=C.
8080/8085 - 2
Transfer instructions
MOVE #VAL8 |,A []
VAL16 |
r8 |
i8 |
$VAL8 |
A,| VAL16
| r8
| i8
| $n
(MVI LDA MOV LDAX IN STA MOV STAX OUT)
MOVE #VAL8 |,s8 []
s8 |
{HL} |
s8,{HL}
(MVI MOV MOV)
MOVE #VAL16,r16 []
VAL16,HL
HL,VAL16
HL,SP
(LXI LHLD SHLD SPHL)
MOVE HL,{DE} [] (U8085)
{DE},HL
#{HL}+VAL8,DE
#{SP}+VAL8,DE
(SHLX LHLX LDHI LDSI)
PUSH | r16 [], r16 without SP
POP | AF [], [all] if POP AF
(PUSH POP)
SETC [C=1]
(STC)
EX DE,HL []
{SP},HL
(XCHG XTHL)
Arithmetic instructions
ADD | #VAL8 |,A [N,Z,H,P,C]
ADDC | r8 | [N,Z,H,P,C]
SUB | {HL} | [N,Z,H,P,C]
SUBC | [N,Z,H,P,C]
COMP | [N,Z,H,P,C]
(ADI ADD ACI ADC SUI SUB SBI SBB CPI CMP)
ADD r16,HL [C]
(DAD)
SUB BC,HL [N,Z,x,H,P,v,C] (U8085)
(DSUB)
INC | r8 [N,Z,H,P]
DEC | {HL} [N,Z,H,P]
(INR DCR)
INC | r16 []
DEC |
(INX DCX)
8080/8085 - 3
Logical instructions
AND | #VAL8 |,A [N,Z,H,P,C=0]
OR | r8 | [N,Z,H,P,C=0]
XOR | {HL} | [N,Z,H,P,C=0]
(ANA ANI ORA ORI XRA XRI)
NOT A []
NOTC [C]
(CMA CMC)
Shift instructions
RR | A [C = A:#0]
RRC | [C = A:#0]
RL | [C = A:#7]
RLC | [C = A:#7]
(RRC RAR RLC RAL)
ASR HL [C = L:#0] (U8085)
RLC DE [v,C = D:#7] (U8085)
(ARHL RDEL)
Program flow instructions
JUMP,cc | VAL16 []
JUMP |
CALL,cc |
CALL |
JUMP {HL} []
JUMP,XC | VAL16 [] (U8085)
JUMP,XS |
(J- JMP C- CALL PCHL JNX5 JX5)
RST v []
RST,VS 16'40 [] (U8085)
(RST RSTV) one byte call (restart)
RET,cc []
RET []
WAIT []
NOP []
ION []
IOFF []
(R- RET HLT NOP EI DI)
Special instructions
DAA A [N,Z,H,P,C]
(DAA) Decimal Adjust A, only valid after ADD and ADDC
RIM | A [] (8085)
SIM | RIM: read interrupt mask
(RIM SIM) SIM: set interrupt mask
RETEM [all] return from emulation mode (V20)
(RETEM) POP.16 IP; POP.16 CS; POP.16 SF;
MD bit write disable
TRAPNATIVE #VAL8 [MD=1] trap to native mode (8086)(V20)
(CALLN) PUSH.16 SF; PUSH.16 CS; PUSH.16 IP; SET MD;
return with RETI.32
Notes
(8085) only available in 8085.
(U8085) unspecified 8085 flag or operation code.
(V20) only available in V20, V30, V40, and V50 (8080 emulation
mode). (c) Patrick Faeh, June 1985.