Hello, i'm developing a simple assembly (AT&T) program as exercise in preparation of an exam and i have a problem:

I need to pass 4 return values of a function using the stack. I know that after the "call", %esp points to the return address that will be used from the "ret". I've tried to pop that value from the stack, push my return values and then push the return address again just before the "ret" but it doesn't work.

Can i have an help please? Where do i need to put those values in the stack? And how do i have to manipulate the %esp or %ebp?


val1 = func( &apple, &bat, &cat, &dog )

The address of apple, bat, cat, and dog are now on the stack.
here's one method!

ZZ equ ????       ; I forget the actual number to use try 8?
Check your address of those arguments, then in debugger
to align them. Dependent upon memory model, method of stack protection etc. that ZZ value has to be set accordingly!

        mov ebx, [ebp + ZZ + 0]       ; Save apple
       mov [ebx], eax

        mov ebx, [ ebp + ZZ + 4]
        mov [ebx], eax

        mov ebx, [ ebp + ZZ + 8]
        mov [ebx], eax

        mov ebx, [ ebp + ZZ + 12]
        mov [ebx], eax

      return eax

ESP points to the current top of stack,
PUSH & POP implicity decrement and increment ESP.
Right upon entering your function ESP points to a
DWORD containing the return address (address
of the instruction past the CALL).
RET will pop the DWORD off the stack (according
to the value of ESP so make sure ESP points
to the return address) to implicitly
change the contents of IP.
If you reserve space on the stack for a couple
of DWORDs (if you need to return two values)
before you CALL your function, to do so
simply subtract 8 from ESP before calling your function.
[ ] <-------Bottom of stack | Higher Address
[ ] Space 2
[ ] Space 1
[ ] Return Address | Lower Address
Then copy ESP into EBP to index into the stack,
once in your function to place the return values on
the stack.
To copy into Space 1 use movl src,4(%ebp)
To copy into Space 2 use movl src,8(%ebp)

push bp
mov bp,sp
mov [bp-2], ax            ;first return valuse
mov [bp-4], dx            ;second return value
pop bp

After return
mov bp,sp
mov ax, [bp-6]
mov dx, [bp-8]          ;these need adjusting if you push more than
                       ;just bp, or if you are using eip rather than ip

Of course it would be a whole lot easier to use registers to return
a value; or do as Wildgoose says, and push the address of variables onto the stack if you want to return more than one.

mathematician your right you can just place the address
of the memory variables on the stack, this would be
a good method.
AT&T syntax goes: mnemonic src,dest

pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%ebx ; move first address on stack into %ebx
movl 0x122,(%ebx)  ; alter data pointed to

16-bit example:

push bp
mov bp,sp
mov bx,[bp+4]
mov word [bx],0x122