I am not quite familiar with assembly code. Excuse me if this question is naive.
I have a simple C program:
int f1(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9)
{
int c = 3;
int d = 4;
return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + c + d;
}
int main(int argc, char** argv)
{
f1(1, 2, 3, 4, 5, 6, 7, 8, 9);
}
I compiled it into an elf64-x86-64 and get below disassembly code:
f1():
0000000000000000 <f1>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d ec mov %edi,-0x14(%rbp) ; 1
7: 89 75 e8 mov %esi,-0x18(%rbp) ; 2
a: 89 55 e4 mov %edx,-0x1c(%rbp) ; 3
d: 89 4d e0 mov %ecx,-0x20(%rbp) ; 4
10: 44 89 45 dc mov %r8d,-0x24(%rbp) ; 5
14: 44 89 4d d8 mov %r9d,-0x28(%rbp) ; 6
18: c7 45 f8 03 00 00 00 movl $0x3,-0x8(%rbp) ; c = 3
1f: c7 45 fc 04 00 00 00 movl $0x4,-0x4(%rbp) ; d = 4
26: 8b 45 e8 mov -0x18(%rbp),%eax ;2
29: 8b 55 ec mov -0x14(%rbp),%edx ; 1
2c: 01 c2 add %eax,%edx
2e: 8b 45 e4 mov -0x1c(%rbp),%eax ;3
31: 01 c2 add %eax,%edx
33: 8b 45 e0 mov -0x20(%rbp),%eax ;4
36: 01 c2 add %eax,%edx
38: 8b 45 dc mov -0x24(%rbp),%eax ;5
3b: 01 c2 add %eax,%edx
3d: 8b 45 d8 mov -0x28(%rbp),%eax ; 6
40: 01 c2 add %eax,%edx
42: 8b 45 10 mov 0x10(%rbp),%eax ;7
45: 01 c2 add %eax,%edx
47: 8b 45 18 mov 0x18(%rbp),%eax ; 8
4a: 01 c2 add %eax,%edx
4c: 8b 45 20 mov 0x20(%rbp),%eax ; 9
4f: 01 c2 add %eax,%edx
51: 8b 45 f8 mov -0x8(%rbp),%eax ; c =3
54: 01 c2 add %eax,%edx
56: 8b 45 fc mov -0x4(%rbp),%eax ; d =4
59: 01 d0 add %edx,%eax
5b: 5d pop %rbp
5c: c3 retq
main():
000000000000005d <main>:
5d: 55 push %rbp
5e: 48 89 e5 mov %rsp,%rbp
61: 48 83 ec 30 sub $0x30,%rsp
65: 89 7d fc mov %edi,-0x4(%rbp)
68: 48 89 75 f0 mov %rsi,-0x10(%rbp)
6c: c7 44 24 10 09 00 00 movl $0x9,0x10(%rsp)
73: 00
74: c7 44 24 08 08 00 00 movl $0x8,0x8(%rsp)
7b: 00
7c: c7 04 24 07 00 00 00 movl $0x7,(%rsp)
83: 41 b9 06 00 00 00 mov $0x6,%r9d
89: 41 b8 05 00 00 00 mov $0x5,%r8d
8f: b9 04 00 00 00 mov $0x4,%ecx
94: ba 03 00 00 00 mov $0x3,%edx
99: be 02 00 00 00 mov $0x2,%esi
9e: bf 01 00 00 00 mov $0x1,%edi
a3: b8 00 00 00 00 mov $0x0,%eax
a8: e8 00 00 00 00 callq ad <main+0x50>
ad: c9 leaveq
ae: c3 retq
It seems there are some holes on the stack when passing parameters from main()
to f1()
:
My questions are:
Why need these holes?
And why do we need below 2 lines of assembly? If they are meant for context restoring, I don't see any instructions to do that. And the
%rsi
register is NOT even used elsewhere. Why still save%rsi
on stack?
65: 89 7d fc mov %edi,-0x4(%rbp)
68: 48 89 75 f0 mov %rsi,-0x10(%rbp)
- And just came up with one more question, since the args
1 ~ 6
have already been passed via the registers, why move them back to memory at the beginning off1()
?