1 Assembly Language: Function Calls Jennifer Rexford.

Slides:



Advertisements
Similar presentations
Machine-Level Programming III: Procedures Feb. 8, 2000 Topics IA32 stack Stack-based languages Stack frames Register saving conventions Creating pointers.
Advertisements

Calling sequence ESP.
University of Washington Procedures and Stacks II The Hardware/Software Interface CSE351 Winter 2013.
C Programming and Assembly Language Janakiraman V – NITK Surathkal 2 nd August 2014.
Machine Programming – Procedures and IA32 Stack CENG334: Introduction to Operating Systems Instructor: Erol Sahin Acknowledgement: Most of the slides are.
University of Washington Last Time For loops  for loop → while loop → do-while loop → goto version  for loop → while loop → goto “jump to middle” version.
1 Storage Registers vs. memory Access to registers is much faster than access to memory Goal: store as much data as possible in registers Limitations/considerations:
Context Switch Animation Another one by Anastasia.
Machine-Level Programming III: Procedures Apr. 17, 2006 Topics IA32 stack discipline Register saving conventions Creating pointers to local variables CS213.
PC hardware and x86 3/3/08 Frans Kaashoek MIT
1 Function Calls Professor Jennifer Rexford COS 217 Reading: Chapter 4 of “Programming From the Ground Up” (available online from the course Web site)
Accessing parameters from the stack and calling functions.
Machine-Level Programming III: Procedures Sept. 17, 2007 IA32 stack discipline Register saving conventions Creating pointers to local variablesx86-64 Argument.
– 1 – , F’02 ICS05 Instructor: Peter A. Dinda TA: Bin Lin Recitation 4.
1 Homework Reading –PAL, pp , Machine Projects –Finish mp2warmup Questions? –Start mp2 as soon as possible Labs –Continue labs with your.
Machine-Level Programming III: Procedures Jan 30, 2003
Assembly תרגול 8 פונקציות והתקפת buffer.. Procedures (Functions) A procedure call involves passing both data and control from one part of the code to.
Machine-Level Programming III: Procedures Sept. 15, 2006 IA32 stack discipline Register saving conventions Creating pointers to local variablesx86-64 Argument.
September 22, 2014 Pengju (Jimmy) Jin Section E
Stack Activation Records Topics IA32 stack discipline Register saving conventions Creating pointers to local variables February 6, 2003 CSCE 212H Computer.
Stacks and Frames Demystified CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han.
6.828: PC hardware and x86 Frans Kaashoek
Computer Architecture and Operating Systems CS 3230 :Assembly Section Lecture 7 Department of Computer Science and Software Engineering University of Wisconsin-Platteville.
Fall 2008CS 334: Computer SecuritySlide #1 Smashing The Stack A detailed look at buffer overflows as described in Smashing the Stack for Fun and Profit.
Carnegie Mellon Introduction to Computer Systems /18-243, spring 2009 Recitation, Jan. 14 th.
1 Carnegie Mellon Stacks : Introduction to Computer Systems Recitation 5: September 24, 2012 Joon-Sup Han Section F.
Ithaca College Machine-Level Programming IV: IA32 Procedures Comp 21000: Introduction to Computer Systems & Assembly Lang Spring 2013 * Modified slides.
Machine-Level Programming III: Switch Statements and IA32 Procedures Seoul National University.
University of Washington Today More on procedures, stack etc. Lab 2 due today!  We hope it was fun! What is a stack?  And how about a stack frame? 1.
Code Generation Gülfem Savrun Yeniçeri CS 142 (b) 02/26/2013.
CSc 453 Runtime Environments Saumya Debray The University of Arizona Tucson.
Fabián E. Bustamante, Spring 2007 Machine-Level Programming III - Procedures Today IA32 stack discipline Register saving conventions Creating pointers.
Microprocessors The ia32 User Instruction Set Jan 31st, 2002.
Low Level Programming Lecturer: Duncan Smeed The Interface Between High-Level and Low-Level Languages.
Machine-level Programming III: Procedures Topics –IA32 stack discipline –Register saving conventions –Creating pointers to local variables.
Functions/Methods in Assembly
Compiler Construction Code Generation Activation Records
University of Amsterdam Computer Systems – the instruction set architecture Arnoud Visser 1 Computer Systems The instruction set architecture.
Overview of Back-end for CComp Zhaopeng Li Software Security Lab. June 8, 2009.
IA32 Stack –Region of memory managed with stack discipline –Grows toward lower addresses –Register %esp indicates lowest stack address address of top element.
ICS51 Introductory Computer Organization Accessing parameters from the stack and calling functions.
Section 5: Procedures & Stacks
Recitation 3: Procedures and the Stack
CS 177 Computer Security Lecture 9
Assembly function call convention
Reading Condition Codes (Cont.)
C function call conventions and the stack
IA32 Processors Evolutionary Design
143A: Principles of Operating Systems Lecture 4: Calling conventions
Aaron Miller David Cohen Spring 2011
Homework In-line Assembly Code Machine Language
Introduction to Compilers Tim Teitelbaum
Carnegie Mellon Machine-Level Programming III: Switch Statements and IA32 Procedures / : Introduction to Computer Systems 7th Lecture, Sep.
Chapter 3 Machine-Level Representation of Programs
Computer Architecture adapted by Jason Fritts then by David Ferry
Machine-Level Programming III: Switch Statements and IA32 Procedures
Machine-Level Programming 4 Procedures
Condition Codes Single Bit Registers
Assembly Language Programming II: C Compiler Calling Sequences
Machine-Level Programming III: Procedures Sept 18, 2001
MIPS Procedure Calls CSE 378 – Section 3.
Multi-modules programming
Chapter 3 Machine-Level Representation of Programs
X86 Assembly Review.
Machine-Level Representation of Programs (x86-64)
Where is all the knowledge we lost with information? T. S. Eliot
“Way easier than when we were students”
Presentation transcript:

