Subprograms: Local Variables

Similar documents
Subprograms: Arguments

Stack, subprograms. procedures and modular programming role of stack while using procedures stack implementation (Pentium)

EECE.3170: Microprocessor Systems Design I Summer 2017 Homework 4 Solution

Assembly Language: Function Calls" Goals of this Lecture"

238P: Operating Systems. Lecture 3: Calling conventions. Anton Burtsev October, 2018

Assembly Language: Function Calls" Goals of this Lecture"

Assembly Language: Function Calls

Stack -- Memory which holds register contents. Will keep the EIP of the next address after the call

143A: Principles of Operating Systems. Lecture 5: Calling conventions. Anton Burtsev January, 2017

Assembly basics CS 2XA3. Term I, 2017/18

143A: Principles of Operating Systems. Lecture 4: Calling conventions. Anton Burtsev October, 2017

Program Exploitation Intro

Assembly Language: Function Calls. Goals of this Lecture. Function Call Problems

Register Allocation, iii. Bringing in functions & using spilling & coalescing

CS61 Section Solutions 3

AS08-C++ and Assembly Calling and Returning. CS220 Logic Design AS08-C++ and Assembly. AS08-C++ and Assembly Calling Conventions

CS 31: Intro to Systems Functions and the Stack. Martin Gagne Swarthmore College February 23, 2016

An Introduction to x86 ASM

CSC 2400: Computer Systems. Using the Stack for Function Calls

Function Calls COS 217. Reading: Chapter 4 of Programming From the Ground Up (available online from the course Web site)

Basic Assembly. Ned Nedialkov. McMaster University Canada. SE 3F03 January 2014

CSC 8400: Computer Systems. Using the Stack for Function Calls

Language of x86 processor family

Registers. Ray Seyfarth. September 8, Bit Intel Assembly Language c 2011 Ray Seyfarth

Procedure Calls. Young W. Lim Sat. Young W. Lim Procedure Calls Sat 1 / 27

CS 33: Week 3 Discussion. x86 Assembly (v1.0) Section 1G

W4118: PC Hardware and x86. Junfeng Yang

X86 Stack Calling Function POV

Assembly Language Lab # 9

Practical Malware Analysis

Islamic University Gaza Engineering Faculty Department of Computer Engineering ECOM 2125: Assembly Language LAB. Lab # 10. Advanced Procedures

mith College Computer Science CSC231 Assembly Week #11 Fall 2017 Dominique Thiébaut

The IA-32 Stack and Function Calls. CS4379/5375 Software Reverse Engineering Dr. Jaime C. Acosta

UMBC. contain new IP while 4th and 5th bytes contain CS. CALL BX and CALL [BX] versions also exist. contain displacement added to IP.

16.317: Microprocessor Systems Design I Fall 2015

Lecture 4 CIS 341: COMPILERS

Digital Forensics Lecture 3 - Reverse Engineering

CSC 2400: Computing Systems. X86 Assembly: Function Calls"

Compiler construction. x86 architecture. This lecture. Lecture 6: Code generation for x86. x86: assembly for a real machine.

Ethical Hacking. Assembly Language Tutorial

CSC 2400: Computing Systems. X86 Assembly: Function Calls

Sistemi Operativi. Lez. 16 Elementi del linguaggio Assembler AT&T

Introduction to 8086 Assembly

CS213. Machine-Level Programming III: Procedures

Computer Processors. Part 2. Components of a Processor. Execution Unit The ALU. Execution Unit. The Brains of the Box. Processors. Execution Unit (EU)

The x86 Architecture. ICS312 - Spring 2018 Machine-Level and Systems Programming. Henri Casanova

CNIT 127: Exploit Development. Ch 1: Before you begin. Updated

Assembly III: Procedures. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

Procedure Calls. Young W. Lim Mon. Young W. Lim Procedure Calls Mon 1 / 29

administrivia today start assembly probably won t finish all these slides Assignment 4 due tomorrow any questions?

Machine-level Programming (3)

CS 161 Computer Security. Week of January 22, 2018: GDB and x86 assembly

CMSC 313 Lecture 12 [draft] How C functions pass parameters

ICS143A: Principles of Operating Systems. Midterm recap, sample questions. Anton Burtsev February, 2017

Summary: Direct Code Generation

16.317: Microprocessor Systems Design I Fall 2014

mith College Computer Science CSC231 Assembly Week #12 Thanksgiving 2017 Dominique Thiébaut

Islamic University Gaza Engineering Faculty Department of Computer Engineering ECOM 2125: Assembly Language LAB. Lab # 7. Procedures and the Stack

