Goals of Today’s Lecture

• Finishing introduction to assembly language o EFLAGS register and conditional jumps o Addressing modes • Memory layout of the UNIX process Function Calls o Data, BSS, roData, Text o Stack frames, and the stack pointer ESP • Calling functions Prof. David August o Call and ret commands COS 217 o Placing arguments on the stack o Using the base pointer EBP

Reading: Chapter 4 of “Programming From the Ground Up”

(available online from the course Web site) 1 2

n %edx Detailed Example count %ecx Setting the EFLAGS Register movl $0, %ecx • Comparison cmpl compares two integers .loop: cmpl $1, %edx o Done by subtracting the first number from the second count=0; jle .endloop – Discarding the results, but setting the eflags register Example: while (n>1) { addl $1, %ecx o movl %edx, %eax – cmpl $1, %edx (computes %edx – 1) count++; andl $1, %eax – jle .endloop (looks at the sign flag and the ) je .else if (n&1) • Logical operation compares two integers movl %edx, %eax andl n = n*3+1; addl %eax, %edx o Example: else addl %eax, %edx – andl $1, %eax (bit-wise AND of %eax with 1) addl $1, %edx – je .else (looks at the zero flag) n = n/2; jmp .endif .else: • Unconditional branch } sarl $1, %edx jmp .endif: o Example: jmp .loop – jmp .endif and jmp .loop .endloop: 3 4 EFLAGS Register & Condition Codes A Simple Assembly Program

31 22 101112131415161718192021 0123456789 .section .data .section .text V V IO Reserved (set to 0) I I I A V R 0 N P O D I T S Z 0 A 0 P 1 C # pre-initialized .globl _start D P F C M F T L F F F F F F F F F # variables go here _start: Identification flag Virtual interrupt pending # Program starts executing Virtual # here Alignment check .section .bss Virtual 8086 mode Resume flag # zero-initialized # Body of the program goes Nested task flag # variables go here # here I/O privilege level # Program ends with an Interrupt enable flag .section .rodata # “exit()” system call Sign flag # pre-initialized # to the operating system Zero flag # constants go here movl $1, %eax Auxiliary or adjust flag movl $0, %ebx Carry flag 5 int $0x80 6

Main Parts of the Program Function Calls

• Break program into sections (.section) • Function o Data, BSS, RoData, and Text o A piece of code with well-defined entry and exit points, and a well- defined interface • Starting the program o Making _start a global (.global _start) • “Call” and “Return” abstractions – Tells the assembler to remember the symbol _start o Call: jump to the beginning of an arbitrary procedure – … because the linker will need it o Return: jump to the instruction immediately following the “most- o Identifying the start of the program (_start) recently-executed” Call instruction – Defines the value of the label _start • The jump address in the return operation is dynamically • Exiting the program determined o Specifying the exit() system call (movl $1, %eax) – Linux expects the system call number in EAX register o Specifying the status code (movl $0, %ebx) – Linux expects the status code in EBX register o Interrupting the operating system (int $0x80) 7 8 Implementing Function Calls Implementing Function Calls

P: # Function P R: # Function R P: # Proc P R: # Proc R … … movl $Rtn_point1, %eax … jmp R # Call R jmp ??? # Return jmp R # Call R jmp %eax # Return Rtn_point1: Rtn_point1: … …

Q: # Function Q Q: # Proc Q … movl $Rtn_point2, %eax Convention: At Call time, What should the return store return address in EAX jmp R # Call R instruction in R jump to? jmp R # Call R Rtn_point2: Rtn_point2: … …

9 10

Problem: Nested Function Calls Need to Use a Stack

P: # Function P R: # Function R • A return address needs to be saved for as long as the movl $Rtn_point1, %eax … function invocation continues jmp Q # Call Q jmp %eax # Return • Return addresses are used in the reverse order that they Rtn_point1: are generated: Last-In-First-Out … • The number of return addresses that may need to be saved is not statically known

Q: # Function Q • Problem if P calls Q, and movl $Rtn_point2, %eax • Saving return addresses on a Stack is the most natural Q calls R jmp R # Call R solution Rtn_point2: • Return address for P to Q call is lost …

jmp %eax # Return 11 12 Stack Frames High-Level Picture

• Use stack for all temporary data related to each active function invocation • At Call time, push a new Stack Frame on top of the stack • At Return time, pop the top-most Stack Frame

o Return address Input parameters o Stack Frame o Local variables of function o Saving registers across invocations

