.
.
btfsc STATUS,Z
goto loop
.
.
loop: return
How does this code behave? goto is not branching out, so nothing is saved on the stack? There are no calls in the code as well.
goto and btfsc instructions both affect the program counter, not the stack.
In your snippet if the Z bit of the STATUS register is set then program counter advances to the next instruction. The goto instruction executes changing the program counter to the address of the return instruction at the label loop. The return instruction will set the program counter to the return address on the stack. There must be a valid return address on the stack at that point. If the stack is not set the resulting jump is unpredictable.
If the Z bit is clear then the program counter ‘skips’ and is advanced to the next instruction after the goto instruction where program execution will continue.