← ST-Computer 10 / 1989

Ein ganz kurzes Accessory

Programmierpraxis

“Wäre doch gelacht, wenn ich da nicht noch ein paar Bytes rauskitzeln könnte”, dachte ich mir, als ich mir vornahm, ein bis aufs letzte Byte optimiertes Accessorys zu schreiben, das mir den noch verbleibenden freien Speicherplatz anzeigen sollte.

Irgendwo gab's mal ein RAM-FREE-Programm, das auch nur den freien Restspeicher anzeigte, jedoch eine Länge von 2560 Bytes aufwies und führende Nullen nicht unterdrückte. Das geht besser, dachte ich. Mit ca. 600 Bytes war die erste Version lauffähig, aber bei weitem noch nicht fertig; nun fing die Kleinarbeit erst an:

Datenregister, wenn möglich, mit MOVEQ, Adreßregister mit LEA füllen, Unterroutinen so schieben, daß Kurzadressierung möglich wird (BSRS). Quellen PC-relativ adressieren und Ziele adreßregisterindirekt ansprechen, dabei möglichst auf nicht veränderte Register zurückgreifen. Diese und einige andere auch schon in Ausgabe 7/8 1989 im Artikel Assembler-Optimierung gemachte Möglichkeiten führten dann nach langen Sitzungen zu dem Programm, was Sie unten sehen können. Hinzu kommt die Ausnutzung des Umstandes, daß nicht alle Register bei Systemaufrufen verändert werden. Aber Vorsicht, das gleicht einem Tanz auf dem flochseil und muß bei neueren TOS-Versionen nicht so bleiben.

Interessant dürfte jedoch die Art der Initialisierung sein, wie der Aufruf des AES automatisch die drei Register D7/A5/A6 mit Werten belegt, so daß die Parameter für CONTRL auf effektiv(st)e Weise übergeben werden können. Die Variante mit MOVEP (siehe 1.) zieht hierbei den Kürzeren, funktioniert leider auch nicht auf dem sonst recht guten GFA-Assembler, der hierbei falsche Adreß-Offsets berechnet. Na, und die Dezimalroutine kann sich auch sehen lassen. Sie können sie für eigene Projekte weiterverwenden.

Literatur:

Assembleroptimierung, ST-Computer 7/8 1989

M68000-Familie, W. Hilf / A. Nausch, TeWi Verlag, ISBN 3-921803-16-0