• Stack has one Stack Frame per active function invocation

13 14

High-Level Picture High-Level Picture

main begins executing 0 main begins executing 0 main calls P

%ESP P’s

%ESP Stack Frame main’s main’s

Bottom Stack Frame 15 Bottom Stack Frame 16 High-Level Picture High-Level Picture

main begins executing 0 main begins executing 0 main calls P main calls P P calls Q P calls Q Q calls P %ESP P’s

%ESP Stack Frame Q’s Q’s Stack Frame Stack Frame P’s P’s Stack Frame Stack Frame main’s main’s

Bottom Stack Frame 17 Bottom Stack Frame 18

High-Level Picture High-Level Picture

main begins executing 0 main begins executing 0 main calls P main calls P P calls Q P calls Q Q calls P Q calls P P returns P returns %ESP R’s Q calls R %ESP Stack Frame Q’s Q’s Stack Frame Stack Frame P’s P’s Stack Frame Stack Frame main’s main’s

Bottom Stack Frame 19 Bottom Stack Frame 20 High-Level Picture High-Level Picture

main begins executing 0 main begins executing 0 main calls P main calls P P calls Q P calls Q Q calls P Q calls P P returns P returns Q calls R Q calls R %ESP R returns Q’s R returns Q returns Stack Frame %ESP P’s P’s Stack Frame Stack Frame main’s main’s

Bottom Stack Frame 21 Bottom Stack Frame 22

High-Level Picture High-Level Picture

main begins executing 0 main begins executing 0 main calls P main calls P P calls Q P calls Q Q calls P Q calls P P returns P returns Q calls R Q calls R R returns R returns Q returns Q returns P returns P returns %ESP main returns main’s

Bottom Stack Frame 23 Bottom 24 Function Call Details Call and Return Instructions

• Call and Return instructions 0 • Argument passing between procedures Instruction Function pushl src subl $4, %esp • Local variables movl src, (%esp) • Register saving conventions popl dest movl (%esp), dest addl $4, %esp call addr pushl %eip jmp addr ret pop %eip %ESP before Call

25 26

Call and Return Instructions Call and Return Instructions

0 0 Instruction Function Instruction Function

pushl src subl $4, %esp pushl src subl $4, %esp movl src, (%esp) movl src, (%esp) popl dest movl (%esp), dest popl dest movl (%esp), dest addl $4, %esp addl $4, %esp call addr pushl %eip call addr pushl %eip jmp addr %ESP jmp addr %ESP after Call Old EIP before Old EIP ret pop %eip ret pop %eip Return Return instruction assumes that the return address is at the top of

27 the stack 28 Call and Return Instructions Input Parameters

0 • Caller pushes input parameters 0 Instruction Function before executing the Call instruction

pushl src subl $4, %esp • Parameters are pushed in the movl src, (%esp) reverse order Push Nth argument first popl dest movl (%esp), dest o o Push 1st argument last addl $4, %esp o So that the first argument is at the top of call addr pushl %eip the stack at the time of the Call jmp addr ret pop %eip %ESP %ESP after before Return instruction assumes that Return pushing the return address is at the top of arguments

the stack 29 30

Input Parameters Input Parameters

• Caller pushes input parameters 0 • Caller pushes input parameters 0 before executing the Call before executing the Call instruction instruction • Parameters are pushed in the • Parameters are pushed in the reverse order reverse order %ESP Push Nth argument first Push Nth argument first Old EIP o %ESP o after Call st st o Push 1 argument last before Arg 1 o Push 1 argument last Arg 1 o So that the first argument is at the Call Arg … o So that the first argument is at the Arg … top of the stack at the time of the top of the stack at the time of the Arg N Arg N Call Call

Callee can address arguments relative to ESP: Arg 1 as 4(%esp)

31 32 Input Parameters Input Parameters

• Caller pushes input parameters 0 • Caller pushes input parameters 0 before executing the Call before executing the Call instruction instruction • Parameters are pushed in the • Parameters are pushed in the reverse order %ESP reverse order Push Nth argument first Old EIP Push Nth argument first o before o %ESP st st o Push 1 argument last Return Arg 1 o Push 1 argument last after Arg 1 o So that the first argument is at the Arg … o So that the first argument is at the Return Arg … top of the stack at the time of the top of the stack at the time of the Arg N Arg N Call Call

After the function call is finished, the caller pops the pushed arguments from the stack 33 34

