GOSUB label ... label: ... RETURNpb_cg_emit_gosub_return (pb_codegen.c:1738), pb_cg_emit_gosub_pop_return (pb_codegen.c:1768)Calls a local subroutine (defined by a label) within the same function and returns to the statement immediately following GOSUB. Unlike CALL (which invokes external DLL functions), GOSUB is an intra-procedure mechanism. The compiler maintains a dedicated GOSUB return address stack in the stack frame (max 32 entries). Each GOSUB pushes the return address; each RETURN pops and jumps to it.
| Parameter | Description |
|---|---|
label | The name of the subroutine label to jump to. The subroutine must be in the same FUNCTION or SUB and must end with RETURN. |
RETURN | Ends a GOSUB subroutine and returns execution to the statement after the calling GOSUB. |
FUNCTION PBMAIN() AS LONG
PRINT "Main start"
' Call local subroutine
GOSUB PrintBanner
GOSUB PrintBanner
PRINT "Main end"
FUNCTION = 0
PrintBanner:
PRINT "===================="
PRINT " PowerBASIC x64"
PRINT "===================="
PRINT
RETURN
END FUNCTION
mov r10, [rbp - gosub_depth_offset] ; current depth cmp r10, 32 ; PB_GOSUB_STACK_MAX jl __pb_gosub_push_ok_N mov rcx, 1 call [__imp_ExitProcess] ; overflow -> abort __pb_gosub_push_ok_N: lea r11, [rbp - gosub_stack_base] ; stack base mov rax, r10 imul rax, 8 ; depth * 8 sub r11, rax ; r11 = &stack[depth] lea rax, [__pb_gosub_return_N] ; return address mov [r11], rax ; store on stack add r10, 1 mov [rbp - gosub_depth_offset], r10 ; depth++ jmp __pb_label_<routine>_<label> ; jump to subroutine
mov r10, [rbp - gosub_depth_offset] ; current depth sub r10, 1 mov [rbp - gosub_depth_offset], r10 ; depth-- lea r11, [rbp - gosub_stack_base] mov rax, r10 imul rax, 8 sub r11, rax ; r11 = &stack[depth-1] mov rax, [r11] ; load return address jmp rax ; indirect jump to return point __pb_gosub_return_N: ; return target
GOSUB SayHello PRINT "Back from GOSUB" FUNCTION = 0 SayHello: PRINT "Hello!" RETURN