I noticed that many assembler language examples built using direct Win32 calls (without C Runtime dependency) illustrate the use of an explicit ExitProcess () call to terminate the program at the end of the entry point code. I'm not talking about using ExitProcess () to exit some nested place in the program. There are surprisingly fewer examples where the entry point code just exits with a RET statement. One example that comes to mind is the famous TinyPE , where program variants come out with a RET instruction because the RET command is a single byte. Using ExitProcess () or RET seems to do the job.
A RET from the executable entry point returns the EAX value back to the Windows bootloader in KERNEL32, which ultimately passes the exit code back to NtTerminateProcess (), at least in Windows 7. In Windows XP, I think I remember seeing that ExitProcess () is even called directly at the end of the thread cleanup chain.
Since there are many respected optimizations in assembly language that are chosen solely to generate less code, I wonder why more code floating around prefers to explicitly call ExitProcess () rather than RET. Is this a habit or is there another reason?
In the purest sense, is it not advisable to specify RET on a direct call to ExitProcess ()? A direct call to ExitProcess () seems to be similar to exiting your program, killing it from the task manager, since it causes a short circuit in the normal return thread back to where the Windows boot loader called your entry point and thus skipped various thread cleaning operations?
I cannot find any information related to this problem, so I was hoping that someone could shed some light on this topic.
source
share