1 Assembly Language: Function Calls Jennifer Rexford

2 Goals of this Lecture Function call problems: Calling and returning Passing parameters Storing local variables Handling registers without interference Returning values IA-32 solutions to those problems Pertinent instructions and conventions

3 Recall from Last Lecture Examples of Operands Immediate Operand movl $5, … CPU uses 5 as source operand movl $i, … CPU uses address denoted by i as source operand Register Operand movl %eax, … CPU uses contents of EAX register as source operand

4 Recall from Last Lecture (cont.) Memory Operand: Direct Addressing movl i, … CPU fetches source operand from memory at address i Memory Operand: Indirect Addressing movl (%eax), … CPU considers contents of EAX to be an address Fetches source operand from memory at that address Memory Operand: Base+Displacement Addressing movl 8(%eax), … CPU computes address as 8 + [contents of EAX] Fetches source operand from memory at that address

5 Recall from Last Lecture (cont.) Memory Operand: Indexed Addressing movl 8(%eax, %ecx), … Computes address as 8 + [contents of EAX] + [contents of ECX] Fetches source operand from memory at that address Memory Operand: Scaled Indexed Addressing movl 8(%eax, %ecx, 4), … Computes address as 8 + [contents of EAX] + ([contents of ECX] * 4) Fetches source operand from memory at that address Same for destination operand, except… Destination operand cannot be immediate

6 Function Call Problems 1.Calling and returning How does caller function jump to callee function? How does callee function jump back to the right place in caller function? 2.Passing parameters How does caller function pass parameters to callee function? 3.Storing local variables Where does callee function store its local variables? 4.Handling registers How do caller and callee functions use same registers without interference? 5.Returning a value How does callee function send return value back to caller function?

7 Problem 1: Calling and Returning How does caller function jump to callee function? I.e., Jump to the address of the callee’s first instruction How does the callee function jump back to the right place in caller function? I.e., Jump to the instruction immediately following the most-recently-executed call instruction

8 Attempted Solution: Use Jmp Instruction Attempted solution: caller and callee use jmp instruction P:# Function P … jmp R# Call R Rtn_point1: … R:# Function R … jmp Rtn_point1 # Return

9 Attempted Solution: Use Jmp Instruction Problem: callee may be called by multiple callers P:# Function P … jmp R# Call R Rtn_point1: … R:# Function R … jmp ??? # Return Q:# Function Q … jmp R# Call R Rtn_point2: …

