The 2051 supports function calls:
transfers control to the code labelled fct
acall pushes the current PC on to the stack.
The SP register points to the stack - defaults to 7
The push, increments SP before transferring PC
ret pops back the previous PC from the stack
The pop, decrements SP after transferring PC
The assembler programmer has to decide, when a subroutine is called, if registers are to be saved or not.
A subroutine may, when it is invoked, always save the registers it uses on the stack.
Programs that call these routines can be sure that there are no side effects - no registers are altered.
This may be inefficient!
The subroutine may alter R5 and so push and pop it to preserve its contents.
However the calling program may not use R5 at all - in which case the subroutine has pushed and popped needlessly.
Another scheme is to have the calling program save registers before the acall
and recover them afterwards.
This suffers from the drawback that the main routine may save registers that the subroutine doesn't use.
A final scheme is for the subroutine to document which registers it uses and for the calling program to save only the ones that it wants.
Status flags are typically always altered by the actions of the subroutine.
1. In Registers.
Used by most assembly programs.
Has a problem with large numbers of parameters - may run out of registers.
Complex types - eg strings have to have their address passed.
2. In a parameter block.
Pass a pointer to a block of memory in a register. The subroutine reads the parameters from the block of memory.
Each routine has to have its own block of memory.
3. Immediately after the acall.
Parameters can be retrieved by finding out the return address (on the stack) and reading the parameters from that area of memory.
Can't do this if the program is in PROM!
The return address on the stack has to be fiddled before the ret will work. Otherwise the program will return and try and execute the first parameter.
4. On the stack
Most High Level Languages use this method
The calling program pushes parameters onto the stack. The subroutine accesses them via the stack pointer.
One problem is - who pop’s them at the end?
In Pascal it is the responsibility of the subroutine to tidy up the stack before returning.
In C it is the responsibility of the calling routine.
Pascal and C also have different conventions about the order of the parameters.
In Pascal arguments are pushed from left to right.
C pushes them in the reverse order
C is designed for a variable number of arguments.
Assembler 8 -