I study how structures are transferred to functions and returned from functions. Such code:
#include <stdio.h> struct point { int x; int y; }; struct point makepoint(int x, int y) { struct point tmp; tmp.x = x; tmp.y = y; return tmp; } int main() { struct point pt = makepoint(1, 2); struct point *pp = &pt; return 0; } Here are the disassembled listings of both functions. I will try to comment on them.
main function:
0x080483e2 <+0>: push ebp 0x080483e3 <+1>: mov ebp,esp 0x080483e5 <+3>: sub esp,0x10 ; выделили 16 байт для структуры 0x080483e8 <+6>: lea eax,[ebp-0xc] 0x080483eb <+9>: push 0x2 0x080483ed <+11>: push 0x1 0x080483ef <+13>: push eax ; передали адрес структуры скрытым параметром 0x080483f0 <+14>: call 0x80483bb <makepoint> 0x080483f5 <+19>: add esp,0x8 ; освобождаем только 8 байт, остальные заняты структурой 0x080483f8 <+22>: lea eax,[ebp-0xc] 0x080483fb <+25>: mov DWORD PTR [ebp-0x4],eax 0x080483fe <+28>: mov eax,0x0 0x08048403 <+33>: leave 0x08048404 <+34>: ret Note that the main function allocates 16 bytes in the stack, but when the stack is aligned, only 8 bytes are freed. The remaining 8 bytes are occupied by the structure.
makepoint function:
0x080483bb <+0>: push ebp 0x080483bc <+1>: mov ebp,esp 0x080483be <+3>: sub esp,0x10 0x080483c1 <+6>: mov eax,DWORD PTR [ebp+0xc] 0x080483c4 <+9>: mov DWORD PTR [ebp-0x8],eax 0x080483c7 <+12>: mov eax,DWORD PTR [ebp+0x10] 0x080483ca <+15>: mov DWORD PTR [ebp-0x4],eax 0x080483cd <+18>: mov ecx,DWORD PTR [ebp+0x8] 0x080483d0 <+21>: mov eax,DWORD PTR [ebp-0x8] 0x080483d3 <+24>: mov edx,DWORD PTR [ebp-0x4] 0x080483d6 <+27>: mov DWORD PTR [ecx],eax 0x080483d8 <+29>: mov DWORD PTR [ecx+0x4],edx 0x080483db <+32>: mov eax,DWORD PTR [ebp+0x8] 0x080483de <+35>: leave 0x080483df <+36>: ret 0x4 Look again at this place in main :
0x080483eb <+9>: push 0x2 0x080483ed <+11>: push 0x1 0x080483ef <+13>: push eax 0x080483f0 <+14>: call 0x80483bb <makepoint> Taking into account the return address and saved ebp , the address of the structure (push eax) will be shifted to 3 dvds, this is 0xC bytes, and, apparently, we see the address to the address of the structure here:
mov eax,DWORD PTR [ebp+0xc] What happens next in makepoint ? It is difficult to understand this code.
In general, as I understand it: when a function transfers a structure to another function, or when another function returns a structure, the calling function itself allocates space for this structure. Then it transmits only the address of this structure with a hidden parameter.
There is also such a thing as alignment of the structure fields. Can this be observed in the listing? What is the reason for this alignment?