Author Topic: RET n vs POP  (Read 14835 times)

Offline mik3ca

  • Jr. Member
  • *
  • Posts: 30
RET n vs POP
« on: February 18, 2021, 09:13:26 PM »
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: [Select]
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

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: [Select]
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.

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: [Select]
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.

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

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: RET n vs POP
« Reply #1 on: February 18, 2021, 09:22:49 PM »
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).
My graphics card database: www.gpuzoo.com