; ****************************** ; Ein ganz kurzes Accessory ; 7/89 Jürgen Stessun ; (c) MAXON Computer GmbH ; zeigt freien Speicherplatz an ; ****************************** ; Initialisierungsteil fürs ACC ; ****************************** lea STACK(pc),sp ; der Stapel für's ACC bsr.s FILA6 ; a6 und a5 =CONTRL, d7=1 move.w #10,(a5)+ ; 10 Opcode Appl_Init move.l d7,(a5)+ ; 0*Intin 1*Intout (d7=1) clr.w (a5)+ ; 0*Addrin bsr.s AES ; AES-Aufruf, Register setzen move.w INTOUT(pc),APPID-CONTRL(a6) ; Appl.-Nummer merken move.w #35,(a5)+ ; 35 Menu_Register move.w d7,(a5)+ ; 1*Intin(d7=1) move.w d7,(a5)+ ; 1*Intout move.w d7,(a5)+ ; 1*Addrin move.w APPID(pc),INTIN-CONTRL(a6) ; Applikationsnummer move.l #ACCNAME,ADDRIN-CONTRL(a6) ; der ACC-Name bsr.s AES ; AES aufrufen move.w INTOUT(pc),ACCID-CONTRL(a6) ; die ACC-Nummer LOOP: bsr.s MEVENT ; auf Ereignis warten cmpi.w #40,MSGBUFF-CONTRL(a6) ; ACC Open? bne.s LOOP ; nein, weiter warten move.w MSGBUFF+8(pc),d0 ; die ACC-Nummer cmp.w ACCID(pc),d0 ; bin ich gemeint? bne.s LOOP ; nein, weiter warten bsr.s MAIN ; ja, Hauptroutine abarbeiten bra.s LOOP ; und danach wieder warten MEVENT: move.w #23,(a5)+ ; 23 Evnt_Mesag move.l d1,(a5)+ ; 0*Intin 1*Intout (d7=1) move.w d7,(a5)+ ; 1*Addrin move.l #MSGBUFF,ADDRIN-CONTRL(a6) ; Message-Puffer ; ****************************** ; AES aufrufen ; ****************************** AES: move.l #AESPB,d1 ; Zeiger auf Adressliste clr.w (a5)+ ; 0*Addrout move.w #$c8,d0 ; Wert für AES trap #2 ; aufrufen FILA6: lea CONTRL(pc),a6 ; Zeiger für A6 movea.l a6,a5 ; und A5 moveq.l #1,d7 ; d7 auf 1 setzen rts ; fertig mit AES ; *************************** ; Der eigentliche Aktionsteil ; *************************** MAIN: moveq.l #-1,d0 ; Restspeicher erfragen move.l d0,-(sp) ; -1.L auf Stack move.w #$48,-(sp) ; MALLOC trap #1 ; Gemdos addq.l #6,sp ; in D0 Restspeicher lea NUMMER(pc),a4 ; Stringadresse in Alert PRLONG: bsr.s LONGNUM ; in Dezimal wandeln move.l #ALTEXT,ADDRIN-CONTRL(a6) ; Text für Alarmbox ALERT: move.w #52,(a5)+ ; 52 Form Alert move.w d7,(a5)+ ; 1*Intin(d7=l) move.w d7,(a5)+ ; 1*Intout move.w d7,(a5)+ ; 1*Addrin move.w d7,INTIN-CONTRL(a6) ; Default Button = 1 bra.s AES ; ****************************** ; Die Dezimal-Umwandlungsroutine ; ****************************** LONGNUM: moveq.l #7,d4 ; insgesamt 7 Stellen move.l #1000,d1 ; zuerst 4-stellig moveq.l #(' '-'0'),d2 ; Space erlaubt divu.w d1,d0 ; durch 1000 bsr.s D4TODEZ ; umwandeln swap.w d0 ; Rest in d0.w moveq.l #100,d1 ; dann 3-stellig D4TODEZ: move.w d0,d3 ; Zahl retten W1: ext.l d3 ; auf Lang erweitern subq.w #1,d4 ; schon letzte Ziffer? bne.s W2 ; nein clr.w d2 ; sonst kein Space erlaubt W2: divu.w d1,d3 ; Rest durch Teiler beq.s DEZPR1 ; ergab schon 0 clr.w d2 ; kein Space erlaubt DEZPR1: add.b d2,d3 ; Offset zu Space addieren addi.b #'0',d3 ; Offset für ASCII move.b d3,(a4)+ ; ablegen in String swap.w d3 ; Rest der Division divu.w #10,d1 ; nächster Teiler bne.s W1 ; wenn ungleich 0 rts ; sonst fertig .DATA ACCNAME: .DC.b ' Memory',0 ; 2 Spaces vor 'Me...' ALTEXT: .DC.b '[0][Memory:' NUMMER: .DC.b ' Bytes ' ; 8 Spaces vor 'By...' .DC.b '][Ok]',0 .EVEN AESPB: .DC.l CONTRL,GLOBAL,INTIN,INTOUT,ADDRIN,ADDROUT .BSS APPID: .DS.w 1 ; die Applikationsnummer ACCID: .DS.w 1 ; die ACC-Nummer MSGBUFF: .DS.b 16 ; der Nachrichtenpuffer CONTRL: .DS.w 1 ; Opcode der AES-Funktion .DS.w 1 ; Anzahl der Intin-Einträge .DS.w 1 ; Anzahl der Intout-Ausgaben .DS.w 1 ; Anzahl der Addrin-Einträge .DS.w 1 ; Anzahl der Addrout-Ausgaben GLOBAL: .DS.w 15 INTIN: .DS.w 2 ; Wort-Eingaben INTOUT: .DS.w 2 ; Wort-Ausgaben ADDRIN: .DS.1 2 ; Adreß-Eingaben ADDROUT: .DS.l 2 ; Adreß-Ausgaben .DS.b 100 ; Platz für Stapel STACK: .END a$=SPACE$(320) adr%=VARPTR(a$) RESTORE daten CLR pruef% FOR n%=0 TO 79 READ b$ wert%=VAL("&H"+b$) LPOKE adr%+4*n%,wert% pruef%=pruef% XOR (wert%) NEXT n% IF pruef%<>&H73DF00B4 ALERT 1," Daten nicht korrekt | Bitte überprüfen",1,"OK",dummy% ELSE BSAVE "MEMORY.ACC",adr%,318 ALERT 1," Alles Ok ",1,"Ende",dummy% ENDIF EDIT daten: DATA 601A0000,D40000,400000,B80000,0,0,0,4FFA01CA,61663AFC DATA A2AC7,425D614E,3D7A0142,FFEC3AFC,233AC7,3AC73AC7 DATA 3D7A00F2,282D7C,D4,30612E,3D7A0122,FFEE6116,C6E0028 DATA FFF066F6,303A00DE,B07A00D0,66EC612A,60E83AFC,172AC7 DATA 3AC72D7C,118,30223C,FC,425D303C,C84E42,4DFA00BA,2A4E7E01 DATA 4E7570FF,2F003F3C,484E41,5C8F49FA,646118,2D7C0000,DD0030 DATA 3AFC0034,3AC73AC7,3AC73D47,2860BE,7807223C,3E8,74F080C1 DATA 61044840,72643600,48C35344,66024242,86C16702,4242D602 DATA 6030030,18C34843,82FC000A,66E24E75,20204D65,6D6F7279,5B305D DATA 5B4D656D,6F72793A,20202020,20202020,42797465,73205D5B DATA 4F6B5D00,128,132,150,154,158,160,28,30082A72,4040404 DATA 4000000 ! 320 Bytes=80 Data
Jürgen Stessun