The address of the CALL routine is equivalent to the address of the next PUSH instruction + the address of the JMP routine .
At the same time, the PUSH address is almost equivalent to SUB xSP, pointer size + MOV [xSP], address .
SUB xSP, pointer size can be replaced with PUSH .
RET is almost equivalent to JMP [xSP] , followed by ADD xSP, the address of the pointer at the location where the JMP leads.
And ADD xSP, the pointer address can be replaced with POP .
So you can see what basic freedom the compiler has. Oh, by the way, it can optimize your code so that your function is fully integrated, and there is no call or return from it.
While somewhat perverse, it is not possible to make much more frightening control transfers using instructions and methods very specific to the platform (CPU and OS).
To transfer control, you can use IRET instead of CALL and RET if you push the appropriate things on the stack for instructions.
You can use Windows Structured Exception Handling so that the command that throws the CPU exception (e.g. division by 0, page error, etc.) distracts the execution from your exception handler, and from there control can be transferred either back to the same instructions to either the next or next exception handler or to any location. And most x86 instructions can cause processor exceptions.
I am sure there are other unusual ways to control the transfer, inside and inside routines / functions.
You can often see code similar to this:
... CALL A A: JMP B db "some data", 0 B: CALL C ; effectively call C with a pointer to "some data" as a parameter. ... C: ; extracts the location of "some data" from the stack and uses it. ... RET
Here, the first call is not a subroutine, it's just a way to populate the address of data stuck in the middle of the code.
This is probably a programmer, not a compiler. But I could be wrong.
What I'm trying to say with all of this is that you should not expect CALL and RET be the only way to enter and exit subprograms, and you should not expect that they will be used for this purpose and balance each other .