• Welcome to Jose's Read Only Forum 2023.
 

Recursion Using Inline Assembler

Started by Charles Pegge, June 21, 2007, 05:09:14 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Charles Pegge


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


Charles Pegge

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