Machine-Level Programming III: Procedures
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 2
IA32 Pushing Bottom Increasing Addresses -4 Grows Down Top 3
IA32 Popping Bottom Increasing Addresses +4 Grows Down Top 4
Operation Examples pushl %eax popl %edx 0x110 0x110 0x110 0x10c 0x10c 0x10c 0x108 123 0x108 123 0x108 123 0x104 213 0x104 213 %eax 213 %eax 213 %eax 213 %edx 555 %edx 555 %edx 555 213 0x108 0x108 0x104 0x104 0x108 5
Procedure Control Flow 6
Procedure Call Example 804854e: e8 3d 06 00 00 call 8048b90 <main> 8048553: 50 pushl %eax call 8048b90 0x110 0x110 0x10c 0x10c 0x108 123 0x108 123 0x104 0x8048553 0x108 0x108 0x104 %eip 0x804854e %eip 0x804854e 0x8048b90 %eip is program counter 7
Procedure Return Example 8048591: c3 ret ret 0x110 0x110 0x10c 0x10c 0x108 123 0x108 123 0x104 0x8048553 0x8048553 0x104 0x104 0x108 %eip 0x8048591 %eip 0x8048591 0x8048553 %eip is program counter 8
-Based Languages 9
Call Chain Example ( ) { who(); } 10 Procedure recursive who( ) { (); (); } ( ) { (); } Call Chain who
Frames who Frame proc Top 11
Operation ( ) { who(); } Call Chain Frame 12
Operation who( ) { (); (); } Call Chain who Frame who 13
Operation ( ) { (); } Call Chain who Frame who 14
Operation ( ) { (); } Call Chain who Frame who 15
Operation ( ) { (); } Call Chain who who 16 Frame
Operation ( ) { (); } Call Chain who Frame who 17
Operation ( ) { (); } Call Chain who Frame who 18
Operation who( ) { (); who (); } Call Chain Frame who 19
Operation ( ) { } Call Chain who Frame who 20
Operation who( ) { (); who (); } Call Chain Frame who 21
Operation ( ) { who(); } Call Chain who Frame 22
IA32/Linux Frame Caller Frame Frame () Arguments Return Addr Old Saved Registers + Local Variables () Argument Build 23
Revisiting swap int zip1 = 15213; int zip2 = 91125; void call_swap() { swap(&zip1, &zip2); } Calling swap from call_swap call_swap: pushl $zip2 # Global Var pushl $zip1 # Global Var call swap void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } High &zip2 &zip1 Resulting 24 Low
Revisiting swap void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } swap: pushl movl, pushl %ebx movl 12(),%ecx movl 8(),%edx movl (%ecx),%eax movl (%edx),%ebx movl %eax,(%edx) movl %ebx,(%ecx) movl -4(),%ebx movl, popl ret Set Up Body Finish 25
swap Setup #1 Entering Resulting &zip2 &zip1 yp xp Old swap: pushl movl, pushl %ebx 26
swap Setup #2 Entering Resulting 27 &zip2 &zip1 swap: pushl movl, pushl %ebx yp xp Old
swap Setup #3 Entering Resulting 28 &zip2 &zip1 swap: pushl movl, pushl %ebx yp xp Old Old %ebx
Effect of swap Setup Entering Offset (relative to ) Resulting &zip2 12 yp &zip1 8 xp 4 0 Old Old %ebx movl 12(),%ecx # get yp movl 8(),%edx # get xp... Body 29
swap Finish #1 swapʼs Offset Offset 12 8 4 0-4 yp xp Old Old %ebx 12 8 4 0-4 yp xp Old Old %ebx movl -4(),%ebx movl, popl ret 30
swap Finish #2 swapʼs Offset swapʼs Offset 12 8 4 0-4 yp xp Old Old %ebx 12 8 4 0 yp xp Old movl -4(),%ebx movl, popl ret 31
swap Finish #3 swapʼs Offset swapʼs Offset 12 8 4 0 yp xp Old 12 8 4 yp xp movl -4(),%ebx movl, popl ret 32
swap Finish #4 swapʼs Offset 12 8 4 yp xp &zip2 &zip1 Exiting movl -4(),%ebx movl, popl ret 33
Register Saving Conventions : movl $15213, %edx call who addl %edx, %eax ret who: movl 8(), %edx addl $91125, %edx ret 34
Register Saving Conventions 35
IA32/Linux Register Usage Caller-Save Temporaries Callee-Save Temporaries Special %eax %edx %ecx %ebx %esi %edi 36
Recursive Factorial 37 int rfact(int x) { int rval; if (x <= 1) return 1; rval = rfact(x-1); return rval * x; }.globl rfact.type rfact,@function rfact: pushl movl, pushl %ebx movl 8(),%ebx cmpl $1,%ebx jle.l78 leal -1(%ebx),%eax pushl %eax call rfact imull %ebx,%eax jmp.l79.align 4.L78: movl $1,%eax.L79: movl -4(),%ebx movl, popl ret
Rfact Setup Caller pre pre %ebx x Entering Caller 8 4 0 Callee -4 pre pre %ebx x Old Old %ebx rfact: pushl movl, pushl %ebx 38
Rfact Body movl 8(),%ebx # ebx = x cmpl $1,%ebx # Compare x : 1 jle.l78 # If <= goto Term Recursion leal -1(%ebx),%eax # eax = x-1 pushl %eax # Push x-1 call rfact # rfact(x-1) imull %ebx,%eax # rval * x jmp.l79 # Goto done.l78: # Term: movl $1,%eax # return val = 1.L79: # Done: int rfact(int x) { int rval; if (x <= 1) return 1; rval = rfact(x-1) ; return rval * x; } 39
Rfact Recursion leal -1(%ebx),%eax %eax %ebx x Old Old %ebx x-1 x pushl %eax x Old Old %ebx x-1 %eax x-1 %ebx x call rfact x Old Old %ebx x-1 %eax %ebx x-1 x 40
Rfact Result Return from Call imull %ebx,%eax x x Old Old Old %ebx Old %ebx x-1 x-1 %eax (x-1)! %eax (x-1)! x! %ebx x %ebx x 41 Assume that rfact(x-1) returns (x-1)! in register %eax
8 4 0-4 -8 %eax %ebx Rfact Completion movl -4(),%ebx pre pre %ebx x Old pre pre %ebx Old %ebx 8 x x-1 4 0 Old x! movl, popl ret Old x %ebx %eax x! %ebx Old %ebx %eax x! %ebx Old %ebx pre pre %ebx x 42
43 Summary