#### 0(%esp) - old registers #### 16(%esp) - return address #### 20(%esp) - current thread #### 24(%esp) - new thread .globl thread_switch thread_switch: # Save caller's register state. # Note that the SVR4 ABI allows us to destroy %eax, %ecx, %edx. # This stack frame must match the one set up by thread_create(). pushl %ebx pushl %ebp pushl %esi pushl %edi # Get offsetof (struct thread, stack). .globl thread_stack_ofs mov thread_stack_ofs, %edx # Save current stack pointer to old thread's stack, if any. movl 20(%esp), %eax test %eax, %eax jz 1f movl %esp, (%eax,%edx,1) 1: # Restore stack pointer from new thread's stack. movl 24(%esp), %ecx movl (%ecx,%edx,1), %esp # Restore caller's register state. popl %edi popl %esi popl %ebp popl %ebx ret