10 Attempted Solution: Use Register P:# Function P movl $Rtn_point1, %eax jmp R# Call R Rtn_point1: … Q:# Function Q movl $Rtn_point2, %eax jmp R# Call R Rtn_point2: … R:# Function R … jmp *%eax# Return Attempted solution 2: Store return address in register Special form of jmp instruction; we will not use

11 Attempted Solution: Use Register P:# Function P movl $Rtn_point1, %eax jmp Q# Call Q Rtn_point1: … Q:# Function Q movl $Rtn_point2, %eax jmp R# Call R Rtn_point2: … jmp %eax# Return R:# Function R … jmp *%eax# Return Problem if P calls Q, and Q calls R Return address for P to Q call is lost Problem: Cannot handle nested function calls

12 May need to store many return addresses The number of nested functions is not known in advance A return address must be saved for as long as the function invocation continues, and discarded thereafter Addresses used in reverse order E.g., function P calls Q, which then calls R Then R returns to Q which then returns to P Last-in-first-out data structure (stack) Caller pushes return address on the stack … and callee pops return address off the stack IA 32 solution: Use the stack via call and ret IA-32 Solution: Use the Stack EIP for P EIP for Q

13 IA-32 Call and Ret Instructions P:# Function P … call R call Q … Q:# Function Q … call R … ret R:# Function R … ret Ret instruction “knows” the return address 1 2

14 IA-32 Call and Ret Instructions P:# Function P … call R call Q … Q:# Function Q … call R … ret R:# Function R … ret Ret instruction “knows” the return address

15 Implementation of Call InstructionEffective Operations pushl srcsubl $4, %esp movl src, (%esp) popl destmovl (%esp), dest addl $4, %esp ESP 0 ESP (stack pointer register) points to top of stack

16 Implementation of Call InstructionEffective Operations pushl srcsubl $4, %esp movl src, (%esp) popl destmovl (%esp), dest addl $4, %esp call addrpushl %eip jmp addr ESP before call 0 Note: can’t really access EIP directly, but this is implicitly what call is doing Call instruction pushes return address (old EIP) onto stack EIP (instruction pointer register) points to next instruction to be executed

17 Implementation of Call InstructionEffective Operations pushl srcsubl $4, %esp movl src, (%esp) popl destmovl (%esp), dest addl $4, %esp call addrpushl %eip jmp addr ESP after call 0 Old EIP

18 Implementation of Ret InstructionEffective Operations pushl srcsubl $4, %esp movl src, (%esp) popl destmovl (%esp), dest addl $4, %esp call addrpushl %eip jmp addr retpop %eip ESP before ret 0 Note: can’t really access EIP directly, but this is implicitly what ret is doing. Old EIP Ret instruction pops stack, thus placing return address (old EIP) into EIP

19 Implementation of Ret InstructionEffective Operations pushl srcsubl $4, %esp movl src, (%esp) popl destmovl (%esp), dest addl $4, %esp call addrpushl %eip jmp addr retpop %eip ESP after ret 0

20 Problem 2: Passing Parameters Problem: How does caller function pass parameters to callee function? int add3(int a, int b, int c) { int d; d = a + b + c; return d; } int f(void) { return add3(3, 4, 5); }

21 Attempted Solution: Use Registers Attempted solution: Pass parameters in registers f: movl $3, %eax movl $4, %ebx movl $5, %ecx call add3 … add3: … # Use EAX, EBX, ECX … ret

22 Attempted Solution: Use Registers Problem: Cannot handle nested function calls Also: How to pass parameters that are longer than 4 bytes? f: movl $3, %eax movl $4, %ebx movl $5, %ecx call add3 … add3: … movl $6, %eax call g # Use EAX, EBX, ECX # But EAX is corrupted! … ret

23 IA-32 Solution: Use the Stack ESP before pushing params 0 Caller pushes parameters before executing the call instruction

24 IA-32 Parameter Passing ESP before call 0 Caller pushes parameters in the reverse order Push N th param first Push 1 st param last So first param is at top of the stack at the time of the Call Param N Param 1 Param …

25 IA-32 Parameter Passing ESP after call 0 Callee addresses params relative to ESP: Param 1 as 4(%esp) Param N Param 1 Param … Old EIP

