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 Preisliste). 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.