[SECTION .text] [GLOBAL context_switch] [GLOBAL context_launch] [GLOBAL fake_systemv_abi] ; context_switch saves the registers in the current context structure ; and populates the registers from the the next context. align 16 context_switch: ; RDI: Pointer to next context structure ; RSI: Pointer to current context structure ; Save non-scratch register of current context mov [rsi + 0], rbx mov [rsi + 8], rbp mov [rsi + 16], r12 mov [rsi + 24], r13 mov [rsi + 32], r14 mov [rsi + 40], r15 ; Save stack pointer of current context mov [rsi + 48], rsp ; context_launch populates the register set from the next context structure. ; It does not save the current registers. align 16 ; When only one parameter is used for `align`, it will use NOP context_launch: ; RDI: Pointer to next context structure ; Restore registers of next context mov rbx, [rdi + 0] mov rbp, [rdi + 8] mov r12, [rdi + 16] mov r13, [rdi + 24] mov r14, [rdi + 32] mov r15, [rdi + 40] ; Load stack pointer of next context mov rsp, [rdi + 48] ; Context switched, return ret ; fake_systemv_abi is used to populate the volatile argument registers used by the systemv abi (rdi, rsi, ...) ; with values from the non-volatile registers saved within the thread context (r15, r14, ...) align 16 fake_systemv_abi: ; Copy first parameter (placed in R15 by context_switch) to RDI mov rdi, r15 ; Copy second parameter from R14 to RSI mov rsi, r14 ; Copy third parameter from R13 to RDX mov rdx, r13 ; Return to the actual target function (kickoff) ret