; Listing8-1.asm
;
; A program that demonstrates deferred execution of a statement.
;


            option     casemap:none
            .nolist
            include    aoalib.inc
            include    aoaProcs.inc
            includelib aoalib.lib
            .list
            
            .const

; Program title:

             align  word
ttlStr       byte   "Listing 8-1", 0



            .data
c           dword   10
d           dword   20
            
            .code


; ifexpr( expressionValue, execIfTrue, execIfFalse )
;
; Note: code is not Windows ABI compliant. Not needed
; here. The "print" routine cleans up the stack so
; that when it actually calls the C printf statement,
; the system is Windows ABI compliant.

            parms ifexpr, rsp, 8,   \
                  expr:byte,        \
                  trueStmts:qword,  \
                  falseStmts:qword

ifexpr      proc    

; If the expression value passed to this function is
; true, execute the trueStmts code, otherwise
; execute the falseStmts code:

            movzx   edx, ifexpr$expr
            call    print
            byte    "expr=%d", nl, 0
            
            test    edx, edx
            je      elsePart
            
            call    print
            byte    "calling trueStmts", nl, 0
            
            call    ifexpr$trueStmts
            jmp     ifdone
            
elsePart:   call    print
            byte    "calling falseStmts", nl, 0
            call    ifexpr$falseStmts
ifdone:     ret
ifexpr      endp

;--------------------------------------------------
;
; Here is the main assembly language function.
            
            public  asmMain
                        
asmMain     proc
            push    rbp
            mov     rbp, rsp
            sub     rsp, 64

            mov     edx, c
            mov     r8d, d
            call    print
            byte    "Before ifexpr(0), c=%d, d=%d", nl, 0
            
; Set up the "procedures" to call for "ifexpr(0/1)"

            jmp     overStmt1and2 
            
stmt1:      call    print
            byte    "in stmt1", nl, 0
            mov     eax, c
            inc     c
            ret

stmt2:      call    print
            byte    "in stmt2", nl, 0
            mov     eax, d
            dec     d
            ret

; Call ifexpr with a false expression:

overStmt1and2:  
            mov     byte ptr [rsp], 0
            lea     rax, stmt1
            mov     [rsp+8], rax
            lea     rax, stmt2
            mov     [rsp+16], rax
            call    ifexpr
            
            mov     edx, eax
            mov     r8d, c
            mov     r9d, d
            call    print
            byte    "ifexpr(0) returned %d, c=%d, d=%d", nl, 0
            
; Call ifexpr with a true expression

            mov     byte ptr [rsp], 1
            lea     rax, stmt1
            mov     [rsp+8], rax
            lea     rax, stmt2
            mov     [rsp+16], rax
            call    ifexpr
            
            mov     edx, eax
            mov     r8d, c
            mov     r9d, d
            call    print
            byte    "ifexpr(1) returned %d, c=%d, d=%d", nl, 0
        

            leave
            ret
        
asmMain     endp
            end