The way a process terminates depends on the operating system. On Linux, in amd64 version, you can use the syscall instruction to invoke calls to the kernel (system calls). One of them is equivalent to C's exit() function:
mov eax,60 ; 60 is the code for exit().
mov edi,0 ; 0 on EDI is the code passed to exit().
syscall ; finally calls exit(0) - ending the process
But, if you are using Linux, 32 bits version, the syscall instruction isn't present. You must use int 0x80 interface to do system calls. The equivalent from above is:
mov eax,1 ; 1 is the code for exit().
mov ebx,0 ; 0 on EBX is the code to pass to exit().
int 0x80 ; calls exit(0), ending the process
Notice the codes are different for amd64 and i386 linuxes...
I don't know how to do for Windows Desktop Applications, except the old DOS way:
mov ax,0x4c00 ; 0x4C is exit; 0x00 is the errorlevel.
int 0x21
If you disassemble a code created by a C compiler, you'll see a RET instruction in the end of the main() funcion. It is this way because main() is called by the "runtime" object file linked to your program without you knowing... this runtime will call main() and exit your process when main() returns (doing some housekeeping like closing all files, freeing memory, etc)...