Page 1 of 1
How to return a struct from assembly
Posted: Wed May 28, 2014 7:52 pm
by ScropTheOSAdventurer
Ok, so I was curious as to how you return a struct from an assembly standpoint. So I compiled this code:
Code: Select all
#include <stdint-gcc.h>
typedef struct {
uint32_t lolz;
uint32_t loler;
} teststruct;
teststruct returnval;
teststruct thetestfunction(void ) {
returnval.lolz = 4;
returnval.loler = 8;
return returnval;
};
Then disassembled it, so the thetestfunction looked like this:
Code: Select all
00000000 <thetestfunction>:
0: 8b 44 24 04 mov 0x4(%esp),%eax
4: c7 05 00 00 00 00 04 movl $0x4,0x0
b: 00 00 00
e: c7 05 04 00 00 00 08 movl $0x8,0x4
15: 00 00 00
18: 8b 15 00 00 00 00 mov 0x0,%edx
1e: 8b 0d 04 00 00 00 mov 0x4,%ecx
24: 89 10 mov %edx,(%eax)
26: 89 48 04 mov %ecx,0x4(%eax)
29: c2 04 00 ret $0x4
So apparently space is created on the stack right below the returning address. However, I am left scratching my head at the "ret $0x4" instruction; why does it need to clean up 32 bits on the stack? Is this even part of the "System V" ABI or is it just dependent on how GCC does it? I'm going to look.
Re: How to return a struct from assembly
Posted: Wed May 28, 2014 7:58 pm
by sortie
Use stdint.h instead of stdint-gcc.h btw.
Yes, this should be covered by the system V abi. You are right to just do the same as the compiler though, as a quick test reveals what the compiler would do. You may find the gcc -S option useful btw.
Re: How to return a struct from assembly
Posted: Wed May 28, 2014 8:04 pm
by ScropTheOSAdventurer
For some reason, the stdint.h I got causes errors, and I was too lazy to see why, so I just used stdint-gcc.h instead. Thanks.
Edit: However, why is it cleaning up four extra bytes off the stack?
Re: How to return a struct from assembly
Posted: Wed May 28, 2014 8:52 pm
by thepowersgang
Possibly because this code was compiled with mingw targeting win32, and hence uses a callee cleanup calling convention (where the called function is responsible for removing arguments from the stack) - Working from memory here, but I think that 'ret imm16' pops the return address, then adds the argument to esp.
Re: How to return a struct from assembly
Posted: Wed May 28, 2014 8:59 pm
by alexfru
The caller is supposed to pass (as the very first parameter, before the formal parameters, if any) the address of the structure receptacle(?) when calling a function that returns a structure. And that called function is supposed to store the returned structure at that address. Look at the disassembly, thetestfunction does exactly that. So, there's one implicit parameter. ret removes it from the stack according to the function calling convention in use (the caller could do that as well, btw).
Re: How to return a struct from assembly
Posted: Wed May 28, 2014 10:15 pm
by ScropTheOSAdventurer
I am not using MinGW. Right now I am using a GCC cross compiler on Cygwin (my flash drive with Lubuntu on it got overheated and burned out
). @alexfru, that does make some sense. I will look at it.
EDIT: I see now; sorry about that; getting used to AT&T syntax. I thought eax was just their way of skipping the return address (well, it did, but it did more)
. So where the returned struct is might not even be on the stack! Interesting. Thanks!
Re: How to return a struct from assembly
Posted: Thu May 29, 2014 2:56 am
by Bender
Isn't there a 'LEAVE' (HLL procedure exit) instruction which compilers use? IIRC that does a similar thing, although you do have to set up ESP and EBP before the procedure. (ENTER?) Not sure.
Re: How to return a struct from assembly
Posted: Thu May 29, 2014 6:13 am
by Gigasoft
Isn't there a 'LEAVE' (HLL procedure exit) instruction which compilers use? IIRC that does a similar thing, although you do have to set up ESP and EBP before the procedure. (ENTER?) Not sure.
Yeah, I think I may have overheard some rumour about a "leave" instruction, some years ago at a pub. Could be a hoax, though. Man, if only the x86 instruction set was documented. Then we wouldn't have to reverse engineer it by trial and error. Intel should really write up a manual for it someday.
Re: How to return a struct from assembly
Posted: Thu May 29, 2014 6:48 am
by alexfru
Gigasoft wrote:Man, if only the x86 instruction set was documented. Then we wouldn't have to reverse engineer it by trial and error. Intel should really write up a manual for it someday.
What??? It is documented. There are omissions and typos, though, as usual. But you can crosscheck intel and AMD docs, also go back to the 80386 and 80486 manuals, where some things are documented a tad better. For most things no reverse engineering is needed.
Re: How to return a struct from assembly
Posted: Thu May 29, 2014 7:06 am
by Brendan
Hi,
alexfru wrote:Gigasoft wrote:Man, if only the x86 instruction set was documented. Then we wouldn't have to reverse engineer it by trial and error. Intel should really write up a manual for it someday.
What??? It is documented. There are omissions and typos, though, as usual. But you can crosscheck intel and AMD docs, also go back to the 80386 and 80486 manuals, where some things are documented a tad better. For most things no reverse engineering is needed.
I'd expect Gigasoft's post is purely sarcasm and wasn't intended to be taken literally.
Bender wrote:Isn't there a 'LEAVE' (HLL procedure exit) instruction which compilers use?
There is a LEAVE instruction, but (like ENTER, LOOP, PUSHAD, etc) it's typically implemented as micro-code in modern 80x86 CPUs and is slower than an equivalent sequence of simpler instructions, so compilers tend to avoid it and use the simpler instructions instead (possibly even when code size is more important and the smaller/slower complex instruction would be better).
Cheers,
Brendan
Re: How to return a struct from assembly
Posted: Thu May 29, 2014 10:05 am
by ScropTheOSAdventurer
Yeah, I did compile it with optimizations enabled.