The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: rags on June 11, 2007, 01:26:00 PM

Title: ret and retn usage
Post by: rags on June 11, 2007, 01:26:00 PM
I was looking over the source code for RAGrid trying to understand how Ketil wrote it, when I saw the usage of the retn mneumonic in a proceedure.

It was used like it is in this example:


SomeProc PROC arg1:dword

    mov eax, arg1

    .if eax == 5
         call DoThis
         add eax, 5

   .elseif eax == 6
        call DoThat
        sub eax, 6
    .else
       call DoNothingMuch
    .endif

ExitProc:
    ret

DoThis:
    shl eax, 1
    retn

DoThat:
    shl eax, 2
    retn

DoNothingMuch:
    xor eax, eax
    retn

SomeProc endp




Why the use retn for the return from the calls to subroutines within the proc, and not ret ?

Thanks,
    Rags
Title: Re: ret and retn usage
Post by: hutch-- on June 11, 2007, 01:46:23 PM
I think you will find that it will work with RET as well as it is contained within a MASM procedure. Its one of the two opcodes used in flat memory model for RET, C3h is a bare near return where C2h is a POP of the stack and a RET.
Title: Re: ret and retn usage
Post by: Tedd on June 11, 2007, 02:25:18 PM
"ret" is really a built-in macro - if it's inside a function that has arguments then it will be substituted with "ret 4*<num_args>" which will remove the args from the stack before returning; and "leave" will be inserted before the return, to cleanup the stackframe.
Whereas "retn" is the bare 'near return' opcode, and doesn't do this substitution.

It's not usually a good idea to mix the two unless you really know what you're doing :wink


In that code, 'DoThis', 'DoThat', 'DoNothingMuch' are built like nested functions - they're called to, and upon the 'retn', we return back to the point after they were called, which then does its stuff and eventually hits the actual 'ExitProc:' return. Using "ret" for these cases would cause them to clean up the stack as if they were the last exit point, which they're not - so 'retn' is used to avoid this cleanup (which is undesired, but would be produced as we're still inside the 'SomeProc' function.)
Title: Re: ret and retn usage
Post by: evlncrn8 on June 11, 2007, 02:31:15 PM
that code uses nested procs within the code...

the retn puts a 0xC3 in, if the proc itself used locals, params and whatever
it typically has a 0xC2 0xXX or whatnot...

advantage of nested procs - they can access the local variables because of the ebp frame
disadvantage of nested procs - if u get a bug, finding it can be time consuming and tricky
Title: Re: ret and retn usage
Post by: rags on June 11, 2007, 11:09:07 PM
thanks for the replies, I now understand the difference better.
rags