How to return a struct from assembly

Programming, for all ages and all languages.
Post Reply
User avatar
ScropTheOSAdventurer
Member
Member
Posts: 86
Joined: Sun Aug 25, 2013 5:47 pm
Location: Nebraska, USA

How to return a struct from assembly

Post 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.
"Procrastination is the art of keeping up with yesterday."
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: How to return a struct from assembly

Post 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.
User avatar
ScropTheOSAdventurer
Member
Member
Posts: 86
Joined: Sun Aug 25, 2013 5:47 pm
Location: Nebraska, USA

Re: How to return a struct from assembly

Post 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?
"Procrastination is the art of keeping up with yesterday."
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: How to return a struct from assembly

Post 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.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: How to return a struct from assembly

Post 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).
User avatar
ScropTheOSAdventurer
Member
Member
Posts: 86
Joined: Sun Aug 25, 2013 5:47 pm
Location: Nebraska, USA

Re: How to return a struct from assembly

Post 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 :evil: ). @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) :oops: . So where the returned struct is might not even be on the stack! Interesting. Thanks!
"Procrastination is the art of keeping up with yesterday."
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: How to return a struct from assembly

Post 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.
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: How to return a struct from assembly

Post 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. :roll:
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: How to return a struct from assembly

Post 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. :roll:
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.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: How to return a struct from assembly

Post 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. :roll:
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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
ScropTheOSAdventurer
Member
Member
Posts: 86
Joined: Sun Aug 25, 2013 5:47 pm
Location: Nebraska, USA

Re: How to return a struct from assembly

Post by ScropTheOSAdventurer »

Yeah, I did compile it with optimizations enabled.
"Procrastination is the art of keeping up with yesterday."
Post Reply