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