### Author Topic: Recursion Using Inline Assembler  (Read 5264 times)

0 Members and 1 Guest are viewing this topic.

#### Charles Pegge

• Global Moderator
• Hero Member
• Posts: 674
• User-Rate: +27/-1
##### Recursion Using Inline Assembler
« on: June 21, 2007, 05:09:14 PM »

Recursive functions are always a bit confusing. Doing them using Inline assembler adds a few extra complications. This example shows how it can be done safely, making minimal assumptions about the BASIC/Assembler interface.

To spice things up a little the recursive routine calls two of itself.

All we do in this example is increment a counter using the edx register
each time the routine is entered or reentered.

Code: [Select]
`' Skeleton Inline Assembler Function showing how to do binary recursion.'  Charles E V Pegge'  21 June 2007' FreeBasic ver 0.16bfunction binrecurse(byval d as long ptr,byval c as long) as longasm push ebx    ' preserve ebx register push [d]    ' push our datablack pointer onto stack for transfer push [c]    ' push extinction counter onto stack for transfer. pop ecx     ' po extinction counter into ecx pop ebx     ' pop datablock base address into ebx xor edx,edx ' clear edx call aa     ' call the recursion routine jmp cc      ' goto to the exit procedure'----------------------------------------------------------------------aa:          ' start of recursion routine             ' BODY OF CODE HERE inc edx     ' tally the number of entries dec ecx     ' decrement the extinction counter jl  bb      ' return if this is less than zero otherwise procede             ' MORE CODE GOES HERE push ecx    ' need to conserve ecx after first calls but not the last call aa     ' first call to aa recursion pop ecx     ' restore extinction counter for the next call call aa     ' last call to aa recursion'----------------------------------------------------------------------bb:          ' extinction point             ' remember to clean up stack  anything is on there ret         ' return control to previous caller'----------------------------------------------------------------------cc:          ' exit procedures before ending the main recurse function pop ebx     ' restore ebx mov [function],edx ' return the tallyend asmend functiondim dd(1000) as longdim cc as longfor cc=0 to 8 print cc,binrecurse(varptr(dd(0)),cc)next`

#### Charles Pegge

• Global Moderator
• Hero Member
• Posts: 674
• User-Rate: +27/-1
##### Re: Recursion Using Inline Assembler
« Reply #1 on: June 21, 2007, 05:42:40 PM »
The PB Win version:
Code: [Select]
`' Skeleton Inline Assembler Function showing how to do binary recursion.'  Charles E V Pegge'  21 June 2007' PowerBasic ver 8x #COMPILE EXE#DIM ALL    FUNCTION binrecurse(BYVAL d AS LONG PTR,BYVAL c AS LONG) AS LONG! push ebx    ' preserve ebx register! push d      ' push our datablack pointer onto stack for transfer! push c      ' push extinction counter onto stack for transfer.! pop ecx     ' po extinction counter into ecx! pop ebx     ' pop datablock base address into ebx! xor edx,edx ' clear edx! call aa     ' call the recursion routine! jmp cc      ' goto to the exit procedure'----------------------------------------------------------------------aa:           ' start of recursion routine!             ' BODY OF CODE HERE! inc edx     ' tally the number of entries! dec ecx     ' decrement the extinction counter! jl  bb      ' return if this is less than zero otherwise procede!             ' MORE CODE GOES HERE! push ecx    ' need to conserve ecx after first calls but not the last! call aa     ' first call to aa recursion! pop ecx     ' restore extinction counter for the next call! call aa     ' last call to aa recursion'----------------------------------------------------------------------bb:           ' extinction point!             ' remember to clean up stack  anything is on there! ret         ' return control to previous caller'----------------------------------------------------------------------cc:           ' exit procedures before ending the main recurse function! pop ebx     ' restore ebx! mov function,edx ' return the tallyEND FUNCTIONFUNCTION PBMAIN () AS LONGDIM dd(1000) AS LONGDIM c AS LONGDIM s AS STRINGFOR c=0 TO 8 s=s+STR\$(c)+"  "+STR\$(binrecurse(VARPTR(dd(0)),c))+CHR\$(13)+CHR\$(10)NEXTMSGBOX sEND FUNCTION        `