title: Assembly Coroutines
body: <p>I'm trying to create a coroutine implementation for fun to be used with C programs. I'm running on Windows 64bit, Intel x86-64. I'm compiling my function with CodeBlocks 17.12 which is using mingw32-gcc (MinGW.org GCC-6.3.0-1). My current implementation segfaults with 0xC0000005 (access violation) when I try and call printf in the coroutine. I'm at a loss for what the problem is and how to debug it.</p>
  <p>I'm getting my inspiration from:</p>
  <ol>
  <li><a href="https://stackoverflow.com/questions/50429345/fast-fibers-coroutines-under-x64-windows">Fast fibers/coroutines under x64 Windows</a> which links to:</li>
  <li><a href="https://the8bitpimp.wordpress.com/2014/10/21/coroutines-x64-and-visual-studio/" rel="nofollow noreferrer">https://the8bitpimp.wordpress.com/2014/10/21/coroutines-x64-and-visual-studio/</a></li>
  </ol>
  <h2>main.c</h2>
  <pre><code>#include &lt;stdint.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  extern void swap32(void*, void*);
  
  typedef struct {
      uintptr_t sp;
  } Coro;
  
  Coro mainco;
  Coro otherco;
  
  uint8_t costack[1024];
  
  void cofunc(Coro* coro)
  {
      printf(&quot;Hello&quot;);
  
      unsigned i;
      for(i = 10; i &lt; 20; i++)
      {
          printf(&quot;coro: %d\n&quot;, i);
  
          swap32(&amp;otherco, &amp;mainco);
      }
  }
  
  void prepare(Coro* coro, void* stack, unsigned stacksize, void (*func)(Coro*))
  {
      uint32_t* ptr;
      ptr    = (uint32_t*)((uint8_t*)stack + stacksize);
      ptr   -= 7;
      ptr[0] = 1;                 /* edi */
      ptr[1] = 2;                 /* esi */
      ptr[2] = 3;                 /* ebx */
      ptr[3] = (uint32_t)(ptr+5); /* ebp TODO: fix? */
      ptr[4] = (uint32_t)func;
      ptr[5] = (uint32_t)swap32;  /* return instruction address TODO: fix? */
      coro-&gt;sp = ptr;
  }
  
  int main()
  {
      prepare(&amp;otherco, costack, 1024, cofunc);
  
      unsigned i;
      for(i = 0; i &lt; 10; i++)
      {
          printf(&quot;main:  %d\n&quot;, i);
  
          swap32(&amp;mainco, &amp;otherco);
      }
  
      return 0;
  }
  </code></pre>
  <h2>coro.S</h2>
  <p>Assembly in AT&amp;T syntax.</p>
  <pre><code>.global _swap32
  
  // ecx: context for the coroutine that is being paused.
  // edx: context for the coroutine that is being resumed.
  _swap32:
      mov 4(%esp), %ecx
      mov 8(%esp), %edx
      # Save registers
      push %ebp
      push %ebx
      push %esi
      push %edi
      # Save old stack
      mov %esp, (%ecx)
      # Load new stack
      mov (%edx), %esp
      # Restore registers
      pop %edi
      pop %esi
      pop %ebx
      pop %ebp
      ret
  </code></pre>
  <p>Here is my general understanding:</p>
  <ol>
  <li><p>When a coroutine yields/pauses, it needs to store its stack pointer, instruction pointer, and registers somewhere.</p>
  </li>
  <li><p>In my implementation, the return address (next instruction pointer) is stored in the C call to <code>swap32</code> because the calling <code>swap32</code> pushes the return address to the current stack.</p>
  </li>
  <li><p><code>swap32</code> saves the current stack pointer then swaps the stack pointer for the destination coroutine so that when <code>ret</code> is finally executed, the saved instruction pointer for the destination coroutine is called.</p>
  </li>
  <li><p>A coroutine is initialized by setting up a stack frame as if it had called <code>swap32</code>. In my implementation, the register state is saved in the stack. Therefore, the initialized coroutine's stack would look like this (with decreasing addresses):</p>
  <pre><code>function parameters    &lt;--- start of function's stack
  return address         &lt;--- where a normal ebp would point to
  swap32 return address  &lt;--- pushed because of call to swap32
  saved context          &lt;--- pushed because swap32 saves context to current stack
  </code></pre>
  <p>That way, <code>swap32</code> pops the saved context, followed by <code>ret</code> popping the saved function and resuming the coroutine.</p>
  </li>
  </ol>
  <p>What I see is this: if I remove the calls to <code>printf</code> from <code>cofunc</code>, then the coroutine yields back to main successfully. If I add the calls to <code>printf</code> back to <code>cofunc</code>, then my program crashes. So here is where my understanding runs out.</p>
  <h2>Question:</h2>
  <p>Why does it crash with <code>printf</code> and not crash without? Is it because I haven't initialized the coroutine correctly or is there another reason for it to be crashing?</p>