Tips und Tricks für Programmierer

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


Aus:TOS 02 /1991, Seite

Links

Copyright-Bestimmungen: siehe Über diese Seite