Assembler lecture 4 S.Šimoňák, DCI FEEI TU of Košice

Computer Architecture and Assembly Language. Practical Session 3

Chapter 11. Addressing Modes

Chapter 3: Addressing Modes

CSE351 Autumn 2012 Midterm Exam (5 Nov 2012)

CSCI 334: Principles of Programming Languages. Computer Architecture (a really really fast introduction) Lecture 11: Control Structures II

CSC 2400: Computer Systems. Using the Stack for Function Calls

CMSC 313 COMPUTER ORGANIZATION & ASSEMBLY LANGUAGE PROGRAMMING

IA-32 Architecture. CS 4440/7440 Malware Analysis and Defense

ASSEMBLY III: PROCEDURES. Jo, Heeseung

16.317: Microprocessor Systems Design I Spring 2015

Assembly III: Procedures. Jo, Heeseung

See P&H 2.8 and 2.12, and A.5-6. Prof. Hakim Weatherspoon CS 3410, Spring 2015 Computer Science Cornell University

Computer Systems Lecture 9

CMSC 313 Lecture 12. Project 3 Questions. How C functions pass parameters. UMBC, CMSC313, Richard Chang

3. Process Management in xv6

Objectives. ICT106 Fundamentals of Computer Systems Topic 8. Procedures, Calling and Exit conventions, Run-time Stack Ref: Irvine, Ch 5 & 8

Procedure-Calling Conventions October 30

Addressing Modes. Outline

X86 Assembly -Procedure II:1

Linking and Loading. ICS312 - Spring 2010 Machine-Level and Systems Programming. Henri Casanova

Systems I. Machine-Level Programming V: Procedures

x86 assembly CS449 Fall 2017

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 21: Generating Pentium Code 10 March 08

Lecture 15 Intel Manual, Vol. 1, Chapter 3. Fri, Mar 6, Hampden-Sydney College. The x86 Architecture. Robb T. Koether. Overview of the x86

Sungkyunkwan University

UMBC. 1 (Feb. 9, 2002) seg_base + base + index. Systems Design & Programming 80x86 Assembly II CMPE 310. Base-Plus-Index addressing:

The x86 Architecture

Microprocessors ( ) Fall 2010/2011 Lecture Notes # 15. Stack Operations. 10 top

6/20/2011. Introduction. Chapter Objectives Upon completion of this chapter, you will be able to:

PC Assembly Language. Paul A. Carter

Implementing Threads. Operating Systems In Depth II 1 Copyright 2018 Thomas W. Doeppner. All rights reserved.

CSC 2400: Computer Systems. Towards the Hardware: Machine-Level Representation of Programs

Machine Programming 3: Procedures

The course that gives CMU its Zip! Machine-Level Programming III: Procedures Sept. 17, 2002

PC Assembly Language. Paul A. Carter

X86 Addressing Modes Chapter 3" Review: Instructions to Recognize"

Winter Compiler Construction T11 Activation records + Introduction to x86 assembly. Today. Tips for PA4. Today:

CSC 8400: Computer Systems. Machine-Level Representation of Programs

Lecture #16: Introduction to Runtime Organization. Last modified: Fri Mar 19 00:17: CS164: Lecture #16 1

CSE351 Spring 2018, Midterm Exam April 27, 2018

16.317: Microprocessor Systems Design I Fall 2013

Transcription:

Subprograms: Local Variables ICS312 Machine-Level and Systems Programming Henri Casanova (henric@hawaii.edu)

Local Variables in Subprograms In all the examples we have seen so far, the subprograms were able to do their work using only registers But sometimes, a subprogram s needs are beyond the set of available registers and some data must be kept in memory Just think of all subprograms you wrote that used more than 6 local variables (EAX, EBX, ECX, EDX, ESI, EDI) One possibility could be to declare a small.bss segment for each subprogram, to reserve memory space for all local variables Drawback #1: memory waste This reserved memory consumes memory space for the entire duration of the execution even if the subprogram is only active for a tiny fraction of the execution time (or never!) Drawback #2: subprograms are not reentrant

Re-entrant subprogram A subprogram is active if it has been called but the RET instruction hasn t been executed yet A subprogram is reentrant if it can be called from anywhere in the program This implies that the program can call itself, directly or indirectly, which enables recursion e.g., f calls g, which calls h, which calls f At a given time, two or more instances of a subprogram can be active Two or more activation records for this subprogram on the stack If we store the local variables of a subprogram in the.bss segment, then there can only be one activation! Otherwise activation #2 could corrupt the local variables of the activation #1 Therefore, with our current scheme for storing local variables, programs are not reentrant and one cannot have recursive calls when subprograms have local variables! In our previous example the recursive program had no local variables, so we were lucky Having reentrant programs is so useful that we don t want to live without it