26 IA-32 Parameter Passing ESP after return 0 After returning to the caller… Param N Param 1 Param …

27 IA-32 Parameter Passing ESP after popping params 0 … the caller pops the parameters from the stack

28 IA-32 Parameter Passing For example: f: … # Push parameters pushl $5 pushl $4 pushl $3 call add3 # Pop parameters addl $12, %esp add3: … movl 4(%esp), wherever movl 8(%esp), wherever movl 12(%esp), wherever … ret

29 Base Pointer Register: EBP ESP after call 0 Problem: As callee executes, ESP may change E.g., preparing to call another function Error-prone for callee to reference params as offsets relative to ESP Solution: Use EBP as fixed reference point to access params Param N Param 1 Param … Old EIP EBP

30 Need to save old value of EBP Before overwriting EBP register Callee executes “prolog” pushl %ebp movl %esp, %ebp Using EBP ESP 0 Param N Param 1 Param … Old EIP Old EBP EBP

31 Callee executes “prolog” pushl %ebp movl %esp, %ebp Regardless of ESP, callee can reference param 1 as 8(%ebp), param 2 as 12(%ebp), etc. Base Pointer Register: EBP ESP, EBP 0 Param N Param 1 Param … Old EIP Old EBP

32 Base Pointer Register: EBP EBP 0 Param N Param 1 Param … Old EIP Old EBP Before returning, callee must restore ESP and EBP to their old values Callee executes “epilog” movl %ebp, %esp popl %ebp ret ESP

33 Base Pointer Register: EBP ESP, EBP 0 Param N Param 1 Param … Old EIP Old EBP Callee executes “epilog” movl %ebp, %esp popl %ebp ret

34 Base Pointer Register: EBP ESP 0 Param N Param 1 Param … Old EIP Callee executes “epilog” movl %ebp, %esp popl %ebp ret EBP

35 Base Pointer Register: EBP ESP 0 Param N Param 1 Param … Callee executes “epilog” movl %ebp, %esp popl %ebp ret EBP

36 Problem 3: Storing Local Variables Where does callee function store its local variables? int add3(int a, int b, int c) { int d; d = a + b + c; return d; } int foo(void) { return add3(3, 4, 5); }

37 IA-32 Solution: Use the Stack Local variables: Short-lived, so don’t need a permanent location in memory Size known in advance, so don’t need to allocate on the heap So, the function just uses the top of the stack Store local variables on the top of the stack The local variables disappear after the function returns int add3(int a, int b, int c) { int d; d = a + b + c; return d; } int foo(void) { return add3(3, 4, 5); }

38 IA-32 Local Variables EBP 0 Param N Param 1 Param … Old EIP Old EBP Local variables of the callee are allocated on the stack Allocation done by moving the stack pointer Example: allocate memory for two integers subl $4, %esp (or equivalently, subl $8, %esp) Reference local variables as negative offsets relative to EBP -4(%ebp) -8(%ebp) ESP Var 1 Var 2

39 IA-32 Local Variables For example: add3: … # Allocate space for d subl $4, %esp … # Access d movl whatever, -4(%ebp) … ret

40 Problem 4: Handling Registers Problem: How do caller and callee functions use same registers without interference? Registers are a finite resource! In principle: Each function should have its own set of registers In reality: All functions must use the same small set of registers Callee may use a register that the caller also is using When callee returns control to caller, old register contents may be lost Caller function cannot continue where it left off

41 IA-32 Solution: Define a Convention IA-32 solution: save the registers on the stack Someone must save old register contents Someone must later restore the register contents Define a convention for who saves and restores which registers

42 IA-32 Register Handling EBP 0 Param N Param 1 Param … Old EIP Old EBP Caller-save registers EAX, EDX, ECX If necessary… Caller saves on stack before call Caller restores from stack after call Callee-save registers EBX, ESI, EDI If necessary… Callee saves on stack after prolog Callee restores from stack before epilog Caller can assume that values in EBX, ESI, EDI will not be changed by callee ESP Var 1 Var 2 Saved EAX, EDX,ECX Saved EBX, ESI,EDI

43 Problem 5: Return Values Problem: How does callee function send return value back to caller function? In principle: Store return value in stack frame of caller Or, for efficiency: Known small size => store return value in register Other => store return value in stack int add3(int a, int b, int c) { int d; d = a + b + c; return d; } int foo(void) { return add3(3, 4, 5); }

