assemblyx86parameter-passingstack-memorystack-frame

Get parameter value in Assembly


I'm a beginner in Assembly, so I'm confused about passing parameters in function call from another function. Specifically I have code like this: Assembly:

bar:
pushl   %ebp
movl    %esp, %ebp
subl    $16, %esp
movl    $555, -4(%ebp)
movl    12(%ebp), %eax
movl    8(%ebp), %edx
addl    %edx, %eax
movl    %eax, -8(%ebp)
leave
ret
foo:
pushl   %ebp
movl    %esp, %ebp
subl    $8, %esp
movl    $222, 4(%esp)
movl    $111, (%esp)
call    bar
leave
ret

original C code:

void
bar(int a, int b)
{
 int x, y;

 x = 555;
 y = a+b;
 }

 void
 foo(void) {
 bar(111,222);
 }

In Assembly code, I don't understand why in foo()

movl $222, 4(%esp)
movl $111, (%esp)
call bar

can again be read by bar():

movl 12(%ebp), %eax
movl 8(%ebp), %edx

I tried to analyze but i still don't understand if esp - 8 bytes in foo() function can be equivalent to the position read in bar() function esp - 16 bytes ? Is offset numbers like 12, 8, 4 related between the two functions? I am really confused about this. If someone explain it to me or give me a specific example to understand this problem, I would be very grateful and appreciated. Thanks


Solution

  • Let's imagine some sample values and track what happens to ESP/EBP. Plus remember that pushing something (including the "push eip" hidden inside call) will decrement ESP.

    bar:  ;ESP=88
    pushl   %ebp    ;ESP=84
    movl    %esp, %ebp   ;EBP=84
    subl    $16, %esp    ;ESP=78
    movl    $555, -4(%ebp)
    movl    12(%ebp), %eax   ;@96->EAX
    movl    8(%ebp), %edx    ;@92->EDX
    addl    %edx, %eax
    movl    %eax, -8(%ebp)
    leave
    ret
    foo:
    pushl   %ebp         ;starting here:
    movl    %esp, %ebp   ;let's assume ESP=100,EBP=100
    subl    $8, %esp     ;ESP=92
    movl    $222, 4(%esp) ;222->96
    movl    $111, (%esp)  ;111->92
    call    bar
    leave
    ret