134 lines
3.6 KiB
NASM
Executable File
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
|