Bryant and O Hallaron, Computer Systems: A Programmer s Perspective, Third Edition. Carnegie Mellon

Similar documents
Machine-Level Programming III: Procedures

Machine-level Programs Procedure

CS429: Computer Organization and Architecture

Machine- Level Representa2on: Procedure

Machine-Level Programming (2)

Procedures and the Call Stack

Mechanisms in Procedures. CS429: Computer Organization and Architecture. x86-64 Stack. x86-64 Stack Pushing

Assembly III: Procedures. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

The Stack & Procedures

The Stack & Procedures

void P() {... y = Q(x); print(y); return; } ... int Q(int t) { int v[10];... return v[t]; } Computer Systems: A Programmer s Perspective

Machine Program: Procedure. Zhaoguo Wang

Stack Frame Components. Using the Stack (4) Stack Structure. Updated Stack Structure. Caller Frame Arguments 7+ Return Addr Old %rbp

Assembly Programming IV

Sungkyunkwan University

Foundations of Computer Systems

Machine- Level Programming III: Switch Statements and IA32 Procedures

%r8 %r8d. %r9 %r9d. %r10 %r10d. %r11 %r11d. %r12 %r12d. %r13 %r13d. %r14 %r14d %rbp. %r15 %r15d. Sean Barker

Assembly Programming IV

IA32 Stack. Stack BoDom. Region of memory managed with stack discipline Grows toward lower addresses. Register %esp contains lowest stack address

x86-64 Programming III

Building an Executable

University of Washington

Lecture 4: x86_64 Assembly Language

Systems I. Machine-Level Programming V: Procedures

ASSEMBLY III: PROCEDURES. Jo, Heeseung

Assembly III: Procedures. Jo, Heeseung

Princeton University Computer Science 217: Introduction to Programming Systems. Assembly Language: Function Calls

Assembly Language: Function Calls

Assembly III: Procedures. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

CS213. Machine-Level Programming III: Procedures

Machine Language CS 3330 Samira Khan

Machine Programming 3: Procedures

CS 107. Lecture 13: Assembly Part III. Friday, November 10, Stack "bottom".. Earlier Frames. Frame for calling function P. Increasing address

The course that gives CMU its Zip! Machine-Level Programming III: Procedures Sept. 17, 2002

6.1. CS356 Unit 6. x86 Procedures Basic Stack Frames

Giving credit where credit is due

Compiling C Programs Into X86-64 Assembly Programs

x86-64 Programming III & The Stack

Areas for growth: I love feedback

IA32 Stack. Lecture 5 Machine-Level Programming III: Procedures. IA32 Stack Popping. IA32 Stack Pushing. Topics. Pushing. Popping

Machine- Level Programming III: Switch Statements and IA32 Procedures

CS 261 Fall Machine and Assembly Code. Data Movement and Arithmetic. Mike Lam, Professor

Machine/Assembler Language Putting It All Together

C to Assembly SPEED LIMIT LECTURE Performance Engineering of Software Systems. I-Ting Angelina Lee. September 13, 2012

IA32 Stack The course that gives CMU its Zip! Machine-Level Programming III: Procedures Sept. 17, IA32 Stack Popping. IA32 Stack Pushing

X86 Assembly -Procedure II:1

Systems Programming and Computer Architecture ( )

Lecture 3 CIS 341: COMPILERS

Machine-Level Programming II: Control

1 Number Representation(10 points)

Compiling C Programs Into x86-64 Assembly Programs

Region of memory managed with stack discipline Grows toward lower addresses. Register %esp contains lowest stack address = address of top element


CSE 351 Midterm - Winter 2017

CSCI 2021: x86-64 Control Flow

Intel x86-64 and Y86-64 Instruction Set Architecture

Data Representa/ons: IA32 + x86-64

Function Calls and Stack

Machine-Level Programming II: Control

CSE351 Spring 2018, Midterm Exam April 27, 2018

CS356: Discussion #15 Review for Final Exam. Marco Paolieri Illustrations from CS:APP3e textbook

CSE 351 Midterm Exam Spring 2016 May 2, 2015

C to Machine Code x86 basics: Registers Data movement instructions Memory addressing modes Arithmetic instructions

Lecture 4 CIS 341: COMPILERS

18-600: Recitation #4 Exploits

Stack Discipline Jan. 19, 2018

Machine-level Programming (3)

