The following examples are for illustration only. They have not been optimized. The examples assume that you are familiar with programming in assembler. Note that, in the examples, the stack grows toward the bottom of the page, and ESP always points to the top of the stack.
For the call
m = func(a,b,c);
a, b, and c are 32-bit integers and func has two local variables, x and y (both 32-bit integers).
The stack for the call to func would look like this:

The instructions used to create this activation record on the stack look like this on the calling side:
PUSH c
PUSH b
PUSH a
CALL _func
.
.
ADD ESP, 12 ; Cleaning up the parameters
.
.
MOV m, EAX
.
.
For the callee, the code looks like this:
_func PROC
PUSH EBP
MOV EBP, ESP ; Allocating 8 bytes of storage
SUB ESP, 08H ; for two local variables.
PUSH EDI ; These would only be
PUSH ESI ; pushed if they were used
PUSH EBX ; in this function.
.
.
MOV EAX, [EBP - 8] ; Load y into EAX
MOV EBX, [EBP + 12] ; Load b into EBX
.
.
XOR EAX, EAX ; Zero the return value
POP EBX ; Restore the saved registers
POP ESI
POP EDI
LEAVE ; Equivalent to MOV ESP, EBP
; POP EBP
RET
_func ENDP
The saved register set is EBX, ESI, and EDI. In the case where the structure is passed as a value parameter and the size of the structure is 5, 6, 7, or more than 8 bytes in size, the address to place the return values is passed as a hidden parameter, and the address passed back in EAX.
struct test_tag {
int a;
int some_array[100];
} test_struct;
struct test_tag __cdecl test_function(struct test_tag test_parm)
{
test_parm.a = 42;
return test_parm;
}
int main(void)
{
test_struct = test_function(test_struct);
return test_struct.a;
}
The code generated for the above example would be:
_test_function PROC PUSH EDI PUSH ESI MOV DWORD PTR [ESP+0cH], 02aH ; test_parm.a MOV EAX, [ESP+08H] ; Get the target of the return value MOV EDI, EAX ; Value LEA ESI, [ESP+0cH] ; test_parm REP MOVSD POP ESI POP EDI RET _test_function ENDP PUBLIC ?main ?main PROC PUSH EBP MOV EBP, ESP PUSH ESI PUSH EDI SUB ESP, 0194H ; Adjust the stack pointer MOV EDI, ESP MOV ESI, OFFSET FLAT:_test_struct MOV ECX, 065H REP MOVSD ; Copy the parameter PUSH OFFSET FLAT:_test_struct ; Push the address of the target CALL _TEST_FUNCTION ADD ESP,0198H MOV EAX, DWORD PTR _test_struct ; Take care of the return POP EDI ; from main POP ESI LEAVE RET ?main ENDP |