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

257 lines
6.0 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
;; == High address ==
;; *OBJECT
;; 0x13115
;; *KICKOFF
;; EAX
;; ECX
;; EDX
;; EBX
;; ESP
;; EBP
;; ESI
;; SP --> EDI
;; == Low address ==
popa
;; == High address ==
;; *OBJECT
;; 0x13115
;; SP --> *KICKOFF
;; == Low address ==
sti
ret
Thread_switch:
; *
; * Hier muss Code eingefuegt werden
; *
;; NOTE: New code with pusha/popa
;; == High address ==
;; *ESP_NEXT
;; *ESP_PREV
;; SP --> RET ADDR
;; == Low address ==
push eax ; Backup eax
;; == High address == ; Scheduler stack
;; *ESP_NEXT
;; + 0x8 *ESP_PREV
;; RET ADDR
;; SP --> EAX
;; == Low address ==
mov eax, [esp + 0x8]
;; == High address == ; Previous thread stack (thread that was running when the interrupt came)
;; OLD
;; THREAD
;; STACK
;; EAX -> RET ADDR
;; == Low address ==
sub eax, 0x28
;; == High address ==
;; OLD
;; THREAD
;; STACK
;; 0x0 RET ADDR
;; 0x4
;; 0x8
;; 0xc
;; 0x10
;; 0x14
;; 0x18
;; 0x1c
;; 0x20
;; 0x24
;; EAX ->
;; == Low address ==
mov [eax], esp ; Current esp to old thread stack, 0x24 is the amount pusha, pushf change the esp
; We save it, push the current registers to the old threads stack, return and restore
;; == High address ==
;; OLD
;; THREAD
;; STACK
;; 0x0 RET ADDR
;; 0x4
;; 0x8
;; 0xc
;; 0x10
;; 0x14
;; 0x18
;; 0x1c
;; 0x20
;; 0x24
;; EAX -> ESP (Points not to RET ADDR but the EAX we pushed as backup!!!)
;; == Low address ==
;; BUG: Not the correct value
pop eax ; ESP still points to the EAX we pushed before
;; == High address ==
;; *ESP_NEXT
;; *ESP_PREV
;; SP --> RET ADDR
;; == Low address ==
mov esp, [esp + 0x4]
;; == High address ==
;; OLD
;; THREAD
;; STACK
;; SP --> RET ADDR
;; 0x4
;; 0x8
;; 0xc
;; 0x10
;; 0x14
;; 0x18
;; 0x1c
;; 0x20
;; 0x24
;; 0x28 ESP
;; == Low address ==
pusha ; Save current registers to stack
;; == High address ==
;; OLD
;; THREAD
;; STACK
;; RET ADDR
;; EAX
;; ECX
;; EDX
;; EBX
;; ESP
;; EBP
;; ESI
;; EDI
;; SP -->
;; ESP
;; == Low address ==
pushf
;; == High address ==
;; OLD
;; THREAD
;; STACK
;; RET ADDR
;; EAX
;; ECX
;; EDX
;; EBX
;; ESP
;; EBP
;; ESI
;; EDI
;; EFLAGS
;; SP --> ESP
;; == Low address ==
pop esp ; The POP ESP instruction increments the stack pointer (ESP)
; before data at the old top of stack is written into the destination.
;; == High address ==
;; *ESP_NEXT
;; *ESP_PREV
;; RET ADDR
;; SP -->
;; == Low address ==
mov esp, [esp + 0xc] ; 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
;; == High address ==
;; NEW
;; THREAD
;; STACK
;; RET ADDR
;; EAX
;; ECX
;; EDX
;; EBX
;; ESP
;; EBP
;; ESI
;; SP --> EDI
;; == Low address ==
popa
;; == High address ==
;; NEW
;; THREAD
;; STACK
;; SP --> RET ADDR
;; == Low address ==
;; Enable interrupts again
sti
ret