; Listing10-1.asm ; ; A program that demonstrates a ; simple range iterator. option casemap:none .nolist include aoalib.inc include aoaProcs.inc includelib aoalib.lib .list ; Program title: .const align word ttlStr byte "Listing 10-1", 0 .code ; iterator range( start:dword, stop:dword ) parms range, rbp, 0, \ dynamicLink:qword, \ yieldAdrs:qword, \ failAdrs:qword, \ start:dword, \ stop:dword range proc push rbp mov rbp, rsp mov edx, range$start mov r8d, range$stop call print byte "in range, %d to %d", nl, 0 ForEverLbl: mov eax, range$start cmp eax, range$stop jg ForDone ; "Magic" yield operation: push range$dynamicLink ;Caller’s RBP call range$yieldAdrs ; Move on to next iteration of the loop inc range$start jmp ForEverLbl ForDone: pop rbp add rsp, 8 ;Remove return address ret 16 ;Use failure address as return and range endp ; pop parameters ;-------------------------------------------------- ; ; Here is the main assembly language function. public asmMain asmMain proc push rbp mov rbp, rsp sub rsp, 80 mov eax, 10 ; Push stop parameter value. push rax ; Remember, push in reverse order! mov eax, 1 ; Push start parameter value push rax lea rax, ForDone ;Push the failure/end loop address push rax call range ;Call the iterator ; Body of the foreach loop: push rbp ;Preserve iterator’s rbp value mov rbp, [rsp+16] ;Get original RBP value passed by range mov edx, eax ;Display i’s value call print byte "%d", nl, 0 pop rbp ;Restore iterator's RBP value ret 8 ;Return and clean RBP off stack ; After the foreach loop: ForDone: leave ret asmMain endp end