Input Parameters Base Pointer: EBP • As Callee executes, ESP may • Caller pushes input parameters 0 change 0 before executing the Call instruction • Use EBP as a fixed reference point to access arguments and • Parameters are pushed in the other local variables reverse order %ESP th • Need to save old value of EBP o Push N argument first after Call Old EIP o Push 1st argument last before using EBP Arg 1 o So that the first argument is at the Arg … top of the stack at the time of the • Callee begins by executing Arg N Call %ESP pushl %ebp after movl %esp, %ebp After the function call is finished, popping the caller pops the pushed arguments %EBP arguments from the stack 35 36 Base Pointer: EBP Base Pointer: EBP • As Callee executes, ESP may 0 • Before returning, Callee must 0 change restore EBP to its old value %ESP • Use EBP as a fixed reference • Executes point to access arguments and movl %ebp, %esp other local variables %ESP, %EBP %EBP Old EBP popl %ebp Old EBP • Need to save old value of EBP Old EIP Old EIP ret before using EBP Arg 1 Arg 1 • Callee begins by executing Arg … Arg … Arg N Arg N pushl %ebp movl %esp, %ebp • Regardless of ESP, Callee can

address Arg 1 as 8(%ebp) 37 38

Base Pointer: EBP Base Pointer: EBP

• Before returning, Callee must 0 • Before returning, Callee must 0 restore EBP to its old value restore EBP to its old value • Executes • Executes movl %ebp, %esp movl %ebp, %esp %ESP, Old EBP popl %ebp %EBP popl %ebp %ESP Old EIP Old EIP ret ret Arg 1 Arg 1 Arg … Arg … Arg N Arg N

%EBP

39 40 Base Pointer: EBP Allocation for Local Variables • Local variables of the Callee • Before returning, Callee must 0 0 restore EBP to its old value are also allocated on the stack • Allocation done by moving the %ESP • Executes Var 2 stack pointer movl %ebp, %esp Var 1 %EBP popl %ebp • Example: allocate two integers Old EBP o subl $4, %esp Old EIP ret %ESP Arg 1 o subl $4, %esp Arg 1 (or equivalently, subl $8, %esp) Arg … o Arg … Arg N • Reference local variables Arg N using the base pointer o -4(%ebp) %EBP o -8(%ebp)

41 42

Use of Registers GCC/Linux Convention 0 • Caller-save registers %eax, %edx, %ecx %ESP o Saved • Problem: Callee may use a register that the caller Save on stack prior to calling is also using o Registers o When callee returns control to caller, old register • Callee-save registers Var 2 contents may be lost %ebx, %esi, %edi Var 1 o %EBP o Someone must save old register contents and later o Old values saved on stack prior Old EBP restore to using Old EIP Arg 1 • %esp, %ebp handled as Arg … described earlier • Need a convention for who saves and restores Arg N which registers • Return value is passed from Saved Registers 43 Callee to Caller in %eax 44 A Simple Example A Simple Example

# In general, one may need to push int add3(int a, int b, int c){ # callee-save registers onto the stack int add3(int a, int b, int c) int d; { d = a + b + c; # Add the three arguments int d; return d; movl 8(%ebp), %eax } addl 12(%ebp), %eax %ESP d = a + b + c; Var d addl 16(%ebp), %eax %EBP return d; old EBP # Put the sum into d } old EIP movl %eax, -4(%ebp) Arg a # Return value is already in eax Arg b int foo(void) Arg c { # In general, one may need to pop # callee-save registers return add3( 3, 4, 5 ); } add3: # Save old ebp and set up new ebp # Restore old ebp, discard stack frame pushl %ebp movl %ebp, %esp movl %esp, %ebp popl %ebp

# Allocate space for d # Return 45 subl $4, $esp ret 46

A Simple Example Conclusion int foo(void) { • Invoking a function return add3( 3, 4, 5 ); # No need to save caller- # save registers either } Call: call the function old EIP o # Push arguments in reverse order Ret: return from the instruction Arg a pushl $5 o Arg b pushl $4 Arg c pushl $3 • Stack Frame for a function invocation includes %ESP call add3 o Return address, %EBP foo: # Return value is already in eax o Procedure arguments, # Save old ebp, and set-up Local variables, and # new ebp # Restore old ebp and o pushl %ebp # discard stack frame o Saved registers movl %esp, %ebp movl %ebp, %esp popl %ebp # No local variables • Base pointer EBP # Return Fixed reference point in the Stack Frame # No need to save callee-save ret o # registers as we Useful for referencing arguments and local variables # don’t use any registers o 47 48