Author Topic: Recursion Using Inline Assembler  (Read 5219 times)

0 Members and 1 Guest are viewing this topic.

Offline Charles Pegge

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 672
  • User-Rate: +27/-1
    • Charles Pegge
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.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


Offline Charles Pegge

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 672
  • User-Rate: +27/-1
    • Charles Pegge
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 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