Local variables on the stack Since activation records on the stack are used to store relevant information pertaining to a subprogram, why not use them for storing the subprogram local variables? The standard approach is to store local variables right after the saved EBP value on the stack This is simply done by subtracting some amount to the ESP pointer The local variables are then accessed as [EBP - 4], [EBP - 8], etc. Let s see this on an example

Local Variable Examples Say we have a subprogram that takes 2 parameters, uses 3 local variables, and doesn t return any value The code of the subprogram is as follows: func: push ebp ; save old EBP value mov ebp, esp ; set EBP sub esp, 12 ; add space for 3 local variables ; subprogram body mov esp, ebp ; deallocate local variables pop ebp ; restore old EBP value ret Let s look at the stack when the subprogram body begins

Local Variables Example Inside the body of the subprogram, parameters are referenced as: [EBP+8]: 1st parameter [EBP+12]: 2nd parameter Inside the body of the subprogram, local variables are referenced as: [EBP-4]: 1st local variable [EBP-8]: 2nd local variable [EBP-12]: 3rd local variable EBP+12 EBP+8 EBP+4 EBP EBP-4 EBP-8 EBP-12 2nd parameter 1st parameter return address saved EBP 1st local var 2nd local var 3rd local var

Local Variables Example Inside the body of the subprogram, parameters are referenced as: [EBP+8]: 1st parameter [EBP+12]: 2nd parameter Inside the body of the subprogram, local variables are referenced as: [EBP-4]: 1st local variable [EBP-8]: 2nd local variable [EBP-12]: 3rd local variable EBP+12 EBP+8 EBP+4 EBP EBP-4 EBP-8 EBP-12 2nd parameter 1st parameter return address saved EBP 1st local var 2nd local var 3rd local var Very important you have this picture in mind; you should be able to redraw it

A deep stack Each call to a subprogram puts an activation record on the stack, saved EBP values and arguments Important: While a function is active, EBP always points to the saved EBP value saved for the function s caller EBP is sort of the anchor point of the activation record ( B stands for Base Pointer) We have seen this on a small example in the previous set of lecture notes Let s look at a bigger example But not with the corresponding assembly code

x() calls e() calls f() calls g() calls h() e s arguments e s return @ x s saved EBP e s local vars }e s activation record EBP

x() calls e() calls f() calls g() calls h() e s arguments e s return @ x s saved EBP e s local vars f s arguments f s return @ e s saved EBP f s local vars EBP

x() calls e() calls f() calls g() calls h() e s arguments g s arguments e s return @ g s return @ x s saved EBP f s saved EBP e s local vars f s arguments f s return @ e s saved EBP f s local vars EBP

x() calls e() calls f() calls g() calls h() e s arguments g s arguments e s return @ g s return @ x s saved EBP f s saved EBP e s local vars h s return @ g s saved EBP f s arguments f s return @ e s saved EBP f s local vars h s local vars EBP

x() calls e() calls f() calls g() calls h() e s arguments e s return @ x s saved EBP e s local vars f s arguments f s return @ e s saved EBP f s local vars g s arguments g s return @ f s saved EBP h s return @ g s saved EBP h s local vars EBP The saved EBPs provide links between the activation records The current EBP is for the current function Let s see what happens when h returns

x() calls e() calls f() calls g() calls h() e s arguments e s return @ x s saved EBP e s local vars g s arguments g s return @ f s saved EBP h s return @ g s saved EBP When h returns mov ESP, EBP f s arguments f s return @ e s saved EBP f s local vars EBP

x() calls e() calls f() calls g() calls h() e s arguments e s return @ x s saved EBP e s local vars g s arguments g s return @ f s saved EBP h s return @ When h returns mov ESP, EBP pop EBP f s arguments f s return @ e s saved EBP f s local vars EBP

x() calls e() calls f() calls g() calls h() e s arguments e s return @ x s saved EBP e s local vars g s arguments g s return @ f s saved EBP When h returns mov ESP, EBP pop EBP pop return address f s arguments f s return @ e s saved EBP f s local vars EBP

x() calls e() calls f() calls g() calls h() e s arguments e s return @ x s saved EBP g s arguments g s return @ f s saved EBP We are now in a clean state, where g is the active subprogram e s local vars f s arguments f s return @ The EBP register and its saved values provide the crucial link between activation records e s saved EBP f s local vars EBP If EBP values get corrupted, then all is lost

