33 lines
1.2 KiB
NASM
33 lines
1.2 KiB
NASM
global asm_switch_context
|
||
|
||
asm_switch_context:
|
||
; 1. Сохраняем регистры текущей задачи (то, что не сохраняет C)
|
||
push ebx
|
||
push ebp
|
||
push esi
|
||
push edi
|
||
|
||
; После 4-х пушей структура стека выглядит так:
|
||
; [esp + 0] -> edi
|
||
; [esp + 4] -> esi
|
||
; [esp + 8] -> ebp
|
||
; [esp + 12] -> ebx
|
||
; [esp + 16] -> адрес возврата (куда возвращаться в kthread_yield)
|
||
; [esp + 20] -> первый аргумент: uint32_t** old_esp
|
||
; [esp + 24] -> второй аргумент: uint32_t* new_esp
|
||
|
||
; 2. Забираем аргументы из старого стека
|
||
mov eax, [esp + 20] ; eax = old_esp
|
||
mov edx, [esp + 24] ; edx = new_esp
|
||
|
||
; 3. Меняем стеки
|
||
mov [eax], esp ; Сохраняем текущий ESP потока
|
||
mov esp, edx ; ПЕРЕПРЫГИВАЕМ НА НОВЫЙ СТЕК
|
||
|
||
; 4. Восстанавливаем регистры новой задачи
|
||
pop edi
|
||
pop esi
|
||
pop ebp
|
||
pop ebx
|
||
|
||
ret ; Прыгаем либо в kthread_yield другого потока, либо в entry_point
|