Ein switch case
ist eine Kontrollstruktur, die es ermöglicht, eine Variable oder einen Ausdruck mit mehreren möglichen Werten zu vergleichen. Basierend auf dem Wert wird der entsprechende Fall (Case) ausgewählt und dessen Anweisungen ausgeführt. Diese Struktur ermöglicht eine effiziente und übersichtliche Handhabung von mehreren Bedingungen im Vergleich zu einer langen Kette von if-else
-Anweisungen.
case(X)
0: statement 0; break;
1: statement 1; break;
2: statement 2; break;
default: statement 3; break;
Wichtig: X darf nicht größer als Anzahl cases sein, es liegt am Programmierer dies zu gewährleisten!
In Assembler wird die switch-case
-Struktur durch indirekte Sprünge effizient umgesetzt. Ein indirekter Sprung ist ein Sprungbefehl, bei dem die Zieladresse nicht direkt angegeben ist. Stattdessen wird die Adresse in einem Register oder Speicherort gespeichert, und der Sprung erfolgt zur in diesem Register oder in dem Speicherort angegebenen Adresse.
Anstelle einer ineffizienten, linearen Reihe von Vergleichen wie bei if-else
, bei denen jede Bedingung nacheinander geprüft wird, wird bei switch-case
ein Sprungtabelle verwendet.
Diese Tabelle enthält Adressen zu den verschiedenen case
-Labels. Die Implementierung erfolgt typischerweise so:
case
-Labels wird erstellt.BX
) wird verwendet, um direkt zum passenden Codeblock zu springen..data
table: .word case0
.word case1
.word case2
.word default
Eine Sprungtabelle wie diese funktioniert, indem sie eine Liste von Adressen (Sprungziele) enthält, die den Code für verschiedene cases repräsentieren.
.text
start:
MOV r0, #2 @ r0 = X
@ CASE(X)
AND r0, r0, #3
LDR r1, =table
LDR r1, [r1, r0, LSL #2]
BX r1
case0:
MOV r2, #1
B endcase
case1:
MOV r2, #2
B endcase
case2:
MOV r2, #3
B endcase
default:
MOV r2, #5
endcase:
MOV r0, r2
...
Erklärung des Sprungbefehls
LDR r1, [r1, r0, LSL #2]
BX r1
r1: enthält die Basisadresse der Sprungtabelle.
r0: ist der Index, der mit LSL #2 multipliziert wird, um auf das richtige Wort in der Tabelle zuzugreifen. Der Index wird mit 4 multipliziert, weil jede Adresse in der Sprungtabelle 4 Bytes groß ist. Die Multiplikation stellt sicher, dass man den richtigen Speicherplatz für das gewünschte Element in der Tabelle trifft, da die Tabelle sequentiell in 4-Byte-Schritten angeordnet ist.
LDR r1, [r1, r0, LSL #2]: gibt somit an, dass die effektive Adresse durch Hinzufügen des verschobenen Werts von r0 zur Basisadresse in r1 gebildet wird, anschließend wird diese Adresse in r1 geladen.
BX r1 führt einen bedingungslosen Sprung zur Adresse aus, die in r1 steht.
Alternativ hätte man dem Sprung auch in einer Zeile realisieren können:
LDR pc, [r1, r0, LSL #2]
zurück | Hauptmenü | weiter |
3.2 Kontrollstrukturen |
---|
3.2.1 Intro |
3.2.2 If-not-then |
3.2.3 If-elseIf-then |
3.2.4 If-then elseif-then |
3.2.5 Switch-Case |
3.2.6 While-Schleifen |
3.2.7 Do-While-Schleifen |
3.2.8 Zustandsautomaten |