.file "enter_context_x86_64.s" .text .global __cs_enter_context .type __cs_enter_context, @function .align 16 __cs_enter_context: # Parameter List (in order) # rdi = new stack pointer # rsi = first parameter to callback # rdx = callback function pointer # rcx = new stack limit (not used on most platforms) # Return # rax = continuation that returned control back to the caller (null if fallthrough) # Variables # r12 = temporary for the old stack pointer ############### Save State ############### # Make space on the stack leaq -0x38(%rsp), %rsp # Store calee saved general registers. movq %r12, 0x00(%rsp) movq %r13, 0x08(%rsp) movq %r14, 0x10(%rsp) movq %r15, 0x18(%rsp) movq %rbx, 0x20(%rsp) movq %rbp, 0x28(%rsp) # Store MMX control- and status-word stmxcsr 0x30(%rsp) # Store x87 control-word fnstcw 0x34(%rsp) ############### Save State ############### # Perform change to new stack. # Keep old stack as second parameter to our callback function. movq %rsp, %r12 # Make sure that stack start is properly aligned. andq $-16, %rdi # Switch to new stack pointer. movq %rdi, %rsp # Init the new stack to something reasonable. # Here we point it at the finish part of our function with the frame pointer at 0x0. # This is not stricly required, but stops debuggers/tools from freaking out. leaq __cs_finish(%rip), %r13 pushq %r13 pushq $0x0 movq %rsp, %rbp # Perform actual function call, this will now be on the new stack # rdi = first parametor to callback (continuation) # rsi = second parameter to callback (arbetary pointer) movq %r12, %rdi call *%rdx # Restore state of returned continuation. # To do so we first reset the stack pointer (which we get returned in rax). # After that we execute our standard restore procedere to pop the state from the stack. movq %rax, %rsp ############ Restore State ############ # restore calee saved general registers movq 0x00(%rsp), %r12 movq 0x08(%rsp), %r13 movq 0x10(%rsp), %r14 movq 0x18(%rsp), %r15 movq 0x20(%rsp), %rbx movq 0x28(%rsp), %rbp # restore MMX control- and status-word ldmxcsr 0x30(%rsp) # restore x87 control-word fldcw 0x34(%rsp) # Free space on the stack leaq 0x38(%rsp), %rsp ############ Restore State ############ # Just return back from the call. # This is the end of a fiber, so we have no continuation. xor %rax, %rax ret __cs_finish: # exit code is zero xorq %rdi, %rdi # exit application call _exit@PLT hlt