44 IA-32 Return Values IA-32 Convention: Integral type or pointer: Store return value in EAX char, short, int, long, pointer Floating-point type: Store return value in floating- point register (Beyond scope of course) Structure: Store return value on stack (Beyond scope of course) int add3(int a, int b, int c) { int d; d = a + b + c; return d; } int foo(void) { return add3(3, 4, 5); }

45 Stack Frames Summary of IA-32 function handling: Stack has one stack frame per active function invocation ESP points to top (low memory) of current stack frame EBP points to bottom (high memory) of current stack frame Stack frame contains: Return address (Old EIP) Old EBP Saved register values Local variables Parameters to be passed to callee function

46 A Simple Example int add3(int a, int b, int c) { int d; d = a + b + c; return d; } /* In some calling function */ … x = add3(3, 4, 5); …

47 Trace of a Simple Example 1 ESP EBP x = add3(3, 4, 5); High memory Low memory

48 Trace of a Simple Example 2 Old EAX Old ECX Old EDX ESP EBP # Save caller-save registers if necessary pushl %eax pushl %ecx pushl %edx x = add3(3, 4, 5); High memory Low memory

49 Trace of a Simple Example 3 Old EAX Old ECX Old EDX ESP EBP # Save caller-save registers if necessary pushl %eax pushl %ecx pushl %edx # Push parameters pushl $5 pushl $4 pushl $3 x = add3(3, 4, 5); High memory Low memory

50 Trace of a Simple Example 4 # Save caller-save registers if necessary pushl %eax pushl %ecx pushl %edx # Push parameters pushl $5 pushl $4 pushl $3 # Call add3 call add3 Old EAX Old ECX Old EDX Old EIP ESP EBP x = add3(3, 4, 5); High memory Low memory

51 Trace of a Simple Example 5 # Save old EBP pushl %ebp int add3(int a, int b, int c) { int d; d = a + b + c; return d; } Old EAX Old ECX Old EDX Old EIP Old EBP ESP EBP Prolog High memory Low memory

52 Trace of a Simple Example 6 # Save old EBP pushl %ebp # Change EBP movl %esp, %ebp int add3(int a, int b, int c) { int d; d = a + b + c; return d; } EBP Old EAX Old ECX Old EDX Old EIP Old EBP ESP Prolog High memory Low memory

53 Trace of a Simple Example 7 # Save old EBP pushl %ebp # Change EBP movl %esp, %ebp # Save caller-save registers if necessary pushl %ebx pushl %esi pushl %edi int add3(int a, int b, int c) { int d; d = a + b + c; return d; } EBP Old EAX Old ECX Old EDX Old EIP Old EBP Old EBX Old ESI Old EDI ESP Unnecessary here; add3 will not change the values in these registers High memory Low memory

54 Trace of a Simple Example 8 # Save old EBP pushl %ebp # Change EBP movl %esp, %ebp # Save caller-save registers if necessary pushl %ebx pushl %esi pushl %edi # Allocate space for local variable subl $4, %esp int add3(int a, int b, int c) { int d; d = a + b + c; return d; } EBP Old EAX Old ECX Old EDX Old EIP Old EBP Old EBX Old ESI Old EDI ESP High memory Low memory

55 Trace of a Simple Example 9 # Save old EBP pushl %ebp # Change EBP movl %esp, %ebp # Save caller-save registers if necessary pushl %ebx pushl %esi pushl %edi # Allocate space for local variable subl $4, %esp # Perform the addition movl 8(%ebp), %eax addl 12(%ebp), %eax addl 16(%ebp), %eax movl %eax, -16(%ebp) int add3(int a, int b, int c) { int d; d = a + b + c; return d; } EBP Old EAX Old ECX Old EDX Old EIP Old EBP Old EBX Old ESI Old EDI 12 ESP High memory Low memory Access params as positive offsets relative to EBP Access local vars as negative offsets relative to EBP

