The ret instruction is not a real instruction per say, it gets converted to a retn or a retf, standing for “Return Near” and “Return Far” respectively. This depends on where you are returning to in memory. A retn is for when you are returning to an address within the same segment you are currently in, and a retf is for when you return to a different segment.


Generally speaking a retn will:

pop eip     ; This operation has two effects: 1) it will remove the return 
            ; address from the top of the stack and place it into the EIP 
            ; register. 2) Since it was placed within the EIP register which 
            ; always points to the currently executing instruction in memory,
            ; execution will now jump to that address and continue executing 
            ; from there.



A ret can be provided a value, e.g. ret 4 which is typically used in calling conventions where the callee cleans up the stack. A ret 4 will return to the caller and then add 4 to ESP to remove the pushed argument to the function that was just returned from off the stack.


Example: If you passed a function two integers (assuming they are 4 bytes each) you would likely see a ret 8 within the called function to clean up those two arguments from the stack once returned.


For the cdecl calling convention, the caller is expected to clean up the stack not the callee. So with cdecl functions you will often just see a ret at the end of the function, then immediately after you return execution to the caller you will see a value to be added to the ESP value depending on how many arguments were passed to the function that was just returned from and any other values that were pushed onto the stack during the execution of those functions.