; Listing8-3.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-3", 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 "in ifexpr, 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$falseStmts.environment call ifexpr$falseStmts.procedure ifdone: ret ifexpr endp ;-------------------------------------------------- ; ; Here is the main assembly language function. public asmMain locals asmMain, \ c:dword, \ d:dword, \ s1:thunk_t, \ s2:thunk_t asmMain proc push rbp mov rbp, rsp sub rsp, 64 mov asmMain$c, 10 ;Automatic, must initialize mov asmMain$d, 20 ; Set up the "procedures" to call for "ifexpr(0/1)" setTh asmMain$s1 push rbp mov rbp, rcx call print byte "in stmt1", nl, 0 mov eax, asmMain$c inc asmMain$c pop rbp ret endTh setTh asmMain$s2 push rbp mov rbp, rcx call print byte "in stmt2", nl, 0 mov eax, asmMain$d dec asmMain$d pop rbp ret endTh mov edx, asmMain$c mov r8d, asmMain$d call print byte "Before ifexpr(0), c=%d, d=%d", nl, 0 ; Call ifexpr with a false expression: mov byte ptr [rsp], 0 ;Expr=false copyTh [rsp+8], asmMain$s1 ;True thunk copyTh [rsp+24], asmMain$s2 ;False thunk 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 copyTh [rsp+8], asmMain$s1 ;True thunk copyTh [rsp+24], asmMain$s2 ;False thunk 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