; Listing8-2.asm ; ; A program that demonstrates deferred execution of a statement ; using thunks. option casemap:none .nolist include aoalib.inc include aoaProcs.inc include aoaTypes.inc includelib aoalib.lib .list .const ; Program title: align word ttlStr byte "Listing 8-2", 0 .code ; ifexpr ; ( ; expressionValue:byte, ; execIfTrue:thunk, ; execIfFalse:thunk ; ) parms ifexpr, rsp, 8, \ expr:byte, \ trueStmts:thunk_t, \ falseStmts:thunk_t 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 mov rcx, ifexpr$trueStmts.environment call ifexpr$trueStmts.procedure jmp ifdone elsePart: call print byte "calling falseStmts", nl, 0 mov rcx, ifexpr$trueStmts.environment call ifexpr$falseStmts.procedure ifdone: ret ifexpr endp ;-------------------------------------------------- ; ; Here is the main assembly language function. public asmMain locals asmMain, c:dword, d:dword asmMain proc push rbp mov rbp, rsp sub rsp, 64 mov asmMain$c, 10 ;Automatic, must initialize mov asmMain$d, 20 mov edx, asmMain$c mov r8d, asmMain$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: push rbp mov rbp, rcx call print byte "in stmt1", nl, 0 mov eax, asmMain$c inc asmMain$c pop rbp ret stmt2: push rbp mov rbp, rcx call print byte "in stmt2", nl, 0 mov eax, asmMain$d dec asmMain$d pop rbp ret ; Call ifexpr with a false expression: overStmt1and2: mov byte ptr [rsp], 0 ;Expr=false mov [rsp+8], rbp ;Pass thunk lea rax, stmt1 ; stmt1 mov [rsp+16], rax mov [rsp+24], rbp ;Pass thunk lea rax, stmt2 ; stmt2 mov [rsp+32], rax call ifexpr mov edx, eax mov r8d, asmMain$c mov r9d, asmMain$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 ;Expr=true mov [rsp+8], rbp ;Pass thunk lea rax, stmt1 ; stmt1 mov [rsp+16], rax mov [rsp+24], rbp ;Pass thunk lea rax, stmt2 ; stmt2 mov [rsp+32], rax call ifexpr mov edx, eax mov r8d, asmMain$c mov r9d, asmMain$d call print byte "ifexpr(1) returned %d, c=%d, d=%d", nl, 0 leave ret asmMain endp end