Lecture 26 - x86-64
Goals
- Look at how functions work on the x86-64 architecture
x86
Before we go any further, I want to bring us back to x86 assembly. I want to get us to the point where we can use assembly as a debugging tool, so I want you to start getting familiar with the dialect that is actually used for our machine.
See the slides for an overview of the registers, addressing modes, and instructions
Let’s take a look at our last example again – this time in x86
$ gcc -c func4.c
$ objdump -Mintel -d -j .text func4.o > func4_x86.s
0000000000000000 <f>:
0: 55 push rbp
1: 48 89 e5 mov rbp,rsp
4: 89 7d ec mov DWORD PTR [rbp-0x14],edi
7: 89 75 e8 mov DWORD PTR [rbp-0x18],esi
a: 89 55 e4 mov DWORD PTR [rbp-0x1c],edx
d: 89 4d e0 mov DWORD PTR [rbp-0x20],ecx
10: 44 89 45 dc mov DWORD PTR [rbp-0x24],r8d
14: 44 89 4d d8 mov DWORD PTR [rbp-0x28],r9d
18: 8b 55 ec mov edx,DWORD PTR [rbp-0x14]
1b: 8b 45 e8 mov eax,DWORD PTR [rbp-0x18]
1e: 01 c2 add edx,eax
20: 8b 45 e4 mov eax,DWORD PTR [rbp-0x1c]
23: 01 c2 add edx,eax
25: 8b 45 e0 mov eax,DWORD PTR [rbp-0x20]
28: 01 c2 add edx,eax
2a: 8b 45 dc mov eax,DWORD PTR [rbp-0x24]
2d: 01 c2 add edx,eax
2f: 8b 45 d8 mov eax,DWORD PTR [rbp-0x28]
32: 01 c2 add edx,eax
34: 8b 45 10 mov eax,DWORD PTR [rbp+0x10]
37: 01 c2 add edx,eax
39: 8b 45 18 mov eax,DWORD PTR [rbp+0x18]
3c: 01 d0 add eax,edx
3e: 89 45 fc mov DWORD PTR [rbp-0x4],eax
41: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
44: 5d pop rbp
45: c3 ret
0000000000000046 <main>:
46: 55 push rbp
47: 48 89 e5 mov rbp,rsp
4a: 48 83 ec 20 sub rsp,0x20
4e: 89 7d ec mov DWORD PTR [rbp-0x14],edi
51: 48 89 75 e0 mov QWORD PTR [rbp-0x20],rsi
55: 6a 07 push 0x7
57: 6a 06 push 0x6
59: 41 b9 05 00 00 00 mov r9d,0x5
5f: 41 b8 04 00 00 00 mov r8d,0x4
65: b9 03 00 00 00 mov ecx,0x3
6a: ba 02 00 00 00 mov edx,0x2
6f: be 01 00 00 00 mov esi,0x1
74: bf 00 00 00 00 mov edi,0x0
79: e8 00 00 00 00 call 7e <main+0x38>
7e: 48 83 c4 10 add rsp,0x10
82: 89 45 fc mov DWORD PTR [rbp-0x4],eax
85: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
88: c9 leave
89: c3 ret
We can see that it pretty much follows the same pattern as the ARM assembly did
Some differences beyond syntax and instructions:
- there is no LR.
callalways pushes the return address on the stack and ret always pops it - for
f, the compiler didn’t both updating the stack pointer - x86 can handle six parameters in registers before resorting to memory
Mechanical level
vocabulary
Skills