I am very new to assembly and I am wondering about the behavior of ret. If i never use a call during the code, but put a ret at the end, the code just goes back to the beginning. Is this a default behavior when there is no call used? If I used a jmp, would that affect the behavior of ret if there is still no call used?
2 Answers
call
puts the next instruction's address into the call stack, then jumps to the target address.
ret
pops the last address from the call stack, then jumps here. It seems that if the stack is empty, it returns 0x00000000
, and it jumps to the start of the program. At least in some systems. You should not use this because of address space violations.
jmp
has no effect on the call stack, so it won't modify the behavior of ret
.
Edit: As @PeterCordes wrote; if you use push
or pop
, they can write stack memory, and ret
would pop that.
In many systems, the bootup/startup code actually calls the main()
function (or its equivalent), e.g. bare metal AVR programs using https://www.nongnu.org/avr-libc/ (That has the advantage that the compiler can compile main()
as a function like any other, not needing any special treatment).
So when your user code in main()
does ret
(even though your user code itself never actually calls anthing), your user code will return from that implicit call and the bootup/startup code will continue running.
Now the question is what the bootup/startup code does after main()
has returned. It could go into an endless busy loop, halt the system, power down, reboot, etc.