2021-04-03 - i386 coroutines
I have been trying to add coroutines to a hobby OS. Lots of the examples are in Intel syntax, 64-bit architecture, or sell themselves as windows/linux/mac only.
Finally got a working solution after tweaking a few examples. The AT&T syntax assembly and the coroutine init code came from here: https://stackoverflow.com/questions/62766352/assembly-coroutines
A stacksize of 8192 seems to work (based on the comments of the stackoverflow question) and stack can be malloc-ed or not. "ptr" can point to our switch task or a cleanup subroutine that also runs switch task at the end.
uint32_t* ptr; /* the new stack pointer */ ptr = (uint32_t*)((uint8_t*)stack + stacksize); ptr -= 7; ptr = 1; /* edi */ ptr = 2; /* esi */ ptr = 3; /* ebx */ ptr = (uint32_t)(ptr + 5); /* ebp */ ptr = (uint32_t)func; ptr = (uint32_t)switch_task; /* return instruction address */ .global switch_task switch_task: 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