Subroutines
Subroutines and methods are the
basic building blocks of larger programs. At the heart of every
subroutine call are two fundamental actions: it has to store the
current location so it can come back to it, and it has to transfer
control to the subroutine. The
bsr
opcode does both. It pushes the address
of the next instruction onto the control stack, and then branches to
a label that marks the subroutine:
print "in main\n" bsr _sub print "and back\n" end _sub: print "in sub\n" ret
At the end of the subroutine, the ret
instruction
pops a location back off the control stack and goes there, returning
control to the caller. The jsr
opcode pushes the
current location onto the call stack and jumps to a subroutine. Just
like the jump
opcode, it takes an
absolute address
in an integer register, so the address has to be calculated first
with the set_addr
opcode:
print "in main\n" set_addr I0, _sub jsr I0 print "and back\n" end _sub: print "in sub\n" ret
Calling Conventions
A bsr
or jsr
is fine for
a
simple subroutine call, but few subroutines are quite that simple. The biggest issues revolve around register usage. Parrot has 32 registers of each type, and the caller and the subroutine share the same set of registers. How does the subroutine keep from destroying the caller’s values? More importantly, who is responsible for saving and restoring registers? Where are arguments for the subroutine stored? Where are the subroutine’s return values stored? A number of different answers ...
Get Perl 6 and Parrot Essentials, Second Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.