Stack Overhead Reduction

There may be some instances where you wish to repeatedly call a very small SUB and this may produce a situation where the normally modest stack overhead may actually become a factor in the speed of the entire algorithm.

To help boost performance in such cases, PowerBASIC offers the often-overlooked GOSUB/RETURN statements, which can be used in place of a call to a SUB/END SUB block.  Where stack overhead reduction is critical, you can create a Label in the code below the end of your normal code (but still within the current Sub/Function block).

You may then take the Inline Assembler code from the target SUB, and place it right after the Label.  Finally, a RETURN statement is added so that execution resumes at the next instruction after the GOSUB.  Such code would look something like this:

FUNCTION MyFunc() AS LONG

  ' Inline Assembler code

  GOSUB LABEL

  ' More Inline Assembler code

  EXIT FUNCTION ' or EXIT SUB

 

LABEL:

  ' Your Inline Assembler code

  RETURN

END FUNCTION  ' or END SUB

This technique is very efficient because the variables used in the Inline Assembler Sub/Function (that have been moved from a SUB, back into the calling code) are maintained within the same scope as the calling code, and can therefore be used without having to pass them on the stack.  The result is that we have eliminated virtually all the stack overhead involved in repeatedly calling a SUB.

Finally, you can even use the standard Intel assembler notation !CALL and !RET within the Sub/Function, to jump to the Label and return from it to the next instruction.  For example:

FUNCTION MyFunc() AS LONG

  ' Inline Assembler code

  ! CALL LABEL

  ' More Inline Assembler code

  EXIT FUNCTION ' or EXIT SUB

 

LABEL:

  ' Your Inline Assembler code

  ! RET

END FUNCTION  ' or END SUB

Finally, it is very important to note that you must NEVER exit a PowerBASIC Sub/Function with the RET instruction.  PowerBASIC Subs and Functions automatically perform their own stack cleanup (of local variables, etc) when an END SUB/FUNCTION or EXIT SUB/FUNCTION statement is executed, whereas an RET instruction would try to force a Sub/Function exit without the internal stack cleanup being performed.  A RET instruction cannot ever be used as a substitute for these BASIC statements.

In summary, your program will fail with a spectacular Stack Fault (GPF) if you attempt to terminate a PowerBASIC Sub/Function with RET mnemonic.

 

See Also

The Inline Assembler

The stack

Balancing the stack

Tricks of the stack

Saving registers