; Listing11-1.asm
;
; A program that demonstrates simple fiber calls.

            option     casemap:none
            .nolist
            include    aoalib.inc
            include    aoaProcs.inc
            includelib aoalib.lib
            include    c:\masm32\include64\win64.inc
            include    c:\masm32\include64\kernel32.inc
            includelib c:\masm32\lib64\kernel32.lib  
            
            .list
            
; Program title:

            .const
             align  word
ttlStr       byte   "Listing 11-1", 0


            .data
mainFiber   qword   ?       ;Pointer to Windows' asmMain stuff
fiber       qword   ?       ;Pointer to Windows' myFiber stuff
fiberData   dword   456
            .code

; A simple fiber that prints it was called
; and then passes control back to the main fiber.

            locals  myFiber, fiberData:qword
myFiber     proc
            push    rbp
            mov     rbp, rsp
            sub     rsp, 80
            
            mov     myFiber$fiberData, rcx
            
            mov     edx, [rcx]
            call    print
            byte    "In myFiber, parm=%d", nl, 0
                    
            mov     rcx, mainFiber
            call    SwitchToFiber
            
; Demonstrate that the stack maintained its state
; across the switch:

            mov     rcx, myFiber$fiberData
            mov     edx, [rcx]
            call    print
            byte    "In myFiber again, parm=%d", nl, 0

            mov     rcx, mainFiber
            call    SwitchToFiber    

            leave   ;Never executes, just because...
            ret
myFiber     endp

;--------------------------------------------------
;
; Here is the main assembly language function.
            
            public  asmMain
asmMain     proc
            push    rbp
            mov     rbp, rsp
            sub     rsp, 80
            
            mov     rcx, 123        ;Kind of irrelevant here.
            call    ConvertThreadToFiber
            mov     mainFiber, rax
            
            xor     rcx, rcx
            lea     rdx, myFiber
            lea     r8, fiberData        ;To print inside myFiber.
            call    CreateFiber
            mov     fiber, rax
            
            call    print
            byte    "Switching to myFiber", nl, 0
            
            mov     rcx, fiber
            call    SwitchToFiber
            
            call    print
            byte    "Back to asmMain, "
            byte    "switching back to myFiber", nl, 0
 
            mov     rcx, fiber
            call    SwitchToFiber
            
            call    print
            byte    "Back to asmMain once more, quitting"
            byte    nl, 0
            
; Clean up the fiber we created:

            mov     rcx, fiber
            call    DeleteFiber
            
            call    ConvertFiberToThread
            test    al, al
            jnz      allDone
            
            call    GetLastError
            mov     edx, eax
            call    print
            byte    "Windows error %d converting fiber "
            byte    "to thread", nl, 0
            
allDone:    leave
            ret
        
asmMain     endp
            end