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.
' Skeleton Inline Assembler Function showing how to do binary recursion.
' Charles E V Pegge
' 21 June 2007
' FreeBasic ver 0.16b
function binrecurse(byval d as long ptr,byval c as long) as long
asm
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 tally
end asm
end function
dim dd(1000) as long
dim cc as long
for cc=0 to 8
print cc,binrecurse(varptr(dd(0)),cc)
next
The PB Win version:
' 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 tally
END FUNCTION
FUNCTION PBMAIN () AS LONG
DIM dd(1000) AS LONG
DIM c AS LONG
DIM s AS STRING
FOR c=0 TO 8
s=s+STR$(c)+" "+STR$(binrecurse(VARPTR(dd(0)),c))+CHR$(13)+CHR$(10)
NEXT
MSGBOX s
END FUNCTION