Recitation: Attack Lab

Buffer Overflow Attack (AskCypert CLaaS)

Do not turn the page until 5:10.

An Experience Like No Other. Stack Discipline Aug. 30, 2006

How Software Executes

Where We Are. Optimizations. Assembly code. generation. Lexical, Syntax, and Semantic Analysis IR Generation. Low-level IR code.

CSE351 Autumn 2014 Midterm Exam (29 October 2014)

CSE 351 Midterm - Winter 2015

18-600: Recitation #4 Exploits (Attack Lab)

Processor state. Information about currently executing program. %rax, %rdi, ... %r14 %r15. %rsp. %rip CF ZF SF OF. Temporary data

CSE 351 Midterm - Winter 2015 Solutions

CSC 252: Computer Organization Spring 2018: Lecture 6

x86 Programming I CSE 351 Winter

Credits and Disclaimers

Machine Level Programming: Control

CSE 401/M501 Compilers

CS 3330 Exam 1 Fall 2017 Computing ID:

Assembly II: Control Flow. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

C++ Named Return Value Optimization

Computer Systems C S Cynthia Lee

CSE P 501 Exam Sample Solution 12/1/11

CSE351 Autumn 2014 Midterm Exam (29 October 2014)

CS24: INTRODUCTION TO COMPUTING SYSTEMS. Spring 2018 Lecture 4

CS429: Computer Organization and Architecture

Brief Assembly Refresher

Assembly II: Control Flow

University*of*Washington*

Computer Organization: A Programmer's Perspective

x86 Programming II CSE 351 Winter

Changelog. Assembly (part 1) logistics note: lab due times. last time: C hodgepodge

Corrections made in this version not seen in first lecture:

Machine Level Programming: Basics

Transcription:

Carnegie Mellon

Machine-Level Programming III: Procedures 15-213/18-213/14-513/15-513: Introduction to Computer Systems 7 th Lecture, September 18, 2018

Today Procedures Mechanisms Stack Structure Calling Conventions Passing control Passing data Managing local data Illustration of Recursion 3

