← TOS 02 / 1991

Tips und Tricks für Programmierer

Programmieren

Sortier-Algorithmus in Assembler

Wer öfter mit Tabellen arbeitet, weiß, wie zeitaufwendig eine Sortierung der darin befindlichen Daten ist. Eine kleine Routine in Assembler benötigt selbst für größere Mengen nur kurze Zeit. Wir verwenden den sogenannten »Bubble-Sort«-Algorithmus (Listing 1), der eine Tabelle von Zahlen nach steigendem Wert sortiert. Kleinere Zahlen gelangen dabei wie Blasen im Wasser nach oben. Das Programm verfolgt einen einfachen Algorithmus. Dieser vergleicht lediglich zwei aufeinander folgende Zahlen. War die zweite Zahl kleiner, werden die beiden Zahlen in der Tabelle vertauscht, das sog. Austausch-Bit gesetzt und die nächsten Zahlen bearbeitet. Der Sortiervorgang ist schließlich beendet, wenn ein Durchlauf ohne Vertauschung stattfindet. Die Routine benötigt folgende Parameter: die Anfangsadresse der Tabelle sowie deren Länge. Die Startadresse übergeben Sie in Adreßregister A1. Außerdem enthält der erste Tabelleneintrag die Anzahl der auf ihn folgenden Einträge. Die Routine liefert keinen Rückgabewert. Bitte beachten Sie, daß das Listing eine Tabelle mit Einträgen der Breite »Word« verarbeitet. Für andere Datentypen ist eine entsprechende Anpassung erforderlich. (ah)

Listing 1: Klein aber schnell: die Bubblesort-Routine

; Bubble-Sort ; Tabellenanfang in a1 sortierung: movem.l d0-d2/a0-a1, -(sp) ; Register retten s_begin: move.w (a1), d0 ; Anzahl der Tabelleneintäge lea 2(a1), a0 bclr #7, d2 ; Austausch-Bit löschen subq.w #2, d0 s_loop: move.w (a0)+, d1 ; Eintag i in d1 cmp.w (a0), d1 ; mit Eintrag i+1 vergleichen ble.s s_ende ; falls i <= i+1, dann Ende move.w (a0), -2(a0) ; Tabelleneinträge move.w d1, (a0) ; vertauschen bset #7, d2 ; Austausch-Bit setzen s_ende: dbra d0, s_loop btst #7, d2 ; Austausch-Bit gesetzt? bne.s s_begin ; Ja, dann nochmal movem.l (sp)+, d0-d2/a0-a1 ; Register zurück fertig: rts

# Suchen einer beliebigen Zeichenkette

Für die Verwaltung einer großen Menge Textdaten ist es oftmals erforderlich, bestimmte Textpassagen zu suchen. Unsere Routine arbeitet nach einem einfachen aber effektiven Schema (Listing 2). Zunächst sucht sie den Speicher nach dem ersten Buchstaben des Suchstrings ab. Erst wenn dieser übereinstimmt, vergleicht die Routine jeden weiteren Buchstaben. Schlägt dieser Vergleich z.B. nach der vierten Stelle fehl, geht‘s wieder auf die Suche nach dem ersten Buchstaben, bis eine komplette Übereinstimmung vorhanden oder die Speichergrenze erreicht ist. Ein »:« muß den Suchstring beenden. Als Parameter erwartet die Routine die Startadresse des zu suchenden Textes in A1. Die Startadresse des Speicherbereichs, in dem die Suche stattfindet, übergeben Sie in A0. Das Ende dieses Bereiches muß mit einem »*« markiert sein. Bei erfolgreicher Suche gibt die Routine in A3 die Anfangsadresse des gefundenen Strings zurück. (ah)

Listing 2: Gezielte Suche nach Textpassagen aller Art

; Routine zum Suchen eines Strings ; Startadresse des Suchstrings in A1 ; Startadresse des Speicherbereichs in A0 movem.l d1/a2, -(sp) ; Register retten movea.l a1, a2 cmpi.b #‘:‘, (a1) ; Enthält String ein Zeichen? beq.s gotcha ; nein, dann raus move.b (a1), d1 ; Erstes Zeichen nach d1 bra.s erster wied: movea.l a2, a1 ; Startadresse Suchstring addq.l #1, a3 ; Ein Zeichen weiter movea.l a2, a0 ; kopieren erster: cmp.b (a0)+, d1 ; 1. Buchstabe stimmt? beq.s weiter cmpi.b #‘*‘, (a0) ; Ende des Speicherbereiches bne.s erster bra.s nichts_da ; nein, dann wieder Suchen weiter: addq.l #1, a1 ; auf zweiten Buchstaben zeigen movea.l a0, a3 ; Adresse kopieren subq.l #1, a3 testen: cmpi.b #‘:‘, (a1) ; Ende des Suchstrings? beq.s gotcha ; Suche erfolgreich! cmpi.b #‘*‘, (a0) ; Ende des Speicherbereiches? beq.s nichts_da ; ja, dann nichts gefunden. cmpm.b (a0)+, (a1)+ ; Vergleichen beq.s testen ; falls gleich -> weiter machen bra.s wied ; sonst wieder von vorne nichts_da: movea.l #0, a3 gotcha: movem.l (sp)+, d1/a2 ; Register zurück rts