CISC 36 Machine-Level Programming III: Procedures Sept. 22, 2 IA32 Region of memory managed with stack discipline Grows toward lower addresses Register indicates lowest stack address address of top element Bottom Increasing Addresses Grows Down Top class7.ppt 2 IA32 Pushing IA32 Popping Bottom Bottom Increasing Addresses Increasing Addresses - Grows Down + Grows Down Top Top 3 Page 1
Operation Eamples Procedure Control Flow pushl %ea popl %ed 11 1c 1 3 11 1c 1 1 3 213 11 1c 1 1 3 213 %ea %ed 213 555 1 %ea %ed 213 555 1 1 %ea %ed 213 555 213 1 1 5 6 Procedure Call Eample Procedure Return Eample 5e: e 3d 6 call b9 <main> 553: 5 pushl %ea 591: c3 call b9 11 1c 1 3 11 1c 1 3 1 553 11 1c 1 3 1 553 11 1c 1 3 553 1 1 1 1 1 1 %eip 5e %eip 5e b9 %eip 591 %eip 591 553 %eip is program counter %eip is program counter 7 Page 2
-Based Languages Eample ( ) (); Procedure recursive ( ) (); (); ( ) (); 9 1 s proc Top Operation ( ) (); 11 Page 3
Operation ( ) (); (); Operation ( ) (); 13 1 Operation ( ) (); Operation ( ) (); 15 16 Page
Operation ( ) (); Operation ( ) (); 17 1 Operation ( ) (); (); Operation ( ) 19 2 Page 5
Operation ( ) (); (); Operation ( ) (); 21 22 IA32/Linu Revisiting swap Calling swap from call_swap 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 t = *p; int t1 = *; *p = t1; * = t; call_swap: pushl $zip2 # Global Var pushl $zip1 # Global Var call swap &zip2 &zip1 Resulting 23 2 Page 6
Revisiting swap void swap(int *p, int *) int t = *p; int t1 = *; *p = t1; * = t; 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 Set Up Body Finish swap Setup #1 Entering &zip2 &zip1 swap: pushl movl, pushl %eb Resulting p Old 25 26 swap Setup #2 Entering Resulting swap Setup #3 Entering Resulting &zip2 &zip1 swap: pushl movl, pushl %eb p Old &zip2 &zip1 swap: pushl movl, pushl %eb p Old Old %eb 27 2 Page 7
Effect of swap Setup swap Finish #1 Entering &zip2 &zip1 (relative to ) movl (),%ec # get movl (),%ed # get p... Body p Old Old %eb Resulting swapʼs - p Old Old %eb - p Old Old %eb movl -(),%eb movl, popl 29 3 swap Finish #2 swap Finish #3 swapʼs - p Old Old %eb swapʼs p Old swapʼs p Old swapʼs p movl -(),%eb movl, popl movl -(),%eb movl, popl 31 32 Page
swap Finish # swapʼs p &zip2 &zip1 Eiting movl -(),%eb movl, popl Register Saving Conventions : movl $15213, %ed call addl %ed, %ea : movl (), %ed addl $915, %ed 33 3 Register Saving Conventions IA32/Linu Register Usage Caller-Save Temporaries %ea %ed %ec Callee-Save Temporaries %eb %esi %edi Special 35 36 Page 9
Recursive Factorial 37 int rfact(int ) int rval; if ( <= 1) urn 1; rval = rfact(-1); urn rval * ;.globl rfact.te rfact,@function rfact: pushl movl, pushl %eb movl (),%eb cmpl $1,%eb jle.l7 leal -1(%eb),%ea pushl %ea call rfact imull %eb,%ea jmp.l79.align.l7: movl $1,%ea.L79: movl -(),%eb movl, popl 3 Rfact Setup pre Caller pre %eb Entering rfact: pushl movl, pushl %eb pre Caller pre %eb Old Callee - Old %eb Rfact Body movl (),%eb # eb = cmpl $1,%eb # Compare : 1 jle.l7 # If <= goto Term int rfact(int ) int rval; if ( <= 1) urn 1; rval = rfact(-1) ; urn rval * ; 39 Recursion 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: Rfact Recursion leal -1(%eb),%ea Old Old %eb %ea -1 %eb pushl %ea Old Old %eb -1 %ea -1 %eb call rfact Old Old %eb -1 %ea -1 %eb Page 1
1 Rfact Result Return from Call Old Old %eb -1 %ea (-1)! %eb Assume that rfact(-1) urns (-1)! in register %ea imull %eb,%ea Old Old %eb -1 %ea (-1)!! %eb Rfact Completion movl -(),%eb pre pre %eb Old - Old %eb - -1 %ea! pre pre %eb Old movl, popl pre pre %eb %eb Old %eb %ea! %eb Old %eb %ea! %eb Old %eb 2 Code Recursive Procedure void s_helper (int, int *accum) if ( <= 1) urn; else int z = *accum * ; *accum = z; s_helper (-1,accum); Top-Level Call int sfact(int ) int val = 1; s_helper(, &val); urn val; Creating & Initializing Initial part of sfact _sfact: pushl # Save movl, # Set subl $16, # Add 16 bytes movl (),%ed # ed = Old movl $1,-() # val = 1 - val = 1 - Temp. - Unused Space -16 3 Pass pointer to update location int sfact(int ) int val = 1; s_helper(, &val); urn val; Page 11
Passing 5 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 Old - val =! 1 - - Unused -16 &val 6 Using void s_helper (int, int *accum) int z = *accum * ; *accum = z; Register %ec holds 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* %ea accum* %ec %ed Summary 7 Page