1
Files
lecture-operating-system-de…/c_os/kernel/threads/Thread.asm

134 lines
3.6 KiB
NASM
Executable File

;*****************************************************************************
;* *
;* C O R O U T I N E *
;* *
;*---------------------------------------------------------------------------*
;* Beschreibung: Assemblerdarstellung der 'struct CoroutineState' aus *
;* CoroutineState.h *
;* *
;* Die Reihenfolge der Registerbezeichnungen muss unbedingt *
;* mit der von 'struct CoroutineState' uebereinstimmen. *
;* *
;* Autor: Olaf Spinczyk, TU Dortmund *
;*****************************************************************************
; EXPORTIERTE FUNKTIONEN
[GLOBAL Thread_switch]
[GLOBAL Thread_start]
; IMPLEMENTIERUNG DER FUNKTIONEN
[SECTION .text]
Thread_start:
; *
; * Hier muss Code eingefuegt werden
; *
;; NOTE: New code with pusha/popa, restores all registers as I use this not only for first start
;; == High address ==
;; ESP
;; SP --> RET ADDR
;; == Low address ==
mov esp, [esp + 0x4]
;; == High address ==
;; *OBJECT
;; 0x13115
;; *KICKOFF
;; EAX
;; ECX
;; EDX
;; EBX
;; ESP
;; EBP
;; ESI
;; EDI
;; SP --> EFLAGS
;; == Low address ==
popf
popa
;; == High address ==
;; *OBJECT
;; 0x13115
;; SP --> *KICKOFF
;; == Low address ==
sti
ret
Thread_switch:
; *
; * Hier muss Code eingefuegt werden
; *
;; NOTE: The thread switching works like this:
;; 1. Prev thread is running, pit interrupt triggers preemption, interrupt handler called
;; 2. Prev registers are pushed to prev stack after the return address
;; 3. Switch to next stack
;; 3. Registers are popped from stack, the esp now points
;; to the return address (that was written to the stack when it
;; was switched from)
;; 4. Return follows the return address to resume normal stack execution
;; == High address ==
;; ESP_NEXT
;; *ESP_PREV
;; SP --> RET ADDR
;; == Low address ==
pusha
pushf
;; == High address ==
;; + 0x2c ESP_NEXT
;; + 0x28 *ESP_PREV
;; + 0x24 RET ADDR
;; EAX
;; ECX
;; EDX
;; EBX
;; ESP
;; EBP
;; ESI
;; EDI
;; SP --> EFLAGS
;; == Low address ==
mov eax, [esp + 0x28] ; Point to *ESP_PREV (Address)
mov [eax], esp ; Update thread esp variable
;; ============================================================
mov esp, [esp + 0x2c] ; Move to next coroutines stack
;; == High address ==
;; NEW
;; THREAD
;; STACK
;; RET ADDR
;; EAX
;; ECX
;; EDX
;; EBX
;; ESP
;; EBP
;; ESI
;; EDI
;; SP --> EFLAGS
;; == Low address ==
popf ; Load new registers from stack
popa
;; == High address ==
;; NEW
;; THREAD
;; STACK
;; SP --> RET ADDR
;; == Low address ==
;; Enable interrupts again
sti
ret