15-213 The course that gives CMU its Zip! Machine-Level Programming III: Procedures Sept. 17, 2002 Topics IA32 stack discipline Register saving conventions Creating pointers to local variables IA32 Region of memory managed with stack discipline Grows toward lower addresses Register indicates lowest stack address address of top element Bottom Top Increasing Addresses Grows Down class07.ppt 2 15-213, F 02 IA32 Pushing Pushing pushl Src Fetch operand at Src Decrement by Write operand at address given by Bottom Increasing Addresses IA32 Popping Popping popl Dest Read operand at address given by Increment by Write to Dest Bottom Increasing Addresses - Grows Down + Grows Down Top 3 15-213, F 02 Top 15-213, F 02
Operation Eamples Procedure Control Flow pushl %ea popl %ed Use stack to support procedure call and urn Procedure call: call label Push urn address on stack; Jump to label 0110 010c 010 3 0110 010c 010 010 3 213 0110 010c 010 010 3 213 Return address value Address of instruction beyond call Eample from disassembly 05e: e 3d 06 00 00 call 0b90 <main> %ea 213 %ea 213 %ea 213 0553: 50 pushl %ea Return address = 00553 %ed 555 %ed 555 %ed 555 213 Procedure urn: 010 010 010 010 010 Pop address from stack; Jump to address 5 15-213, F 02 6 15-213, F 02 Procedure Call Eample 05e: e 3d 06 00 00 call 0b90 <main> 0553: 50 pushl %ea Procedure Return Eample 0591: c3 call 0b90 0110 0110 0110 0110 010c 010c 010c 010c 010 3 010 3 010 3 010 3 010 00553 010 00553 00553 010 010 010 010 010 010 %eip 005e %eip 005e 00b90 %eip 00591 %eip 00591 00553 %eip is program counter 7 15-213, F 02 %eip is program counter 15-213, F 02
-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 Discipline State for given procedure needed for limited time From when called to when urn Callee urns before caller does Allocated in s state for single procedure instantiation Eample Code Structure (É) (); Procedure recursive (É) (); (); (É) (); 9 15-213, F 02 10 15-213, F 02 s Contents Local variables Return information Temporary space Management Space allocated when enter procedure Set-up code Deallocated when urn Finish code s pointer indicates stack top pointer indicates start of current frame 11 15-213, F 02 proc Top Operation (É) (); 15-213, F 02
Operation (É) (); (); Operation (É) (); 13 15-213, F 02 1 15-213, F 02 Operation (É) (); 15 15-213, F 02 Operation (É) (); 16 15-213, F 02
Operation (É) (); Operation (É) (); 17 15-213, F 02 1 15-213, F 02 Operation (É) (); (); Operation (É) 19 15-213, F 02 20 15-213, F 02
Operation (É) (); (); Operation (É) (); 21 15-213, F 02 22 15-213, F 02 IA32/Linu Revisiting swap Current ( Top to Bottom) Parameters for function about to call Argument build Local variables If can t keep in registers Saved register contet Old frame pointer Caller Return address Pushed by call instruction Arguments for this call Caller () () Arguments Return Addr Old Saved Registers + Local Variables Argument Build int zip1 = 15213; int zip2 = 915; void call_swap() swap(&zip1, &zip2); void swap(int *p, int *) int t0 = *p; int t1 = *; *p = t1; * = t0; Calling swap from call_swap call_swap: pushl $zip2 pushl $zip1 call swap &zip2 &zip1 # Global Var # Global Var Resulting 23 15-213, F 02 2 15-213, F 02
Revisiting swap void swap(int *p, int *) int t0 = *p; int t1 = *; *p = t1; * = t0; swap: pushl movl, pushl %eb movl (),%ec movl (),%ed movl (%ec),%ea movl (%ed),%eb movl %ea,(%ed) movl %eb,(%ec) movl -(),%eb movl, popl Body 25 15-213, F 02 Set Up Finish swap Setup #1 Entering &zip2 &zip1 swap: pushl movl, pushl %eb Resulting 26 15-213, F 02 p Old swap Setup #2 Entering Resulting swap Setup #3 Entering Resulting &zip2 &zip1 swap: pushl movl, pushl %eb 27 15-213, F 02 p Old &zip2 &zip1 swap: pushl movl, pushl %eb 2 15-213, F 02 p Old Old %eb
Effect of swap Setup swap Finish #1 Entering (relative to ) Resulting swap s p p &zip2 &zip1 p 0 Old 0 Old - Old %eb - Old %eb 0 Old movl (),%ec # get movl (),%ed # get p... Body Old %eb Observation Saved & restored register %eb movl -(),%eb movl, popl 29 15-213, F 02 30 15-213, F 02 swap Finish #2 swap Finish #3 swap s swap s swap s swap s p 0 Old - Old %eb p 0 Old p 0 Old p movl -(),%eb movl, popl movl -(),%eb movl, popl 31 15-213, F 02 32 15-213, F 02
swap Finish # swap s Observation p Saved & restored register %eb Didn t do so for %ea, %ec, or %ed &zip2 &zip1 Eiting movl -(),%eb movl, popl 33 15-213, F 02 Register Saving Conventions When procedure calls : is the caller, is the callee Can Register be Used for Temporary Storage? : movl $15213, %ed call addl %ed, %ea : movl (), %ed addl $915, %ed Contents of register %ed overwritten by 3 15-213, F 02 Register Saving Conventions When procedure calls : is the caller, is the callee Can Register be Used for Temporary Storage? Conventions Caller Save Caller saves temporary in its frame before calling Callee Save Callee saves temporary in its frame before using 35 15-213, F 02 IA32/Linu Register Usage Integer Registers Two have special uses, Three managed as callee-save %eb, %esi, %edi Old values saved on stack prior to using Three managed as caller-save %ea, %ed, %ec Do what you please, but epect any callee to do so, as well Register %ea also stores urned value Caller-Save Temporaries Callee-Save Temporaries Special %ea %ed %ec %eb %esi %edi 36 15-213, F 02
Recursive Factorial.globl rfact.te rfact,@function int rfact(int ) rfact: pushl int rval; movl, if ( <= 1) pushl %eb urn 1; movl (),%eb rval = rfact(-1); cmpl $1,%eb urn rval * ; jle.l7 leal -1(%eb),%ea pushl %ea call rfact imull %eb,%ea Registers jmp.l79 %ea used without first.align saving.l7: movl $1,%ea %eb used, but save at.l79: beginning & restore at end movl -(),%eb movl, popl 37 15-213, F 02 Rfact Setup Caller Caller pre pre %eb pre pre %eb 0 Old Callee - Old %eb Entering rfact: pushl movl, pushl %eb 3 15-213, F 02 Rfact Body Recursion int rfact(int ) int rval; if ( <= 1) urn 1; rval = rfact(-1) ; urn rval * ; movl (),%eb # eb = cmpl $1,%eb # Compare : 1 jle.l7 # If <= goto Term leal -1(%eb),%ea # ea = -1 pushl %ea # Push -1 call rfact # rfact(-1) imull %eb,%ea # rval * jmp.l79 # Goto done.l7: # Term: movl $1,%ea # urn val = 1.L79: # Done: Registers %eb Stored value of %ea Temporary value of -1 Returned value from rfact(-1) Returned value from this call Rfact Recursion leal -1(%eb),%ea %ea %eb Old Old %eb -1 %ea %eb pushl %ea Old Old %eb -1-1 %ea %eb call rfact Old Old %eb -1-1 39 15-213, F 02 0 15-213, F 02
%ea %eb Rfact Result Return from Call Old Old %eb -1 (-1)! Assume that rfact(-1) urns (-1)! in register %ea imull %eb,%ea %ea %eb (-1)!! 1 15-213, F 02 Old Old %eb -1 - - %ea Rfact Completion pre pre %eb 0 Old Old %eb -1! %eb Old %eb %ea %eb pre pre %eb 0 Old! Old %eb movl -(),%eb movl, popl %ea %eb pre pre %eb 2 15-213, F 02! Old %eb Code Recursive Procedure void s_helper (int, int *accum) if ( <= 1) urn; else int z = *accum * ; *accum = z; s_helper (-1,accum); Pass pointer to update location Top-Level Call int sfact(int ) int val = 1; s_helper(, &val); urn val; 3 15-213, F 02 Creating & Initializing Initial part of sfact _sfact: pushl # Save movl, # Set subl $16, # Add 16 bytes movl (),%ed # ed = movl $1,-() # val = 1 Using for Local Variable Temp. Unused Space Variable val must be -16 stored on stack Need to create pointer to it int sfact(int ) Compute pointer as - int val = 1; () s_helper(, &val); Push on stack as second urn val; argument 15-213, F 02 0 Old - val = 1 - -
Passing Calling s_helper from sfact leal -(),%ea # Compute &val pushl %ea # Push on stack pushl %ed # Push call s_helper # call movl -(),%ea # Return val ÊÊ # Finish int sfact(int ) int val = 1; s_helper(, &val); urn val; at time of call 5 15-213, F 02 0 Old - val =! 1 - - -16 Unused &val Using void s_helper (int, int *accum) ÊÊ int z = *accum * ; *accum = z; ÊÊ Register %ec holds %ea %ec ÊÊ movl %ec,%ea # z = imull (%ed),%ea # z *= *accum movl %ea,(%ed) # *accum = z ÊÊ Register %ed holds pointer to accum Use access (%ed) to reference memory accum* accum* 6 15-213, F 02 %ed Summary The Makes Recursion Work Private storage for each instance of procedure call Instantiations don t clobber each other Addressing of locals + arguments can be relative to stack positions Can be managed by stack discipline Procedures urn in inverse order of calls IA32 Procedures Combination of Instructions + Conventions Call / Ret instructions Register usage conventions Caller / Callee save and frame organization conventions 7 15-213, F 02