Atom supports true subroutines and function calls through the subroutine opcodes. A subroutine must be defined after the end: and must start with subroutine: subname and end with endsub:.
When a subroutine is called using the call: opcode, the current frame (register set) is saved onto the frame stack. The frame stack is a Last-In-First-Out (LIFO) stack. To pass parameters to a subroutine, push the registers onto the stack with pushdata:. The data stack is also a LIFO stack so the registers that you are using as parameters must be popped off the data stack in reverse order. To return data from the subroutine, push the registers onto the stack and pop them off after the call: as returned.
Because the frame is saved between calls, recursion is possible. Care must be taken in order to preserve the order of any parameters or return registers. See recurse.ata in the samples folder for an example of using recursion.