X86-Procedures Slides
Total Page:16
File Type:pdf, Size:1020Kb
Machine Code: Procedures Return %rax %eax %r8 %r8d Arg 5 %rbx %ebx %r9 %r9d Arg 6 Arg 4 %rcx %ecx %r10 %r10d Arg 3 %rdx %edx %r11 %r11d Arg 2 %rsi %esi %r12 %r12d Arg 1 %rdi %edi %r13 %r13d Stack ptr %rsp %esp %r14 %r14d %rbp %ebp %r15 %r15d Sean Barker 1 Call Stack Stack “Bottom” Increasing Addresses Stack Grows Down Stack Pointer: %rsp Stack “Top” Sean Barker 2 Stack Operations Stack “Bo8om” Stack “Bo;om” Increasing Increasing Addresses Addresses Stack Stack Grows Down Grows Stack Pointer: %rsp Down -8 Stack Pointer: %rsp +8 Stack “Top” Stack “Top” pushq Src popq Dest 1. Decrement %rsp by 8 1. Read (%rsp) to Dest 2. Write Src to (%rsp) 2. Increment %rsp by 8 Sean Barker 3 Procedure Call Example long x = add(3, 5); long add(long x, long y) { doSomething(x); return x + y; } movq $3, %rdi movq $5, %rsi add: callq add movq %rdi, %rax movq %rax, %rdi addq %rsi, %rax callq doSomething ret Sean Barker 4 Procedure Call Return Addresses (1) • Stack 0x130 • Grows 0000000000400540 <foo>: Down • 0x128 • • 0x120 400544: callq 400550 <bar> 400549: mov %rax,(%rbx) • • %rsp 0x120 %rip 0x400544 0000000000400550 <bar>: 400550: mov %rdi,%rax • • 400557: retq Sean Barker 5 Procedure Call Return Addresses (2) • Stack 0x130 • Grows 0000000000400540 <foo>: Down • 0x128 • • 0x120 400544: callq 400550 <bar> 400549: mov %rax,(%rbx) 0x118 0x400549 • • %rsp 0x118 %rip 0x400550 0000000000400550 <bar>: 400550: mov %rdi,%rax • • 400557: retq Sean Barker 6 Procedure Call Return Addresses (3) • Stack 0x130 • Grows 0000000000400540 <foo>: Down • 0x128 • • 0x120 400544: callq 400550 <bar> 400549: mov %rax,(%rbx) 0x118 0x400549 • • %rsp 0x118 %rip 0x400557 0000000000400550 <bar>: 400550: mov %rdi,%rax • • 400557: retq Sean Barker 7 Procedure Call Return Addresses (4) • Stack 0x130 • Grows 0000000000400540 <foo>: Down • 0x128 • • 0x120 400544: callq 400550 <bar> 400549: mov %rax,(%rbx) • • %rsp 0x120 %rip 0x400549 0000000000400550 <bar>: 400550: mov %rdi,%rax • • 400557: retq Sean Barker 8 Passing Data Registers Stack ¢ First 6 arguments %rdi • • • %rsi Arg n %rdx Stack Grows %rcx • • • Down %r8 Arg 8 %r9 Arg 7 ¢ Return value Stack “Top” %rax Sean Barker 9 Stack Frames Older Previous Stack Frame Frames Frame/Base Pointer: %rbp (Optional) x Frame for proc Stack Pointer: %rsp Stack “Top” Sean Barker 10 Call Chain Example foo(…) { • • bar(…) bar(); { • • • • • baz(); } baz(…) • • • { baz(); • • • • • } baz(); • • } Procedure baz() is recursive Sean Barker 11 Stack Frame Allocation (1) Stack foo foo(…) %rbp { foo • %rsp • bar(); • • } call bar Sean Barker 12 Stack Frame Allocation (2) Stack foo(…) foo { bar(…) •{ foo • • • bar • %rbp whobaz();(); • • • • bar %rsp • baz(); } • • • } call baz Sean Barker 13 Stack Frame Allocation (3) Stack foo(…) foo { bar(…) •{ yoofoo baz(…) bar • • • • { whoamI();(); • • • • • baz bar • • amI(); baz(); %rbp } • • • } • baz • %rsp } call baz (recurse) Sean Barker 14 Stack Frame Allocation (4) Stack foo(…) foo { bar(…) •{ yoofoo baz(…) bar • • • • { whoamI();(); • baz(…) • • • • baz bar • { • amI(); baz();• } • • • • } • baz baz • baz(); } • %rbp • baz } %rsp call baz (recurse) Sean Barker 15 Stack Frame Allocation (5) Stack foo(…) foo { bar(…) •{ yoofoo baz(…) bar • • • • { whoamI();(); • baz(…) • • • • baz bar • { • amI(); baz(…) baz();• } • • • • { • baz baz } baz();• • • } • • baz(); baz baz } • • } %rbp baz return %rsp (base case) Sean Barker 16 Stack Frame Allocation (6) Stack foo(…) foo { bar(…) •{ yoofoo baz(…) bar • • • • { whoamI();(); • baz(…) • • • • baz bar • { • amI(); baz();• } • • • • } • baz baz • baz(); } • %rbp • baz baz } %rsp return (unwinding recursion) Sean Barker 17 Stack Frame Allocation (7) Stack foo(…) foo { bar(…) •{ yoofoo baz(…) bar • • • • { whoamI();(); • • • • • baz bar • • amI(); baz(); %rbp } • • • } • baz baz • %rsp } baz return (unwinding recursion) Sean Barker 18 Stack Frame Allocation (8) Stack foo(…) foo { bar(…) •{ yoofoo • • • bar • %rbp whobaz();(); • • • • baz bar • baz(); %rsp } • • • } baz call baz baz Sean Barker 19 Stack Frame Allocation (9) Stack foo(…) foo { bar(…) •{ yoofoo baz(…) bar • • • • { whoamI();(); • • • • • baz baz bar • • amI(); baz(); %rbp } • • • } • baz baz • %rsp } baz return (base case) Sean Barker 20 Stack Frame Allocation (10) Stack foo(…) foo { bar(…) •{ yoofoo • • • bar • %rbp whobaz();(); • • • • baz baz bar • baz(); %rsp } • • • } baz return baz Sean Barker 21 Stack Frame Allocation (11) Stack foo foo(…) %rbp { yoofoo • bar %rsp • bar(); baz baz • • } baz return baz Sean Barker 22 Caller vs. Callee (1) Stack foo(…) foo { bar(…) •{ foo Caller frame • • • bar • %rbp whobaz();(); • • • • bar Callee frame • baz(); %rsp } • • • } foo is the caller bar is the callee Sean Barker 23 Caller vs. Callee (2) Stack foo(…) foo { bar(…) •{ yoofoo baz(…) bar • • • • { whoamI();(); • • • • • baz bar Caller frame • • amI(); baz(); %rbp } • • • } • baz Callee frame • %rsp } bar is the caller baz is the callee Sean Barker 24 Stack Frame Components Older Stack Frames Caller Frame Arguments 7+ Frame pointer Return Addr %rbp (optional) Saved Registers + Local Callee Variables Frame Argument Stack pointer Build %rsp (optional) Stack “Top” Sean Barker 25 Using the Stack (1) long incr(long* p, long val) { long x = *p; long y = x + val; *p = y; return x; } incr: Register Use(s) movq (%rdi), %rax addq %rax, %rsi %rdi Argument p movq %rsi, (%rdi) %rsi Argument val, y ret %rax x, Return value Sean Barker 26 Using the Stack (2) Initial Stack Structure long foo() { long v1 = 15213; long v2 = incr(&v1, 3000); . caller frame return v1+v2; (e.g., main) } Rtn address %rsp foo: subq $16, %rsp Resulting Stack Structure movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi . caller frame call incr addq 8(%rsp), %rax (e.g., main) addq $16, %rsp Rtn address ret 15213 %rsp+8 callee frame Unused %rsp (foo) Sean Barker 27 Using the Stack (3) Stack Structure long foo() { long v1 = 15213; long v2 = incr(&v1, 3000); . caller frame return v1+v2; } (e.g., main) Rtn address 15213 %rsp+8 callee frame Unused %rsp (foo) foo: subq $16, %rsp movq $15213, 8(%rsp) Register Use(s) movl $3000, %esi %rdi &v1 leaq 8(%rsp), %rdi call incr %rsi 3000 addq 8(%rsp), %rax addq $16, %rsp ret Sean Barker 28 Using the Stack (4) Stack Structure (a<er incr return) long foo() { long v1 = 15213; long v2 = incr(&v1, 3000); . caller frame return v1+v2; (e.g., main) } Rtn address 18213 %rsp+8 callee frame Unused %rsp (foo) foo: subq $16, %rsp movq $15213, 8(%rsp) Register Use(s) movl $3000, %esi %rdi &v1 leaq 8(%rsp), %rdi call incr %rsi 3000 addq 8(%rsp), %rax addq $16, %rsp incr: ret movq (%rdi), %rax addq %rax, %rsi movq %rsi, (%rdi) ret Sean Barker 29 Using the Stack (5) Stack Structure long foo() { long v1 = 15213; . caller frame long v2 = incr(&v1, 3000); (e.g., main) return v1+v2; Rtn address } 18213 %rsp+8 callee frame Unused %rsp (foo) foo: subq $16, %rsp Register Use(s) movq $15213, 8(%rsp) %rax Return value movl $3000, %esi leaq 8(%rsp), %rdi Updated Stack Structure call incr addq 8(%rsp), %rax addq $16, %rsp . caller frame ret (e.g., main) Rtn address %rsp Sean Barker 30 Using the Stack (6) Updated Stack Structure long foo() { long v1 = 15213; long v2 = incr(&v1, 3000); . caller frame return v1+v2; } (e.g., main) Rtn address %rsp foo: subq $16, %rsp Register Use(s) movq $15213, 8(%rsp) %rax Return value movl $3000, %esi leaq 8(%rsp), %rdi Final Stack Structure call incr addq 8(%rsp), %rax addq $16, %rsp . ret %rsp Sean Barker 31 Stack Frame Components Older Stack Frames Caller Frame Arguments 7+ Frame pointer Return Addr %rbp (optional) Saved Registers + Local Callee Variables Frame Argument Stack pointer Build %rsp (optional) Stack “Top” Sean Barker 32 Register Conventions Return value (caller-saved) %rax %rdi %rbx %rsi %r12 Arguments %rdx Callee-saved %r13 Temporaries (caller-saved) %rcx %r14 %r8 %r15 %rbp %r9 Special Caller-saved %r10 %rsp temporaries %r11 Sean Barker 33 Caller-Saved vs. Callee-Saved (1) alice: movq X, %reg # compute X callq bob Could overwrite %reg! movq %reg, ... # use X Caller-Saved %reg Callee-Saved %reg alice: alice: movq X, %reg # compute X pushq %reg # save caller's pushq %reg # save X movq X, %reg # compute X callq bob # might change X callq bob # preserves X popq %reg # restore X movq %reg, ... # use X movq %reg, ... # use X popq %reg # restore caller Sean Barker 34 Caller-Saved vs. Callee-Saved (2) alice: movq X, %reg # compute X callq bob ... # don't need X again Caller-Saved %reg Callee-Saved %reg alice: alice: movq X, %reg # compute X pushq %reg # save caller's callq bob # might change X movq X, %reg # compute X ... callq bob # preserves X ... popq %reg # restore caller Avoids save/restore! Sean Barker 35 Caller-Saved vs. Callee-Saved (3) alice: Caller-Saved %reg movq X, %reg # compute X alice: callq bob movq X, %reg # compute X movq %reg, ... # use X pushq %reg # save X callq charlie callq bob # might change X movq %reg, ... # use X popq %reg # restore X movq %reg, ... # use X Callee-Saved %reg pushq %reg # save X callq charlie # might change alice: popq %reg # restore X pushq %reg # save caller's movq %reg, ... # use X movq X, %reg # compute callq bob # preserves X movq %reg, ... # use X Only one save/restore! callq charlie # preserves X movq %reg, ... # use X popq %reg # restore caller Sean Barker 36 Callee-Saved Example (1) Initial Stack Structure long foo2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); . return x+v2; } Rtn address %rsp foo2: pushq %rbx Resulting Stack Structure subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) . movl $3000, %esi leaq 8(%rsp), %rdi call incr Rtn address addq %rbx, %rax Saved %rbx addq $16, %rsp 15213 %rsp+8 popq %rbx ret Unused %rsp Sean Barker 37 Callee-Saved Example (2) Resulting Stack Structure long foo2(long x) { long v1 = 15213; . long v2 = incr(&v1, 3000); return x+v2; Rtn address } Saved %rbx 15213 %rsp+8 foo2: pushq %rbx Unused %rsp subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) Pre-return Stack Structure movl $3000, %esi leaq 8(%rsp), %rdi call incr .