Jump to content
  • Advertisement
Sign in to follow this  

OMG x86 stack manipulation!!!

This topic is 5046 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I can do it with the ARM, and I know theoretically it's common practice, but I have no idea how to do it on the x86. I'm workin with a 16bit architecture here (legacy code is like that), so bear with me. I want to pass four values to a subroutine on the stack. So I do this
        PUSH    param1
        PUSH    param2
        PUSH    param3
        PUSH    param4

    ; note that each parameter is 2 bytes
now we got into the subroutine (woohoo!) and in the subroutine I backup my registers, do useful work, restore my registers, then kill the value parameters.

        PUSH    AX
        PUSH    BX
        PUSH    CX

    ; do useful work HERE

        POP     CX
        POP     BX
        POP     AX

        RET     8       ; blow the value params off the stack
My question is this: how do I access my parameters?! On the ARM I can just treat the stack like an array that goes backwards, so it'd be like... LDR R1, [SP, #20] ...which says "20 bytes into the stack (added to the Stack Pointer) is where we'll find the first of our parameters...now load that into register R1" So what is the equivalent x86 notation? Anybody know? Thanks =)

Share this post

Link to post
Share on other sites

push param1 ; NOTE: in Method 2 I assume these to be 2 byte values.
push param2
call mySub

; Method 1
pop ax ; Pop return address.
pop bx ; Pop param2
pop dx ; Pop param1
push ax ; Push return address back on stack

; Do useful work here.


; Method 2
; Setup stack frame.
push bp ; Save for later use.
mov bp, si ; Used to access parameters and local vars.

add si, x ; where x is the amount of bytes to reserve for locals variables (if any).

; Save registers.
push ax
push bx
push cx
push dx

mov ax, [bp+4] ; copy param1 to the ax register.
mov bx, [bp+2] ; copy param2 to the bx register.

; Do whatever work.

; Restore registers.
pop dx
pop cx
pop bx
pop ax

; Clean up stack frame.
mov si, bp ; clear local variables from stack.
add si, 4 ; clear 4 bytes (the params) from stack.
pop bp


Method 1 is easier but does not allow for saving the registers (without some extra work), Method 2 is "the way to do it" though I may have made some mistakes.
I think that code will work, not entirely certain, I may have missed something here or there..

Anyway, hope that helps.

EDIT: Found this, thought it may be of use: clicky

Share this post

Link to post
Share on other sites
that is GREAT man...that appears to be, in x86 code, precisely the way I'd do it on the ARM. Thank you thank you thank you =) I'll let you know how well it works!

Share this post

Link to post
Share on other sites
Original post by issch

various code

which could also be written for 286 and above.

enter x,0 ;create stack frame, reserve x bytes for locals
mov ax, [bp+4] ;last variable passed, left most variable for C calling convention.
xor ax, ax ;return code 0
leave ;destroy stack frame

Share this post

Link to post
Share on other sites
Original post by Washu

enter x,0

What does the second parameter to enter do?
Just thought I may as well update my knowledge while im at it :-)

Share this post

Link to post
Share on other sites
proc your_procedure_name
ARG arg1:WORD,arg2:WORD,....,argN:WORD
enter 0,0
;do some stuff
ret 2xN;2 times the number of params you used

where enter 0,0 does the
push bp
mov bp,sp
and leave does
mov sp,bp
pop bp

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!