Not having a ret
instruction in the asm is totally normal; you want to let the compiler generate function prologues / epilogues, including a ret
instruction, like they normally do for paths of execution that reach the }
in a function. (Or you'd use __declspec(naked)
to write the whole function in asm, including handling the calling convention, which would let you use fastcall
to take args in registers instead of needing to load them from stack memory).
The more interesting thing is falling off the end of a non-void
function without a return
. (I edited your question to ask about that, too).
In ISO C++, that's undefined behaviour. (So compilers like clang -fasm-blocks
can assume that path of execution is never reached, and not even emit any instructions for it, not even a ret
.) But MSVC does at least de-facto define the behaviour of doing that,
MSVC specifically does support falling off the end of a non-void function after an asm
statement, treating EAX or ST0 as the return value. Or at least that's how MSVC de-facto works, whether it's intentional support or not, but it does even support inlining such functions, so it's not just a calling-convention abuse of UB. (clang -fasm-blocks
does not work that way; IDK about clang-cl
. But it does not define the behaviour of falling off the end of a non-void function, fully omitting the ret
because that path of execution must not be reachable.)
Not using ret
in the asm{}
block
ESP isn't pointing at the return address when the asm{}
block executes; I think MSVC always forces functions using asm{}
to set up EBP as a frame pointer.
You definitely can't just ret
out of the middle of a function without giving the compiler a chance to restore call-preserved registers and clean up the stack in the function epilogue.
Also, what if the compiler had inlined power2
into a caller?
Then you'd be returning from that caller (if you did leave
/ ret
in an asm block).
Look at the compiler-generated asm.
(TODO: I was going to write more and link something on https://godbolt.org/, but never got back to it.)