NASM Forum > Using NASM

RET n vs POP

(1/1)

mik3ca:
I'm trying to figure out if when returning from a function if I should pop variables that I pushed, or if I should use a parameter with RET or both.

I'll give an example. When I normally code, I do something like this:


--- Code: ---somesegment dw 123h
someoffset dw 123h

somefunction:
push ES
push DI
mov AX,1234h
mov ES,[CS:somesegment]
mov DI,[CS:someoffset]
int 0AAh
pop DI
pop ES
ret

--- End code ---

No this code shouldn't be executed as-is because I did not setup correct segment and offset values. This code is meant to demonstrate that I was protecting sensitive registers and that the interrupt needed a string stored at ES:DI for processing.

But I'm wondering, should I also include a parameter at the end of RET? so my code becomes this?


--- Code: ---somesegment dw 123h
someoffset dw 123h

somefunction:
push ES
push DI
mov AX,1234h
mov ES,[CS:somesegment]
mov DI,[CS:someoffset]
int 0AAh
pop DI
pop ES
ret 4 ;added 4 because the size of DI and ES (both pushed onto stack) variables combined is 4.

--- End code ---

Then again, when I read stuff online, one could probably get away with the following code but to me it doesn't make sense. Have a look:


--- Code: ---somesegment dw 123h
someoffset dw 123h

somefunction:
push ES
push DI
mov AX,1234h
mov ES,[CS:somesegment]
mov DI,[CS:someoffset]
int 0AAh
ret 4 ;added 4 because the size of DI and ES (both pushed onto stack) variables combined is 4.

--- End code ---

So which is best?
Should I push/pop variables with return including number?
Should I push only and return including number?
Should I continue my way and push and pop variables and use no number for return?

I know the variables are called registers in assembly but I say variables because its easier to understand. Please advise.

Thanks

debs3759:
The first code example looks like the only correct way to me. You restore the original values that you had saved. ret 4 would then alter the stack again, which would leave it in a different state to what it was before the call. The third example leaves ES and DI with different values to before the call, which could break other code.

ret n is only useful if you had passed arguments on the stack, and need to clean it up (such as, for example, the case of routines like printf).

Navigation

[0] Message Index

Go to full version