global clear_tss global switch_to global set_tss extern ctask extern ctaskn extern gdt extern save_state ; void switch_to(int n, struct task_struct *task); switch_to: push ebp mov ebp, esp push ebx ; abort if we're switching to the current task mov ebx, [ctask] cmp ebx, [ebp+12] jne .skip pop ebp ret .skip: ; update ctask and ctaskn mov ebx, [ebp+12] mov [ctask], ebx mov ebx, [ebp+8] mov [ctaskn], ebx ; calculate the task segment index and jump to it mov ebx, [ebp+8] add ebx, 5 shl ebx, 3 mov [.tmp+4], bx jmp far [.tmp] pop ebx pop ebp ret .tmp: dq 0 ; void set_tss(unsigned int n, void *tss); set_tss: push ebp mov ebp, esp push ebx mov eax, [ebp+12] mov ebx, [ebp+8] shl ebx, 3 add ebx, gdt+40 mov [ebx+2], ax shr eax, 16 mov [ebx+4], al mov [ebx+7], ah mov eax, 103 ; limit - 1 mov [ebx], ax shr eax, 16 and al, 0x0F mov [ebx+6], al mov byte [ebx+5], 0x89 pop ebx pop ebp ret ; void clear_tss(unsigned int n); clear_tss: push ebp mov ebp, esp push ebx mov ebx, [ebp+8] shl ebx, 3 add ebx, gdt+40 mov byte [ebx+5], 0 pop ebx pop ebp ret