Kapitel 9 - Software Interrupt (SWI / SVC)
← Startseite · Kap. 8 Regelungen · 9 Software Interrupt · → Kap. 10 Leitungscodes & CRC
Verwandt: ARM-Architektur (Modi, CPSR) · Kap. 6 Interrupts
Quellen: [Q: SI] ES-10-SI Softwareinterrupt · [Q: ZF §10/§10a]
Inhalt
- Konzept & Zweck
- Warum privilegierter Modus?
- Ablauf (Hardware)
- SWI-Handler (Software)
- Cortex-M3: SVC
- Prüfungsrelevanz
1. Konzept & Zweck
Ein Software Interrupt ist eine benutzerdefinierte, synchrone Programmunterbrechung, um vom User Mode in den privilegierten (Supervisor) Mode zu gelangen.
- Dient als Schnittstelle Anwendung ↔ Betriebssystem (System Calls, z. B.
putchar,getchar). - Im privilegierten Mode laufen privilegierte Operationen, die im User Mode verboten sind. Dort läuft typischerweise das Betriebssystem → HW-Schutz vor Anwendungen.
- synchron (im Gegensatz zum HW-Interrupt): tritt genau beim
SWI/SVC-Befehl auf, nicht asynchron.
2. Warum privilegierter Modus?
Im User Mode nicht erlaubt / geschützt:
- Zugriff auf den Speicherbereich der eingeblendeten Peripherie (I/O).
- Schreibzugriff auf Teile des Prozessor-Statusworts (CPSR).
- Moduswechsel der CPU oder Interrupts sperren.
- Beschreiben der Vektortabelle.
- Zugriff auf MPU/MMU (Memory Protection/Management Unit - Speicherschutz/virtuelle Adressen).
Nicht alle MC unterstützen einen SWI: Cortex-M0+ hat keinen dedizierten SWI-Maschinenbefehl.
3. Ablauf (Hardware-seitig, ARM7TDMI)
Befehl: SWI #<Nummer> (Syntax swi{<cond>} <Nummer>). Beim Ausführen macht die CPU automatisch:
- Status sichern: CPSR → SPSR_SVC (Flags + alter Modus bleiben erhalten).
- Moduswechsel in Supervisor Mode →
SP_svcundLR_svcwerden aktiv. - Interrupts sperren: IRQ-Disable-Bit (I) im CPSR gesetzt → Handler wird nicht sofort unterbrochen.
- Rücksprungadresse sichern: Adresse des Befehls nach dem SWI →
LR_svc(= PC − 4). - Sprung zum Vektor: PC → feste Adresse
0x08(SWI-Exception-Vector).
Befehlsformat ARM7: obere 4 Bit cond, dann 1111, dann 24-Bit-Immediate = SWI-Nummer.
4. SWI-Handler (Software-seitig)
Der Handler (ab 0x08) muss die SWI-Nummer extrahieren - sie steht nicht in einem Register, sondern im Maschinencode des Befehls selbst:
- Befehl an Adresse
[LR − 4]laden (der SWI-Befehl). - Obere 8 Bit (Opcode) mit
BIC ... #0xff000000ausmaskieren → verbleibende 24 Bit = SWI-Nummer. - Anhand der Nummer verzweigen (Sprungtabelle /
switch). - Rücksprung: SPSR → CPSR, LR → PC (User Mode wiederhergestellt).
Assembler-Handler:
SWIHandler:
stmfd sp!, {lr} @ Rücksprungadresse retten
ldr ip, [lr, #-4] @ SWI-Befehlscode laden
bic ip, ip, #0xff000000 @ obere 8 Bit ausmaskieren → SWI-Nummer
ldr lr, =SWIJumpTable
ldr ip, [lr, ip, LSL #2] @ Funktionsadresse aus Sprungtabelle
mov lr, pc
mov pc, ip @ indirekter Aufruf
ldmfd sp!, {pc}^ @ Rücksprung + CPSR restaurieren
SWIJumpTable:
.word putchar
.word getchar
.word init_ser
C-Handler:
void SWIHandler() __attribute__((interrupt("SWI")));
register int *reg_14 asm("r14"); // Link Register
void SWIHandler() {
switch (*(reg_14 - 1) & 0x00FFFFFF) { // obere 8 Bit maskieren
case 0: function0(); break;
case 1: function1(); break;
case 2: function2(); break;
}
}
// Aufruf: asm("swi 0");
5. Cortex-M3 - SVC
- Befehl:
SVC #<Nummer>(stattSWI). Vektor über die Vektortabelle (SVCall-Exception). - SVC-Nummer ermitteln: Der Handler holt den gestackten PC (
svc_args[6]), liest das Byte direkt vor dem PC → das ist die SVC-Nummer (2-Byte-SVC-Befehl):
unsigned int stacked_pc = svc_args[6];
unsigned char svc_number = ((unsigned char*)stacked_pc)[-2];
- Modi (Wiederholung ARM-Architektur): Thread (priv./unpriv., MSP/PSP) ↔ Handler (immer privileged, MSP). Eintritt über Interrupt/SVC/Fault.
- Beispiel Linux: SWI-Handler im Kernel unter
arch/arm/kernel/entry-common.S.
Prüfungsrelevanz
- Zweck: User → Supervisor Mode für privilegierte Operationen / System Calls.
- synchron (vs. HW-Interrupt asynchron).
- SWI-Nummer extrahieren: aus
[LR−4], obere 8 Bit maskieren (BIC #0xff000000). - Vektoradresse
0x08(ARM7);LR_svc = PC−4; CPSR→SPSR_SVC; IRQ gesperrt. SWI(ARM7) vs.SVC(Cortex-M3); Cortex-M0+ hat keinen.
Typische Fehler: SWI für asynchron halten · SWI-Nummer in einem Register vermuten (sie steht im Opcode) · falsche Maske (0xff000000 obere 8 Bit).