56 Trace of a Simple Example 10 # Copy the return value to EAX movl -16(%ebp), %eax # Restore callee-save registers if necessary movl -12(%ebp), %edi movl -8(%ebp), %esi movl -4(%ebp), %ebx int add3(int a, int b, int c) { int d; d = a + b + c; return d; } EBP Old EAX Old ECX Old EDX Old EIP Old EBP Old EBX Old ESI Old EDI 12 ESP High memory Low memory

57 Trace of a Simple Example 11 # Copy the return value to EAX movl -16(%ebp), %eax # Restore callee-save registers if necessary movl -12(%ebp), %edi movl -8(%ebp), %esi movl -4(%ebp), %ebx # Restore ESP movl %ebp, %esp int add3(int a, int b, int c) { int d; d = a + b + c; return d; } EBP Old EAX Old ECX Old EDX Old EIP Old EBP Old EBX Old ESI Old EDI 12 ESP Epilog High memory Low memory

58 Trace of a Simple Example 12 # Copy the return value to EAX movl -16(%ebp), %eax # Restore callee-save registers if necessary movl -12(%ebp), %edi movl -8(%ebp), %esi movl -4(%ebp), %ebx # Restore ESP movl %ebp, %esp # Restore EBP popl %ebp int add3(int a, int b, int c) { int d; d = a + b + c; return d; } EBP Old EAX Old ECX Old EDX Old EIP Old EBP Old EBX Old ESI Old EDI 12 ESP Epilog High memory Low memory

59 Trace of a Simple Example 13 # Copy the return value to EAX movl -16(%ebp), %eax # Restore callee-save registers if necessary movl -12(%ebp), %edi movl -8(%ebp), %esi movl -4(%ebp), %ebx # Restore ESP movl %ebp, %esp # Restore EBP popl %ebp # Return to calling function ret int add3(int a, int b, int c) { int d; d = a + b + c; return d; } EBP Old EAX Old ECX Old EDX Old EIP Old EBP Old EBX Old ESI Old EDI 12 ESP High memory Low memory

60 Trace of a Simple Example 14 # Save caller-save registers if necessary pushl %eax pushl %ecx pushl %edx # Push parameters pushl $5 pushl $4 pushl $3 # Call add3 call add3 # Pop parameters addl $12, %esp EBP Old EAX Old ECX Old EDX Old EIP Old EBP Old EBX Old ESI Old EDI 12 ESP x = add3(3, 4, 5); High memory Low memory

61 Trace of a Simple Example 15 # Save caller-save registers if necessary pushl %eax pushl %ecx pushl %edx # Push parameters pushl $5 pushl $4 pushl $3 # Call add3 call add3 # Pop parameters addl %12, %esp # Save return value movl %eax, wherever EBP Old EAX Old ECX Old EDX Old EIP Old EBP Old EBX Old ESI Old EDI 12 ESP x = add3(3, 4, 5); High memory Low memory

62 Trace of a Simple Example 16 # Save caller-save registers if necessary pushl %eax pushl %ecx pushl %edx # Push parameters pushl $5 pushl $4 pushl $3 # Call add3 call add3 # Pop parameters addl %12, %esp # Save return value movl %eax, wherever # Restore caller-save registers if necessary popl %edx popl %ecx popl %eax x = add3(3, 4, 5); EBP Old EAX Old ECX Old EDX Old EIP Old EBP Old EBX Old ESI Old EDI 12 ESP High memory Low memory

63 Trace of a Simple Example 17 # Save caller-save registers if necessary pushl %eax pushl %ecx pushl %edx # Push parameters pushl $5 pushl $4 pushl $3 # Call add3 call add3 # Pop parameters addl %12, %esp # Save return value movl %eax, wherever # Restore caller-save registers if necessary popl %edx popl %ecx popl %eax # Proceed! … x = add3(3, 4, 5); EBP ESP High memory Low memory

64 Summary Calling and returning Call instruction: push EIP onto stack and jump Ret instruction: pop stack to EIP Passing parameters Caller pushes onto stack Callee accesses as positive offsets from EBP Caller pops from stack

65 Summary (cont.) Storing local variables Callee pushes on stack Callee accesses as negative offsets from EBP Callee pops from stack Handling registers Caller saves and restores EAX, ECX, EDX if necessary Callee saves and restores EBX, ESI, EDI if necessary Returning values Callee returns data of integral types and pointers in EAX