54 lines
1.5 KiB
NASM
54 lines
1.5 KiB
NASM
[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
|