github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/internal/task/task_stack_386.S (about)

     1  .section .text.tinygo_startTask
     2  .global  tinygo_startTask
     3  .type    tinygo_startTask, %function
     4  tinygo_startTask:
     5      .cfi_startproc
     6      // Small assembly stub for starting a goroutine. This is already run on the
     7      // new stack, with the callee-saved registers already loaded.
     8      // Most importantly, EBX contain the pc of the to-be-started function and
     9      // ESI contain the only argument it is given. Multiple arguments are packed
    10      // into one by storing them in a new allocation.
    11  
    12      // Indicate to the unwinder that there is nothing to unwind, this is the
    13      // root frame. It avoids bogus extra frames in GDB.
    14      .cfi_undefined eip
    15  
    16      // Set the first argument of the goroutine start wrapper, which contains all
    17      // the arguments.
    18      pushl %esi
    19  
    20      // Branch to the "goroutine start" function.
    21      calll *%ebx
    22  
    23      // Rebalance the stack (to undo the above push).
    24      addl $4, %esp
    25  
    26      // After return, exit this goroutine. This is a tail call.
    27      jmp tinygo_pause
    28      .cfi_endproc
    29  
    30  .global tinygo_swapTask
    31  .type tinygo_swapTask, %function
    32  tinygo_swapTask:
    33      // This function gets the following parameters:
    34      movl 4(%esp), %eax // newStack uintptr
    35      movl 8(%esp), %ecx // oldStack *uintptr
    36      // More information on the calling convention:
    37      // https://wiki.osdev.org/System_V_ABI#i386
    38  
    39      // Save all callee-saved registers:
    40      pushl %ebp
    41      pushl %edi
    42      pushl %esi
    43      pushl %ebx
    44  
    45      // Save the current stack pointer in oldStack.
    46      movl %esp, (%ecx)
    47  
    48      // Switch to the new stack pointer.
    49      movl %eax, %esp
    50  
    51      // Load saved register from the new stack.
    52      popl %ebx
    53      popl %esi
    54      popl %edi
    55      popl %ebp
    56  
    57      // Return into the new task, as if tinygo_swapTask was a regular call.
    58      ret