Carnegie Mellon
Machine-‐Level Programming III: Switch Statements and IA32 Procedures
15-‐213 / 18-‐213: Introduc�on to Computer Systems 7th Lecture, Sep 17, 2013
Instructors: Randy Bryant, Dave O’Hallaron, and Greg Kesden Carnegie Mellon
Today
¢ Switch statements
¢ IA 32 Procedures §. Stack Structure §. Calling Conven�ons §. Illustra�ons of Recursion & Pointers
2 Carnegie Mellon long switch_eg Switch Statement (long x, long y, long z) { Example long w = 1; switch(x) { case 1: ¢ Mul�ple case labels w = y*z; break; §. Here: 5 & 6 case 2: ¢ Fall through cases w = y/z; §. /* Fall Through */ Here: 2 case 3: ¢ Missing cases w += z; §. break; Here: 4 case 5: case 6: w -= z; break; default: w = 2; } return w; } 3 Carnegie Mellon
Jump Table Structure
Switch Form Jump Table Jump Targets Code Block switch(x) { jtab: Targ0 Targ0: case val_0: 0 Block 0 Targ1 case val_1: Targ2 Block 1 Targ1: Code Block 9 1 999 9 case val_n-1: 9 Block n–1 Targ2: Code Block } Targn-1 2
Approximate Transla�on 9 9 target = JTab[x]; 9 goto *target; Targn-1: Code Block n–1
4 Carnegie Mellon
Switch Statement Example (IA32) long switch_eg(long x, long y, long z) { long w = 1; switch(x) { . . . } What range of return w; values takes } default? Setup:
switch_eg: pushl %ebp # Setup movl %esp, %ebp # Setup movl 8(%ebp), %eax # %eax = x cmpl $6, %eax # Compare x:6 ja .L8 # If unsigned > goto default jmp *.L4(,%eax,4) # Goto *JTab[x] Note that w not ini�alized here 5 Carnegie Mellon
Switch Statement Example (IA32)
long switch_eg(long x, long y, long z) { long w = 1; switch(x) { Jump table . . . .section .rodata } .align 4 return w; .L4: } .long .L8 # x = 0 .long .L3 # x = 1 Setup: .long .L5 # x = 2 .long .L9 # x = 3 .long .L8 # x = 4 switch_eg: .long .L7 # x = 5 pushl %ebp # Setup .long .L7 # x = 6 movl %esp, %ebp # Setup movl 8(%ebp), %eax # eax = x cmpl $6, %eax # Compare x:6 Indirect ja .L8 # If unsigned > goto default jump jmp *.L4(,%eax,4) # Goto *JTab[x]
6 Carnegie Mellon
Assembly Setup Explana�on
¢ Table Structure Jump table §. Each target requires 4 bytes §. .section .rodata Base address .L4 at .align 4 .L4: .long .L8 # x = 0 .long .L3 # x = 1 ¢ Jumping .long .L5 # x = 2 §. Direct: .long .L9 # x = 3 jmp .L2 .long .L8 # x = 4 §. Jump target is denoted by label .long .L7 # x = 5 .L2 .long .L7 # x = 6
§. Indirect: jmp *.L4(,%eax,4) §. Start of jump .L4 table: §. Must scale by factor of 4 (labels have 32-‐bits = 4 Bytes on IA32) §. Fetch target from effec�ve .L4 Address + eax*4 §. Only for x 0 ≤ ≤ 6 7 Carnegie Mellon
Jump Table
Jump table switch(x) { .section .rodata case 1: // .L3 .align 4 w = y*z; .L4: break; .long .L8 # x = 0 .long .L3 # x = 1 case 2: // .L5 .long .L5 # x = 2 w = y/z; .long .L9 # x = 3 /* Fall Through */ .long .L8 # x = 4 .long .L7 # x = 5 case 3: // .L9 .long .L7 # x = 6 w += z; break; case 5: case 6: // .L7 w -= z; break; default: // .L8 w = 2; }
8 Carnegie Mellon
Code Blocks (x == 1)
switch(x) { .L3: # x == 1 case 1: // .L3 movl 12(%ebp), %eax # y w = y*z; imull 16(%ebp), %eax # w = y*z break; jmp .L2 # Goto done . . . }
9 Carnegie Mellon
Handling Fall-‐Through
long w = 1; . . . switch(x) { case 2: . . . w = y/z; case 2: goto merge; w = y/z; /* Fall Through */ case 3: w += z; break; . . . } case 3: w = 1;
merge: w += z;
10 Carnegie Mellon
Code Blocks (x == 2, x == 3)
.L5: # x == 2 long w = 1; movl 12(%ebp), %eax # y . . . cltd switch(x) { idivl 16(%ebp) # y/z . . . jmp .L6 # goto merge case 2: .L9: # x == 3 w = y/z; movl $1, %eax # w = 1 /* Fall Through */ .L6: # merge: case 3: addl 16(%ebp), %eax # += z w += z; jmp .L2 # goto done break; . . . }
11 Carnegie Mellon
Code Blocks (x == 5, x == 6, default)
switch(x) { .L7: # x == 5, 6 . . . movl $1, %eax # w = 1 case 5: // .L7 subl 16(%ebp), %eax # w -= z case 6: // .L7 jmp .L2 # goto done w -= z; .L8: # default break; movl $2, %eax # w = 2 default: // .L8 .L2: # done: w = 2; }
12 Carnegie Mellon
Switch Code (Finish)
.L2: # done: return w; popl %ebp ret
¢ Noteworthy Features §. Jump table avoids sequencing through cases §. Constant �me, rather than linear §. Use jump table to handle holes and duplicate tags §. Use program sequencing and/or jumps to handle fall-‐through §. Don’t ini�alize w = 1 unless really need it
13 Carnegie Mellon x86-‐64 Switch Implementa�on
¢ Same general idea, adapted to 64-‐bit code
¢ Table entries 64 bits (pointers)
¢ Cases use revised code Jump Table switch(x) { .section .rodata case 1: // .L3 .align 8 w = y*z; .L7: break; .quad .L8 # x = 0 . . . .quad .L3 # x = 1 } .quad .L5 # x = 2 .quad .L9 # x = 3 .quad .L8 # x = 4 .L3: .quad .L7 # X = 5 movq %rdx, %rax .quad .L7 # x = 6 imulq %rsi, %rax ret
14 Carnegie Mellon
IA32 Object Code
¢ Setup §. Label .L8 becomes address 0x80484b8 §. Label .L4 becomes address 0x8048680 Assembly Code switch_eg: . . . ja .L8 # If unsigned > goto default jmp *.L4(,%eax,4) # Goto *JTab[x]
Disassembled Object Code 08048480
15 Carnegie Mellon
IA32 Object Code (cont.)
¢ Jump Table §. Doesn’t show up in disassembled code §. Can inspect using GDB §. gdb switch §. (gdb) x/7xw 0x8048680 §. Examine 7 hexadecimal format “words” (4-‐bytes each) §. Use command help “ x” to get format documenta�on
0x8048680: 0x080484b8 0x08048492 0x0804849b 0x080484a4 0x8048690: 0x080484b8 0x080484ae 0x080484ae
16 Carnegie Mellon
IA32 Object Code (cont.)
¢ Deciphering Jump Table 0x8048680: 0x080484b8 0x08048492 0x0804849b 0x080484a4 0x8048690: 0x080484b8 0x080484ae 0x080484ae
Address Value x
0x8048680 0x80484b8 0 0x8048684 0x8048492 1 0x8048688 0x804849b 2 0x804868c 0x80484a4 3 0x8048690 0x80484b8 4 0x8048694 0x80484ae 5 0x8048698 0x80484ae 6
17 Carnegie Mellon
Disassembled Targets
8048492: 8b 45 0c mov 0xc(%ebp),%eax 8048495: 0f af 45 10 imul 0x10(%ebp),%eax 8048499: eb 22 jmp 80484bd
18 Carnegie Mellon
Matching Disassembled Targets
8048492: 8b 45 0c mov 0x 8048495: 0f af 45 10 imul 0x Value 8048499: eb 22 jmp 80 804849b: 8b 45 0c mov 0x 804849e: 99 cltd 0x80484b8 804849f: f7 7d 10 idivl 0x 0x8048492 80484a2: eb 05 jmp 80 80484a4: b8 01 00 00 00 mov $0 0x804849b 80484a9: 03 45 10 add 0x 80484ac: eb 0f jmp 80 0x80484a4 80484ae: b8 01 00 00 00 mov $0 80484b3: 2b 45 10 sub 0x 0x80484b8 80484b6: eb 05 jmp 80 0x80484ae 80484b8: b8 02 00 00 00 mov $0 0x80484ae
19 Carnegie Mellon Summarizing
¢ C Control §. if-‐then-‐else §. do-‐while §. while, for §. switch
¢ Assembler Control §. Condi�onal jump §. Condi�onal move §. Indirect jump §. Compiler generates code sequence to implement more complex control
¢ Standard Techniques §. Loops converted to do-‐while form §. Large switch statements use jump tables §. Sparse switch statements may use decision trees 20 Carnegie Mellon
Today
¢ Switch statements
¢ IA 32 Procedures §. Stack Structure §. Calling Conven�ons §. Illustra�ons of Recursion & Pointers
21 Carnegie Mellon
IA32 Stack Stack “Bo�om” ¢ Region of memory managed with stack discipline Increasing ¢ Grows toward lower addresses Addresses
¢ Register %esp contains lowest stack address §. address of “top” element Stack Grows Down Stack Pointer: %esp
Stack “Top”
22 Carnegie Mellon
IA32 Stack: Push Stack “Bo�om” ¢ pushl Src §. Fetch operand at Src §. Decrement by 4 Increasing %esp Addresses §. Write operand at address % given by esp
Stack Grows Down Stack Pointer: %esp -‐4
Stack “Top”
23 Carnegie Mellon
IA32 Stack: Pop Stack “Bo�om” ¢ popl Dest §. Read value at address % given by esp §. Increment by 4 Increasing %esp Addresses §. Store value at Dest (must be register)
Stack Grows +4 Down Stack Pointer: %esp
Stack “Top”
24 Carnegie Mellon
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 instruc�on right a�er call §. Example from disassembly 804854e: e8 3d 06 00 00 call 8048b90
25 Carnegie Mellon
Procedure Call Example
804854e: e8 3d 06 00 00 call 8048b90
call 8048b90
0x110 0x110 0x10c 0x10c 0x108 123 0x108 123 0x104 0x8048553
%esp 0x108 %esp 0x104
%eip 0x804854e %eip 0x8048b90
program counter %eip: 26 Carnegie Mellon
Procedure Return Example
8048591: c3 ret
ret
0x110 0x110 0x10c 0x10c 0x108 123 0x108 123 0x104 0x8048553 0x8048553
%esp 0x104 %esp 0x108
%eip 0x8048591 %eip 0x8048553
program counter %eip: 27 Carnegie Mellon
Stack-‐Based Languages
¢ Languages that support recursion §. e.g., C, Pascal, Java §. Code must be “Reentrant” §. Mul�ple simultaneous instan�a�ons of single procedure §. Need some place to store state of each instan�a�on §. Arguments §. Local variables §. Return pointer
¢ Stack discipline §. State for given procedure needed for limited �me §. From when called to when return §. Callee returns before caller does
¢ Stack allocated in Frames §. state for single procedure instan�a�on 28 Carnegie Mellon
Call Chain Example Example Call Chain yoo(…) { 9 yoo 9 who(…) who(); { who 9 999 9 amI(); } amI(…) amI amI 999 { amI(); 9 amI 999 9 } amI(); 9 amI 9 }
Procedure amI () is recursive
29 Carnegie Mellon
Stack Frames Previous ¢ Contents Frame §. Local variables §. Return informa�on Frame Pointer: %ebp §. Temporary space Frame for proc
Stack Pointer: %esp
¢ Management §. Space allocated when enter procedure Stack “Top” §. “Set-‐up” code §. Deallocated when return §. “Finish” code
30 Carnegie Mellon Stack Example
yoo(…) yoo %ebp { yooyoo 9 who %esp 9 who(); 9 amI amI 9 } amI
amI
31 Carnegie Mellon Stack Example
yoo(…) yoo { who(…) 9{ yooyoo who 9999 %ebp who(); amI(); 9999 amI amI who 9 amI(); %esp } 999 } amI
amI
32 Carnegie Mellon Stack Example
yoo(…) yoo { who(…) 9{ yooyoo amI(…) who 9999 { who(); amI(); 9 9999 amI amI who 9 9 amI(); amI(); %ebp } 999 } 9 amI amI 9 %esp } amI
33 Carnegie Mellon Stack Example yoo(…) yoo { who(…) 9{ yooyoo amI(…) who 9999 { who(); amI(); 9amI(…) 9999 amI amI who 9{ 9 amI(); amI9(); } 999 9 } 9 amI amI 9 amI(); } 9 %ebp 9 amI } amI %esp
34 Carnegie Mellon Stack Example yoo(…) yoo { who(…) 9{ yooyoo amI(…) who 9999 { who(); amI(); 9amI(…) 9999 amI amI who 9{ 9 amI(); amI(…) amI9(); } 999 9{ } 9 9 amI amI 9 amI(); 99 } amI(); 9 amI } 9 amI 9 } %ebp amI %esp
35 Carnegie Mellon Stack Example yoo(…) yoo { who(…) 9{ yooyoo amI(…) who 9999 { who(); amI(); 9amI(…) 9999 amI amI who 9{ 9 amI(); amI9(); } 999 9 } 9 amI amI 9 amI(); } 9 %ebp 9 amI } amI %esp
36 Carnegie Mellon Stack Example yoo(…) yoo { who(…) 9{ yooyoo amI(…) who 9999 { who(); amI(); 9 9999 amI amI who 9 9 amI(); amI(); %ebp } 999 } 9 amI amI 9 %esp } amI
37 Carnegie Mellon Stack Example yoo(…) yoo { who(…) 9{ yooyoo who 9999 %ebp who(); amI(); 9999 amI amI who 9 amI(); %esp } 999 } amI
amI
38 Carnegie Mellon Stack Example yoo(…) yoo { who(…) 9{ yooyoo amI(…) who 9999 { who(); amI(); 9 9999 amI amI who 9 9 amI(); amI(); %ebp } 999 } 9 amI amI 9 %esp } amI
39 Carnegie Mellon Stack Example yoo(…) yoo { who(…) 9{ yooyoo who 9999 %ebp who(); amI(); 9999 amI amI who 9 amI(); %esp } 999 } amI
amI
40 Carnegie Mellon Stack Example
yoo yoo(…) %ebp { yooyoo 9 who %esp 9 who(); amI amI 9 9 } amI
amI
41 Carnegie Mellon
IA32/Linux Stack Frame
¢ Current Stack Frame (“Top” to Bo�om) §. “Argument build:” Parameters for func�on about to call Caller Frame §. Local variables If can’t keep in registers Arguments §. Saved register context Frame pointer Return Addr §. Old frame pointer %ebp Old %ebp Saved Registers ¢ Caller Stack Frame + §. Return address Local §. Pushed by call instruc�on Variables §. Arguments for this call Argument Stack pointer Build %esp 42 Carnegie Mellon
Revisi�ng swap Calling swap from call_swap int course1 = 15213; call_swap: int course2 = 18213; GGG subl $24, %esp void call_swap() { movl $course2, 4(%esp) swap(&course1, &course2); movl $course1, (%esp) } call swap GGG
Resul�ng void swap(int *xp, int *yp) . . . Stack { int t0 = *xp; int t1 = *yp; &course2 *xp = t1; &course1 *yp = t0; Rtn adr } %esp
43 Carnegie Mellon
Revisi�ng swap swap: pushl %ebp Set void swap(int *xp, int *yp) movl %esp, %ebp Up { pushl %ebx int t0 = *xp; int t1 = *yp; movl 8(%ebp), %edx *xp = t1; movl 12(%ebp), %eax *yp = t0; movl (%edx), %ecx Body } movl (%eax), %ebx movl %ebx, (%edx) movl %ecx, (%eax)
popl %ebx popl %ebp Finish ret
44 Carnegie Mellon swap Setup #1 Entering Stack Resul�ng Stack
%ebp %ebp • • • • • •
&course2 yp &course1 xp Rtn adr %esp Rtn adr Old %ebp %esp
swap: pushl %ebp movl %esp,%ebp pushl %ebx 45 Carnegie Mellon swap Setup #2 Entering Stack Resul�ng Stack
%ebp • • • • • •
&course2 yp &course1 xp Rtn adr %esp Rtn adr Old %ebp %ebp %esp
swap: pushl %ebp movl %esp,%ebp pushl %ebx 46 Carnegie Mellon swap Setup #3 Entering Stack Resul�ng Stack
%ebp • • • • • •
&course2 yp &course1 xp Rtn adr %esp Rtn adr Old %ebp %ebp Old %ebx %esp swap: pushl %ebp movl %esp,%ebp pushl %ebx 47 Carnegie Mellon swap Body Entering Stack Resul�ng Stack
%ebp • • • • • • Offset rela�ve to %ebp 12 &course2 yp 8 &course1 xp Rtn adr %esp 4 Rtn adr Old %ebp %ebp Old %ebx %esp
movl 8(%ebp),%edx # get xp movl 12(%ebp),%eax # get yp . . .
48 Carnegie Mellon swap Finish Stack Before Finish Resul�ng Stack
%ebp • • • • • popl %ebx • popl %ebp
yp yp xp xp Rtn adr Rtn adr %esp Old %ebp %ebp
Old %ebx %esp ¢ Observa�on §. Saved and restored register %ebx §. Not so %eax for , %ecx , %edx
49 Carnegie Mellon
Disassembled swap 08048490
Today
¢ Switch statements
¢ IA 32 Procedures §. Stack Structure §. Calling Conven�ons §. Illustra�ons of Recursion & Pointers
51 Carnegie Mellon
Register Saving Conven�ons
¢ When procedure yoo calls who: §. yoo is the caller §. who is the callee
¢ Can register be used for temporary storage?
yoo: who: GGG GGG movl $15213, %edx movl 8(%ebp), %edx call who addl $18213, %edx addl %edx, %eax GGG GGG ret ret §. Contents of register % edx overwri�en by who §. This could be trouble ➙ something should be done! §. Need some coordina�on
52 Carnegie Mellon
Register Saving Conven�ons
¢ When procedure yoo calls who: §. yoo is the caller §. who is the callee
¢ Can register be used for temporary storage?
¢ Conven�ons §. “Caller Save” §. Caller saves temporary values in its frame before the call §. “Callee Save” §. Callee saves temporary values in its frame before using
53 Carnegie Mellon
IA32/Linux+Windows Register Usage
¢ %eax, % edx, % ecx %eax §. Caller saves prior to call if values Caller-‐Save are used later Temporaries %edx %ecx ¢ %eax %ebx §. also used to return integer value Callee-‐Save Temporaries %esi %edi ¢ %ebx, % esi, % edi §. Callee saves if wants to use them Special %esp %ebp ¢ %esp, % ebp §. special form of callee save §. Restored to original values upon exit from procedure 54 Carnegie Mellon
Today
¢ Switch statements
¢ IA 32 Procedures §. Stack Structure §. Calling Conven�ons §. Illustra�ons of Recursion & Pointers
55 Carnegie Mellon
Recursive Func�on pcount_r: pushl %ebp /* Recursive popcount */ movl %esp, %ebp int pcount_r(unsigned x) { pushl %ebx if (x == 0) subl $20, %esp return 0; movl 8(%ebp), %ebx else return movl $0, %eax (x & 1) + pcount_r(x >> 1); testl %ebx, %ebx } je .L3 movl %ebx, %eax shrl %eax movl %eax, (%esp) ¢ Registers call pcount_r §. % eax, % edx used without first movl %ebx, %edx saving andl $1, %edx addl %edx, %eax §. % ebx used, but saved at beginning & restored at end .L3: addl $20, %esp popl %ebx popl %ebp ret 56 Carnegie Mellon
pcount_r: Recursive Call #1 pushl %ebp movl %esp, %ebp /* Recursive popcount */ pushl %ebx int pcount_r(unsigned x) { subl $20, %esp if (x == 0) movl 8(%ebp), %ebx return 0; GGG else return (x & 1) + pcount_r(x >> 1); • } • • x ¢ Ac�ons Rtn adr §. Save old value of on stack %ebx Old %ebp %ebp §. Allocate space for argument to Old %ebx recursive call §. Store x % in ebx Unused
%ebx x %esp
57 Carnegie Mellon
Recursive Call #2 GGG movl $0, %eax /* Recursive popcount */ testl %ebx, %ebx int pcount_r(unsigned x) { je .L3 if (x == 0) GGG return 0; .L3: else return GGG (x & 1) + pcount_r(x >> 1); ret }
¢ Ac�ons §. If x == 0, return §. with % eax set to 0
%ebx x
58 Carnegie Mellon
Recursive Call #3 GGG movl %ebx, %eax /* Recursive popcount */ shrl %eax int pcount_r(unsigned x) { movl %eax, (%esp) if (x == 0) call pcount_r return 0; GGG else return (x & 1) + pcount_r(x >> 1); } • • • ¢ Ac�ons Rtn adr §. Store x >> 1 on stack Old %ebp %ebp §. Make recursive call Old %ebx ¢ Effect §. %eax set to func�on result Unused §. %ebx s�ll has value of x x >> 1 %esp %ebx x 59 Carnegie Mellon
Recursive Call #4
/* Recursive popcount */ GGG int pcount_r(unsigned x) { movl %ebx, %edx if (x == 0) andl $1, %edx return 0; addl %edx, %eax else return GGG (x & 1) + pcount_r(x >> 1); }
¢ Assume §. %eax holds value from recursive call §. %ebx holds x %ebx x ¢ Ac�ons §. Compute (x & 1) + computed value
¢ Effect §. %eax set to func�on result 60 Carnegie Mellon Recursive Call #5
/* Recursive popcount */ GGG int pcount_r(unsigned x) { L3: if (x == 0) addl $20, %esp return 0; popl %ebx else return popl %ebp (x & 1) + pcount_r(x >> 1); ret }
• • ¢ Ac�ons %ebp • • §. Restore values of Rtn adr • %ebx and % ebp • Old %ebp §. Restore % esp %ebp %esp Old %ebx
Unused %ebx Old %ebx x >> 1 %esp 61 Carnegie Mellon
Observa�ons About Recursion
¢ Handled Without Special Considera�on §. Stack frames mean that each func�on call has private storage §. Saved registers & local variables §. Saved return pointer §. Register saving conven�ons prevent one func�on call from corrup�ng another’s data §. Stack discipline follows call / return pa�ern §. If P calls Q, then Q returns before P §. Last-‐In, First-‐Out
¢ Also works for mutual recursion §. P calls Q; Q calls P
62 Carnegie Mellon
Pointer Code
Genera�ng Pointer /* Compute x + 3 */ int add3(int x) { int localx = x; incrk(&localx, 3); return localx; }
Referencing Pointer /* Increment value by k */ void incrk(int *ip, int k) { *ip += k; }
¢ add3 creates pointer and passes it to incrk 63 Carnegie Mellon
Crea�ng and Ini�alizing Local Variable
¢ int add3(int x) { Variable localx must be stored on int localx = x; stack incrk(&localx, 3); §. Because: Need to create pointer to it return localx; } ¢ Compute pointer as -‐4(%ebp)
8 x 4 Rtn adr Old First part of 0 %ebp %ebp add3 localx -4 add3: = x pushl %ebp -8 movl %esp, %ebp -12 Unused subl $24, %esp # Alloc. 24 bytes movl 8(%ebp), %eax -16 movl %eax, -4(%ebp) # Set localx to x -20 -24 %esp 64 Carnegie Mellon
Crea�ng Pointer as Argument
¢ int add3(int x) { Use leal instruc�on to compute int localx = x; address of localx incrk(&localx, 3); return localx; }
8 x 4 Rtn adr 0 Old %ebp %ebp Middle part add3 of -4 localx movl $3, 4(%esp) # 2nd arg = 3 leal -4(%ebp), %eax # &localx -8 st movl %eax, (%esp) # 1 arg = &localx -12 Unused call incrk -16 -20 3 %esp+4 -24 %esp 65 Carnegie Mellon
Retrieving local variable
¢ int add3(int x) { Retrieve localx from stack as return int localx = x; value incrk(&localx, 3); return localx; }
8 x 4 Rtn adr 0 Old %ebp %ebp Final part add3 of -4 localx movl -4(%ebp), %eax # Return val= localx leave -8 ret -12 Unused -16 -20 -24 %esp 66 Carnegie Mellon
IA32 Op�miza�on: Inlining
¢ When both func�ons in Genera�ng Pointer same file: /* Compute x + 3 */ int add3(int x) { add3: int localx = x; pushl %ebp incrk(&localx, 3); movl %esp, %ebp return localx; movl 8(%ebp), %eax } addl $3, %eax popl %ebp Referencing Pointer ret /* Increment value by k */ void incrk(int *ip, int k) { *ip += k; }
67 Carnegie Mellon
How Inlining Works
Genera�ng Pointer Expand callee into caller /* Compute x + 3 */ /* Compute x + 3 */ int add3(int x) { int add3_inline(int x) { int localx = x; int localx = x; incrk(&localx, 3); *(&localx) += 3; return localx; return localx; } }
Referencing Pointer /* Increment value by k */ void incrk(int *ip, int k) { *ip += k; }
68 Carnegie Mellon
IA 32 Procedure Summary
¢ Important Points §. Stack is the right data structure for procedure call / return Caller Frame §. If P calls Q, then Q returns before P Arguments ¢ Recursion (& mutual recursion) handled by normal calling conven�ons Return Addr Old %ebp §. Can safely store values in local stack frame and in %ebp callee-‐saved registers Saved §. Put func�on arguments at top of stack Registers §. Result return in + %eax Local ¢ Pointers are addresses of values Variables §. On stack or global Argument Build %esp 69