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
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