ENTER and LEAVE We always have the same prologue and the same epilogue push ebp ; save old EBP value mov ebp, esp ; set EBP sub esp, X ; reserve X=4*N bytes for N local vars mov esp, ebp ; remove space for local vars pop ebp ; restore old EBP value ret ; return

ENTER and LEAVE There are two convenient functions: ENTER and LEAVE push ebp ; save old EBP value mov ebp, esp ; set EBP sub esp, X ; reserve X=4*N bytes for N local vars equivalent to enter X, 0 mov esp, ebp ; remove space for local vars pop ebp ; restore old EBP value ret ; return equivalent to leave ret

Recall the NASM Skeleton ; include directives segment.data ; DX directives segment.bss ; RESX directives Prologue and epilogue of asm_main segment.text asm_main: global asm_main enter 0,0 pusha ; Your program here popa mov eax, 0 leave ret

We Finally Understand the Skeleton ; include directives segment.data ; DX directives segment.bss ; RESX directives segment.text global asm_main asm_main: enter 0,0 ; Save EBP, reserve 0 bytes for local variables pusha ; Save ALL registers ; Your program here popa ; Restore ALL registers mov eax, 0 ; Set the return value to 0 leave ; Restore EBP, remove space for local variables ret ; Pop the return address and jump to it

Knowing your stack At this point it should be clear that it is very important to understand how the stack works and how to use it When programming in assembly you should always have a mental picture of the stack Something you don t do when using a high-level programming language typically As always, abstractions are great, but having no idea how they are implemented can be problematic when hunting bugs Basic example: running out of stack space It s typically a good idea to be consistent Compilers are consistent by design

A Full Example Let s write the assembly code equivalent to the following C/Java function int f(int num) { // computes Fibonacci numbers int x, sum; if (num == 0) return 0; if (num == 1) return 1; x = f(num-1); sum = x + f(num-2) return sum; } Let s write a straight translation, without optimizing variables away, just for demonstration purposes

A Full Example (main program) %include "asm_io.inc" segment.data msg1 db "Enter n: ", 0 msg2 db "The result is: ", 0 ; declaration of asm_main and setup mov eax, msg1 ; eax = address of msg1 call print_string ; print msg1 call read_int ; get an integer from the keyboard (in EAX) push eax ; put the integer on the stack (parameter #1) call f ; call f pop ebx ; remove the parameter from the stack mov ebx, eax ; save the value returned by f mov eax, msg2 ; eax = address of msg2 call print_string ; print msg2 mov eax, ebx ; eax = sum call print_int ; print the sum call print_nl ; print a new line ; clean up

A Full Example (function f) ; FUNCTION: f ; Takes one parameter: an integer ; eax = return value segment.text f: enter 8,0 ; num in [ebp+8] ; local var x in [ebp-4], ; local var sum in [ebp-8] push ebx ; save ebx push ecx ; save ecx push edx ; save edx mov eax, [ebp+8] ; eax = num sub eax, 2 ; eax -= 2 jns next ; if not <0, goto next add eax, 2 ; eax += 2 jmp end next: mov eax, [ebp+8] ; eax = num add eax, -1 ; eax -= 1 push eax ; put (num -1) on stack call f ; call f (recursively) add esp, 4 ; remove (num-1) from stack mov [ebp-4], eax ; put the returned value in x mov eax, [ebp+8] ; eax = num add eax, -2 ; eax -= 2 push eax ; put (num -2) on stack call f ; call f (recursively), ; the return value is in eax add esp, 4 ; remove (num-1) from stack add eax, [ebp-4] ; eax += x end: pop edx ; restore ebx pop ecx ; restore ecx pop ebx ; restore edx leave ; clean up the stack ret ; return

Interfacing Assembly and C Section 4.7 of the book talks about interfacing C and assembly We have seen most of this content already, but let s talk about the issue of saving registers on the stack By convention, C assumes that a subprogram (e.g., the one you re writing in assembly), will not destroy values in EBX, ESI, EDI, EBP, CS, DS, SS, and ES So, if you write an assembly subprogram, make sure you save these on the stack and restore them We ve already said we save EBP Example: I know my subprogram uses EBX (as on page 86) enter 4,0 ; prologue (1 32-bit local var) push ebx ; save EBX pop ebx ; restore EBX leave ; epilogue ret ; return

Conclusion When programming one always faces trade-offs between program readability and program performance With by-hand assembly programming, the programmer can make fine-tuned decisions for these trade-offs e.g., for a particular function I decide to not save all registers because I _know_ that it won t corrupt them, thus saving time e.g., I know that I can reuse some register value that was modified in a subprogram to do some clever optimization Some of these optimizations can only be done by a human who understands what the program does Many optimizations can be done by a compiler