Mechanisms in Procedures Passing control To beginning of procedure code Back to return point Passing data Procedure arguments Return value Memory management Allocate during procedure execution Deallocate upon return Mechanisms all implemented with machine instructions x86-64 implementation of a procedure uses only those mechanisms required P( ) { y = Q(x); print(y) int Q(int i) { int t = 3*i; int v[10]; return v[t]; 4

Mechanisms in Procedures Passing control To beginning of procedure code Back to return point Passing data Procedure arguments Return value Memory management Allocate during procedure execution Deallocate upon return Mechanisms all implemented with machine instructions x86-64 implementation of a procedure uses only those mechanisms required P( ) { y = Q(x); print(y) int Q(int i) { int t = 3*i; int v[10]; return v[t]; 5

Mechanisms in Procedures Passing control To beginning of procedure code Back to return point Passing data Procedure arguments Return value Memory management Allocate during procedure execution Deallocate upon return Mechanisms all implemented with machine instructions x86-64 implementation of a procedure uses only those mechanisms required P( ) { y = Q(x); print(y) int Q(int i) { int t = 3*i; int v[10]; return v[t]; 6

Mechanisms in Procedures Passing control To beginning of procedure code Back to return point Passing data Procedure arguments Return value Memory management Allocate during procedure execution Deallocate upon return Mechanisms all implemented with machine instructions x86-64 implementation of a procedure uses only those mechanisms required P( ) { y = Q(x); print(y) int Q(int i) { int t = 3*i; int v[10]; return v[t]; 7

Mechanisms in Procedures Passing control To beginning of procedure code Back to return point Passing data Procedure arguments Return value Memory management Allocate during procedure execution Deallocate upon return Mechanisms all implemented with machine instructions x86-64 implementation of a procedure uses only those mechanisms required P( ) { y = Q(x); print(y) Machine instructions implement the mechanisms, but the choices are determined by designers. These choices make up the Application Binary Interface (ABI). int Q(int i) { int t = 3*i; int v[10]; return v[t]; 8

Today Procedures Mechanisms Stack Structure Calling Conventions Passing control Passing data Managing local data Illustration of Recursion 9

Carnegie Mellon x86-64 Stack Region of memory managed with stack discipline Memory viewed as array of bytes. Different regions have different purposes. (Like ABI, a policy decision) stack code m e m o r y 10

Carnegie Mellon x86-64 Stack Region of memory managed with stack discipline Stack Bottom stack Stack Pointer: %rsp Stack Top code 11

x86-64 Stack Region of memory managed with stack discipline Grows toward lower addresses Register %rsp contains lowest stack address address of top element Stack Pointer: %rsp Stack Bottom Stack Top Increasing Addresses Stack Grows Down 12

x86-64 Stack: Push pushq Src Fetch operand at Src val Decrement %rsp by 8 Write operand at address given by %rsp Stack Bottom Increasing Addresses Stack Pointer: %rsp Stack Top Stack Grows Down 13

x86-64 Stack: Push pushq Src Fetch operand at Src val Decrement %rsp by 8 Write operand at address given by %rsp Stack Bottom Increasing Addresses Stack Pointer: %rsp -8 Stack Top Stack Grows Down 14

x86-64 Stack: Pop popq Dest Read value at address given by %rsp Increment %rsp by 8 Store value at Dest (usually a register) Stack Bottom Increasing Addresses Stack Pointer: %rsp val Stack Top Stack Grows Down 15

x86-64 Stack: Pop popq Dest Read value at address given by %rsp Increment %rsp by 8 Store value at Dest (usually a register) Stack Bottom Increasing Addresses val Stack Pointer: %rsp +8 Stack Top Stack Grows Down 16

x86-64 Stack: Pop popq Dest Read value at address given by %rsp Increment %rsp by 8 Store value at Dest (usually a register) Stack Bottom Increasing Addresses Stack Pointer: %rsp (The memory doesn t change, only the value of %rsp) val Stack Top Stack Grows Down 17

Today Procedures Mechanisms Stack Structure Calling Conventions Passing control Passing data Managing local data Illustration of Recursion 18

Code Examples void multstore(long x, long y, long *dest) { long t = mult2(x, y); *dest = t; 0000000000400540 <multstore>: 400540: push %rbx # Save %rbx 400541: mov %rdx,%rbx # Save dest 400544: callq 400550 <mult2> # mult2(x,y) 400549: mov %rax,(%rbx) # Save at dest 40054c: pop %rbx # Restore %rbx 40054d: retq # Return long mult2(long a, long b) { 0000000000400550 <mult2>: long s = a * b; 400550: mov %rdi,%rax # a return s; 400553: imul %rsi,%rax # a * b 400557: retq # Return 19

Procedure Control Flow Use stack to support procedure call and return Procedure call: call label Push return address on stack Jump to label Return address: Address of the next instruction right after call Example from disassembly Procedure return: ret Pop address from stack Jump to address 20

Control Flow Example #1 0000000000400540 <multstore>: 400544: callq 400550 <mult2> 400549: mov %rax,(%rbx) 0x130 0x128 0x120 %rsp %rip 0x120 0x400544 0000000000400550 <mult2>: 400550: mov %rdi,%rax 400557: retq 21

Control Flow Example #2 0000000000400540 <multstore>: 400544: callq 400550 <mult2> 400549: mov %rax,(%rbx) 0x130 0x128 0x120 0x118 %rsp %rip 0x400549 0x118 0x400550 0000000000400550 <mult2>: 400550: mov %rdi,%rax 400557: retq 22

Control Flow Example #3 0000000000400540 <multstore>: 400544: callq 400550 <mult2> 400549: mov %rax,(%rbx) 0x130 0x128 0x120 0x118 %rsp %rip 0x400549 0x118 0x400557 0000000000400550 <mult2>: 400550: mov %rdi,%rax 400557: retq 23

Control Flow Example #4 0000000000400540 <multstore>: 400544: callq 400550 <mult2> 400549: mov %rax,(%rbx) 0x130 0x128 0x120 %rsp %rip 0x120 0x400549 0000000000400550 <mult2>: 400550: mov %rdi,%rax 400557: retq 24

Today Procedures Mechanisms tack Structure Calling Conventions Passing control Passing data Managing local data Illustrations of Recursion & Pointers 25

Procedure Data Flow Registers First 6 arguments %rdi Stack %rsi %rdx %rcx %r8 %r9 Return value Arg n Arg 8 Arg 7 %rax Only allocate stack space when needed 26

Data Flow Examples void multstore (long x, long y, long *dest) { long t = mult2(x, y); *dest = t; Carnegie Mellon 0000000000400540 <multstore>: # x in %rdi, y in %rsi, dest in %rdx 400541: mov %rdx,%rbx # Save dest 400544: callq 400550 <mult2> # mult2(x,y) # t in %rax 400549: mov %rax,(%rbx) # Save at dest long mult2 (long a, long b) { long s = a * b; return s; 0000000000400550 <mult2>: # a in %rdi, b in %rsi 400550: mov %rdi,%rax # a 400553: imul %rsi,%rax # a * b # s in %rax 400557: retq # Return 27

Today Procedures Mechanisms Stack Structure Calling Conventions Passing control Passing data Managing local data Illustration of Recursion 28

Stack-Based Languages Languages that support recursion e.g., C, Pascal, Java Code must be Reentrant Multiple simultaneous instantiations of single procedure Need some place to store state of each instantiation Arguments Local variables Return pointer Stack discipline State for given procedure needed for limited time From when called to when return Callee returns before caller does Stack allocated in Frames state for single procedure instantiation 29

Call Chain Example yoo( ) { who(); who( ) { (); (); ( ) { (); Example Call Chain yoo who Procedure () is recursive 30

Stack Frames Contents Return information Local storage (if needed) Temporary space (if needed) Frame Pointer: %rbp (Optional) x Previous Frame Frame for proc Management Space allocated when enter procedure Set-up code Includes push by call instruction Deallocated when return Finish code Includes pop by ret instruction Stack Pointer: %rsp Stack Top 31

Example Stack yoo( ) { who(); yoo who %rbp %rsp yoo yoo 32

Example Stack yoo( ) { who( ) { who(); (); (); yoo who %rbp %rsp yoo yoo who 33

Example Stack yoo( ) { who( ) { ( ) who(); (); { (); (); yoo who %rbp %rsp yoo yoo who 34

Example Stack yoo( ) { who( ) { ( ) who(); (); { ( ) (); { (); (); yoo who %rbp %rsp yoo yoo who 35

Example Stack yoo( ) { who( ) { ( ) who(); (); { ( ) (); { (); ( ) { (); (); yoo who %rbp %rsp yoo yoo who 36

Example Stack yoo( ) { who( ) { ( ) who(); (); { ( ) (); { (); (); yoo who %rbp %rsp yoo yoo who 37

Example Stack yoo( ) { who( ) { ( ) who(); (); { (); (); yoo who %rbp %rsp yoo yoo who 38

Example Stack yoo( ) { who( ) { who(); (); (); yoo who %rbp %rsp yoo yoo who 39

Example Stack yoo( ) { who( ) { ( ) who(); (); { (); (); yoo who %rbp %rsp yoo yoo who 40

Example Stack yoo( ) { who( ) { who(); (); (); yoo who %rbp %rsp yoo yoo who 41

Example Stack yoo( ) { who(); yoo who %rbp %rsp yoo yoo 42

x86-64/linux Stack Frame Current Stack Frame ( Top to Bottom) Argument build: Parameters for function about to call Local variables If can t keep in registers Saved register context Old frame pointer (optional) Caller Stack Frame Return address Pushed by call instruction Arguments for this call Frame pointer %rbp (Optional) Stack pointer %rsp Caller Frame Arguments 7+ Return Addr Old %rbp Saved Registers + Local Variables Argument Build (Optional) 43

Example: incr long incr(long *p, long val) { long x = *p; long y = x + val; *p = y; return x; incr: movq addq movq ret (%rdi), %rax %rax, %rsi %rsi, (%rdi) Register %rdi %rsi %rax Use(s) Argument p Argument val, y x, Return value 44

Example: Calling incr #1 long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1+v2;... Rtn address Initial Stack Structure %rsp call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret Resulting Stack Structure... Rtn address 15213 %rsp+8 Unused %rsp 45

Example: Calling incr #2 long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1+v2; call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret... Rtn address 15213 Unused Register %rdi Stack Structure Use(s) &v1 %rsi 3000 %rsp+8 %rsp 46

Example: Calling incr #2 long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1+v2; call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret... Rtn address 15213 Stack Structure Aside 1: movl $3000, Unused %esi Note: movl -> %exx zeros out high order 32 bits. Why use movl instead of movq? 1 byte shorter. Register %rdi Use(s) &v1 %rsi 3000 %rsp+8 %rsp 47

Example: Calling incr #2 long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1+v2; Aside 2: leaq call_incr: subq Computes $16, %rsp+8 movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret... Rtn address 15213 Unused 8(%rsp), %rdi Actually, used for what it is meant! Register %rdi Stack Structure Use(s) &v1 %rsi 3000 %rsp+8 %rsp 48

Example: Calling incr #2 long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1+v2; call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret... Rtn address 15213 Unused Register %rdi Stack Structure Use(s) &v1 %rsi 3000 %rsp+8 %rsp 49

Example: Calling incr #3 long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1+v2; call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret... Rtn address 18213 Unused Register %rdi Stack Structure Use(s) &v1 %rsi 3000 %rsp+8 %rsp 50

Example: Calling incr #4 Stack Structure long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1+v2; call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret... Rtn address 18213 Unused Register %rax %rsp+8 %rsp Use(s) Return value 51

Example: Calling incr #5a Stack Structure long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1+v2;... Rtn address 18213 Unused %rsp+8 %rsp call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret Register Use(s) %rax Return value Updated Stack Structure... Rtn address %rsp 52

Example: Calling incr #5b long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1+v2; Updated Stack Structure... Rtn address %rsp call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret Register Use(s) %rax Return value Final Stack Structure... %rsp 53

Register Saving Conventions When procedure yoo calls who: yoo is the caller who is the callee Can register be used for temporary storage? yoo: movq $15213, %rdx call who addq %rdx, %rax ret who: subq $18213, %rdx ret Contents of register %rdx overwritten by who This could be trouble something should be done! Need some coordination 54

Register Saving Conventions When procedure yoo calls who: yoo is the caller who is the callee Can register be used for temporary storage? Conventions Caller Saved Caller saves temporary values in its frame before the call Callee Saved Callee saves temporary values in its frame before using Callee restores them before returning to caller 55

x86-64 Linux Register Usage #1 %rax Return value Also caller-saved Can be modified by procedure %rdi,..., %r9 Arguments Also caller-saved Can be modified by procedure %r10, %r11 Caller-saved Can be modified by procedure Return value Arguments Caller-saved temporaries %rax %rdi %rsi %rdx %rcx %r8 %r9 %r10 %r11 56

x86-64 Linux Register Usage #2 %rbx, %r12, %r13, %r14 Callee-saved Callee must save & restore %rbp Callee-saved Callee must save & restore May be used as frame pointer Can mix & match %rsp Special form of callee save Restored to original value upon exit from procedure Callee-saved Temporaries Special %rbx %r12 %r13 %r14 %rbp %rsp 57

Quiz Time! Check out: https://canvas.cmu.edu/courses/5835 58

Callee-Saved Example #1 long call_incr2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); return x+v2; Initial Stack Structure... Rtn address %rsp X comes in register %rdi. We need %rdi for the call to incr. Where should be put x, so we can use it after the call to incr? 59

Callee-Saved Example #2 long call_incr2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); return x+v2; call_incr2: pushq %rbx subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq %rbx, %rax addq $16, %rsp popq %rbx ret Initial Stack Structure... Rtn address %rsp Resulting Stack Structure... Rtn address Saved %rbx %rsp 60

Callee-Saved Example #3 long call_incr2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); return x+v2; call_incr2: pushq %rbx subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq %rbx, %rax addq $16, %rsp popq %rbx ret Initial Stack Structure... Rtn address Saved %rbx %rsp Resulting Stack Structure... Rtn address Saved %rbx %rsp+8 %rsp 61

Callee-Saved Example #4 long call_incr2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); return x+v2; call_incr2: pushq %rbx subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq %rbx, %rax addq $16, %rsp popq %rbx ret... Rtn address Saved %rbx Stack Structure %rsp+8 %rsp x is saved in %rbx, a callee saved register 62

Callee-Saved Example #5 long call_incr2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); return x+v2; call_incr2: pushq %rbx subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq %rbx, %rax addq $16, %rsp popq %rbx ret... Rtn address Saved %rbx 15213 Unused Stack Structure %rsp+8 %rsp x is saved in %rbx, a callee saved register 63

Callee-Saved Example #6 Stack Structure long call_incr2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); return x+v2; call_incr2: pushq %rbx subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq %rbx, %rax addq $16, %rsp popq %rbx ret... Rtn address Saved %rbx 18213 Unused %rsp+8 %rsp Upon return from incr: x is safe in %rbx Return result v2 is in %rax Compute x+v2 64

Callee-Saved Example #7 long call_incr2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); return x+v2; call_incr2: pushq %rbx subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq %rbx, %rax addq $16, %rsp popq %rbx ret Stack Structure... Rtn address Saved %rbx %rsp 18213 Unused Return result in %rax 65

Callee-Saved Example #8 long call_incr2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); return x+v2; call_incr2: pushq %rbx subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq %rbx, %rax addq $16, %rsp popq %rbx ret Initial Stack Structure... Rtn address Saved %rbx %rsp 18213 Unused final Stack Structure... Rtn address %rsp Saved %rbx 18213 Unused 66

Today Procedures Mechanisms Stack Structure Calling Conventions Passing control Passing data Managing local data Illustration of Recursion 68

Recursive Function /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); pcount_r: movl $0, %eax testq %rdi, %rdi je.l6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx.l6: rep; ret 69

Recursive Function Terminal Case /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); Register Use(s) Type %rdi x Argument %rax Return value Return value pcount_r: movl $0, %eax testq %rdi, %rdi je.l6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx.l6: rep; ret 70

Recursive Function Register Save /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); pcount_r: movl $0, %eax testq %rdi, %rdi je.l6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx.l6: rep; ret Register Use(s) Type %rdi x Argument... Rtn address Saved %rbx %rsp 71

Recursive Function Call Setup /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); Register Use(s) Type %rdi x >> 1 Recursive argument %rbx x & 1 Callee-saved pcount_r: movl $0, %eax testq %rdi, %rdi je.l6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx.l6: rep; ret 72

Recursive Function Call /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); Register Use(s) Type %rbx x & 1 Callee-saved %rax Recursive call return value pcount_r: movl $0, %eax testq %rdi, %rdi je.l6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx.l6: rep; ret 73

Recursive Function Result /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); Register Use(s) Type %rbx x & 1 Callee-saved %rax Return value pcount_r: movl $0, %eax testq %rdi, %rdi je.l6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx.l6: rep; ret 74

Recursive Function Completion /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); Register Use(s) Type %rax Return value Return value pcount_r: movl $0, %eax testq %rdi, %rdi je.l6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx.l6: rep; ret... %rsp 75

Observations About Recursion Handled Without Special Consideration Stack frames mean that each function call has private storage Saved registers & local variables Saved return pointer Register saving conventions prevent one function call from corrupting another s data Unless the C code explicitly does so (e.g., buffer overflow in Lecture 9) Stack discipline follows call / return pattern If P calls Q, then Q returns before P Last-In, First-Out Also works for mutual recursion P calls Q; Q calls P 76

x86-64 Procedure Summary Important Points Stack is the right data structure for procedure call/return If P calls Q, then Q returns before P Recursion (& mutual recursion) handled by normal calling conventions Can safely store values in local stack frame and in callee-saved registers Put function arguments at top of stack Result return in %rax Pointers are addresses of values On stack or global Caller Frame %rbp (Optional) %rsp Arguments 7+ Return Addr Old %rbp Saved Registers + Local Variables Argument Build 77

Small Exercise long add5(long b0, long b1, long b2, long b3, long b4) { return b0+b1+b2+b3+b4; long add10(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return add5(a0, a1, a2, a3, a4)+ add5(a5, a6, a7, a8, a9); Where are a0,, a9 passed? rdi, rsi, rdx, rcx, r8, r9, stack Where are b0,, b4 passed? rdi, rsi, rdx, rcx, r8 Which registers do we need to save? Ill-posed question. Need assembly. rbx, rbp, r9 (during first call to add5) 78

Small Exercise long add5(long b0, long b1, long b2, long b3, long b4) { return b0+b1+b2+b3+b4; long add10(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return add5(a0, a1, a2, a3, a4)+ add5(a5, a6, a7, a8, a9); add10: pushq %rbp pushq %rbx movq %r9, %rbp call add5 movq %rax, %rbx movq 48(%rsp), %r8 movq 40(%rsp), %rcx movq 32(%rsp), %rdx movq 24(%rsp), %rsi movq %rbp, %rdi call add5 addq %rbx, %rax popq %rbx popq %rbp ret add5: addq addq addq leaq ret %rsi, %rdi %rdi, %rdx %rdx, %rcx (%rcx,%r8), %rax 79