I'm trying to understand how a function call works in assembly language. My understanding is, after calling a function, the callee
function first uses a function prologue
to create a new stack frame for itself.
Function prologue:
push %rbp
mov %rsp,%rbp
However, I have the following example code,
void printNumber(int nbr){
printf("%d\n", nbr);
}
void myFunction(void (*f)(int)){
for(int i = 0; i < 5; i++){
(*f)(i);
}
}
int main(void){
myFunction(printNumber);
return (0);
}
Disassembly of all the function is :
>>> disass main
Dump of assembler code for function main:
0x000000000040057b <+0>: sub $0x8,%rsp
0x000000000040057f <+4>: mov $0x400526,%edi
0x0000000000400584 <+9>: callq 0x400549 <myFunction>
0x0000000000400589 <+14>: mov $0x0,%eax
0x000000000040058e <+19>: add $0x8,%rsp
0x0000000000400592 <+23>: retq
End of assembler dump.
>>> disass myFunction
Dump of assembler code for function myFunction:
0x0000000000400549 <+0>: sub $0x28,%rsp
0x000000000040054d <+4>: mov %rdi,0x8(%rsp)
0x0000000000400552 <+9>: movl $0x0,0x1c(%rsp)
0x000000000040055a <+17>: jmp 0x40056e <myFunction+37>
0x000000000040055c <+19>: mov 0x1c(%rsp),%edx
0x0000000000400560 <+23>: mov 0x8(%rsp),%rax
0x0000000000400565 <+28>: mov %edx,%edi
0x0000000000400567 <+30>: callq *%rax
0x0000000000400569 <+32>: addl $0x1,0x1c(%rsp)
0x000000000040056e <+37>: cmpl $0x4,0x1c(%rsp)
0x0000000000400573 <+42>: jle 0x40055c <myFunction+19>
0x0000000000400575 <+44>: nop
0x0000000000400576 <+45>: add $0x28,%rsp
0x000000000040057a <+49>: retq
End of assembler dump.
>>> disass printNumber
Dump of assembler code for function printNumber:
0x0000000000400526 <+0>: sub $0x18,%rsp
0x000000000040052a <+4>: mov %edi,0xc(%rsp)
0x000000000040052e <+8>: mov 0xc(%rsp),%eax
0x0000000000400532 <+12>: mov %eax,%esi
0x0000000000400534 <+14>: mov $0x400624,%edi
0x0000000000400539 <+19>: mov $0x0,%eax
0x000000000040053e <+24>: callq 0x400400 <printf@plt>
0x0000000000400543 <+29>: nop
0x0000000000400544 <+30>: add $0x18,%rsp
0x0000000000400548 <+34>: retq
End of assembler dump.
None of the functions disassemblies shows function prologue. This brings to my questions,
- Why
function prologue
is not showing in function disassembly? - In all the function disassemblies, my understanding is
sub
instruction is allocating some space in the stack for local variables and sub-routine.- In main function, It only has one subroutine
myFunction(printNumber);
. Therefore, I guesssub $0x8,%rsp
is being used to allocate 8-byte stack memory for sub-routine call. - But, in other two functions, why allocating more stack memory? For example, function
printNumber
took oneint
type argument. Then what allocating24-bytes
in the stack?
- In main function, It only has one subroutine
Update: I have compiled with following,
gcc -O0 -g -Wall -Wextra -pedantic -fomit-frame-pointer -o function_as_paprameter function_as_paprameter.c