SUB name [( [BYVAL|BYREF] param [AS type] [, ...] )] ... statements ...END SUB
A SUB (subroutine) declares a callable procedure that performs actions but does not return a value. Subroutines are used for procedural code, side effects, and operations where no result needs to be passed back to the caller.
Parameters follow the same rules as FUNCTION declarations: they can be passed BYVAL (by value, the default) or BYREF (by reference). A subroutine terminates when execution reaches END SUB or when EXIT SUB is encountered.
Since subroutines have no return value, they are invoked with the CALL statement or by simply using their name followed by arguments.
| Parameter | Description |
|---|---|
name | The identifier name of the subroutine. Must be unique within the program scope. Follows standard PBXA64 naming rules. |
BYVAL | Optional keyword. Passes the argument by value (default). The subroutine receives a copy. |
BYREF | Optional keyword. Passes the argument by reference. Modifications to the parameter affect the caller's variable. |
param | The parameter name used within the subroutine body. |
AS type | Optional type specification. Supported types include LONG, DWORD, INTEGER, BYTE, STRING, SINGLE, DOUBLE, QUAD, CUR, EXT, and user-defined TYPEs. |
SUB PrintGreeting(BYVAL name AS STRING)
PRINT "Hello, "; name; "!"
END SUB
SUB SwapValues(BYREF a AS LONG, BYREF b AS LONG)
LOCAL temp AS LONG
temp = a
a = b
b = temp
END SUB
FUNCTION PBMAIN() AS LONG
LOCAL x AS LONG
LOCAL y AS LONG
x = 10
y = 20
PrintGreeting "PBXA64 User"
PRINT "Before swap: x="; x; " y="; y
CALL SwapValues(x, y)
PRINT "After swap: x="; x; " y="; y
FUNCTION = 0
END FUNCTION
; Standard Win64 prologue push rbp ; save old base pointer mov rbp, rsp ; set new base pointer sub rsp, frame_size ; allocate stack frame for locals ; Save non-volatile registers (if used) push rbx push rsi push rdi push r12 push r13 push r14 push r15 ; Initialize BYVAL parameters (copy from registers to stack) mov [rbp - param1_offset], rcx ; 1st BYVAL param -> stack mov [rbp - param2_offset], rdx ; 2nd BYVAL param -> stack mov [rbp - param3_offset], r8 ; 3rd BYVAL param -> stack mov [rbp - param4_offset], r9 ; 4th BYVAL param -> stack ; 5th+ params are already on the caller's stack above RSP ; Initialize BYREF parameters (store pointer directly) ; (No copy needed, pointer is already in RCX/RDX/etc.)
; Restore non-volatile registers pop r15 pop r14 pop r13 pop r12 pop rdi pop rsi pop rbx ; Restore stack frame add rsp, frame_size pop rbp ret
jmp __pb_sub_epilogue ; jump directly to epilogue
CALL keyword is optional when invoking a subroutine. Both CALL MySub(args) and MySub args are valid.OPTIONAL or OPT parameters in subroutines.EXPORT modifier.BYREF parameters when the subroutine needs to modify the caller's variables.