about summary refs log tree commit diff
path: root/src/rt/arch/i386/_context.S
blob: a9e329f0bf358ce9dffc5d2c033c6780c09ddba9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
        .text

/*
Callee save registers:
        ebp, ebx, esi, edi

Caller save registers:
        eax, ecx, edx
*/

/*
Saves a set of registers. This is used by our implementation of
getcontext.

The registers_t variable is in (%esp)
*/

// swap_registers(registers_t *oregs, registers_t *regs)
.globl swap_registers
swap_registers:
    // save the old context
    movl 4(%esp), %eax
    movl %ebx, 4(%eax)
    movl %ebp, 16(%eax)
    movl %esi, 20(%eax)
    movl %edi, 24(%eax)

    // save the flags
    pushf
    popl %ecx
    movl %ecx, 44(%eax)

    // save the return address as the instruction pointer
    // and save the stack pointer of the caller
    popl %ecx
    movl %esp, 28(%eax)
    movl %ecx, 48(%eax)

    // restore the new context
    movl 4(%esp), %eax

    movl 4(%eax), %ebx
    movl 16(%eax), %ebp
    movl 20(%eax), %esi
    movl 24(%eax), %edi
    movl 28(%eax), %esp

    // restore the flags
    movl 44(%eax), %ecx
    push %ecx
    popf

    // Return!
    jmp *48(%eax)