0% found this document useful (0 votes)
10 views15 pages

Chapter 8

Chapter 8 covers the concept of subroutines, including their definitions, types, and how to pass arguments by value or reference. It explains stack frames, their structure, and the importance of stack parameters in programming, particularly in C/C++ and assembly languages. The chapter also discusses calling conventions, local variables, and provides examples of stack frame management and the WriteStackFrame procedure for debugging.

Uploaded by

M Ahmed Butt
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views15 pages

Chapter 8

Chapter 8 covers the concept of subroutines, including their definitions, types, and how to pass arguments by value or reference. It explains stack frames, their structure, and the importance of stack parameters in programming, particularly in C/C++ and assembly languages. The chapter also discusses calling conventions, local variables, and provides examples of stack frame management and the WriteStackFrame procedure for debugging.

Uploaded by

M Ahmed Butt
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 15

Chapter 8

8.1 Introduction

 Subroutines are small parts of code you call from elsewhere.

 Different names:

o C/C++ ➔ Functions

o Java ➔ Methods

o MASM ➔ Procedures

 Arguments ➔ values sent to the subroutine.

 Parameters ➔ values received by the subroutine.

 Subroutine basics you'll learn:

o Passing arguments (by value or reference).

o Handling local variables.

o Recursion using the stack.

o Memory models and calling conventions.

8.2 Stack Frames


8.2.1 What is a Stack Frame?

 A stack frame is a chunk of the stack used during a subroutine call.

 It contains:

o Passed arguments

o Return address

o Local variables

o Saved registers

Steps to create a stack frame:

1. Push arguments.

2. Call the subroutine (push return address).


3. Push old EBP (base pointer).

4. Set EBP = ESP (stack pointer) ➔ new reference point.

5. Reserve space for local variables.

6. Push any registers you need to save.

Why Learn Stack Frames?

 ALL 32-bit Windows functions use stack parameters.

 64-bit programs use registers + stack.

8.2.2 Why Not Use Only Register Parameters?

Problems with using only registers:

 Need to save and restore (push/pop) registers ➔ messy code.

 Risk of bugs if push/pop mismatch.

 Performance is lost because of extra pushes/pops.

Example Problem: If you push 3 registers but accidentally miss popping


them back, the program crashes or misbehaves.

Advantages of Stack Parameters

 Clean and organized.

 No need to juggle registers.

 Safer and easier to debug.

How to Pass Data?

1. Passing by Value

 Copy the value onto the stack.

 Example:

push val2
push val1

call AddTwo

Stack before call:

val2

val1

Equivalent C++:

int sum = AddTwo(val1, val2);

Note: Values pushed in reverse order (last argument first).

2. Passing by Reference

 Push address (offset) instead of value.

 Example:

push OFFSET val2

push OFFSET val1

call Swap

Equivalent C++:

Swap(&val1, &val2);

3. Passing Arrays

 Arrays are always passed by reference (only address pushed).

 Example:

push OFFSET array

call ArrayFill

Why?
Passing the whole array by value would be very slow and waste stack
space.
Super Summary Table 🔥

What is
Type Example C++ Version
Pushed?

Pass by Value Value itself push val Add(val1, val2)

Pass by Address push OFFSET Swap(&val1,


Reference (offset) val &val2)

Address push OFFSET


Pass Array ArrayFill(array)
(offset) array

Stack Frames, and Calling Conventions (Irvine Chapter 8.2.3 & 8.2.4)

1. Accessing Stack Parameters

 In C/C++, when a function starts (prologue):

o Save EBP (push it).

o Set EBP = ESP (makes it easy to access parameters).

o Optional: save other registers too.

 When function ends (epilogue):

o Restore EBP.

o RET to caller.

Example in Assembly (C equivalent of int AddTwo(int x, int y)):

AddTwo PROC

push ebp

mov ebp, esp

mov eax, [ebp+12] ; get second parameter (y)

add eax, [ebp+8] ; add first parameter (x)

pop ebp

ret

AddTwo ENDP
✅ Result is returned in EAX.

2. Base-Offset Addressing

 Use [ebp+offset] to access stack parameters.

 Example offsets:

o [ebp+8] → first parameter

o [ebp+12] → second parameter

📝 Tip: You can make code readable:

x_param EQU [ebp+8]

y_param EQU [ebp+12]

3. Cleaning Up the Stack

 After calling a function, you must remove the parameters from the
stack.

 Otherwise:

o Stack gets corrupted.

o Program crash (wrong return address).

Example mistake:

push 6

push 5

call AddTwo

; ❌ didn't remove parameters!

 Correct ways:

o Either the caller removes the arguments.

o Or the callee (function) removes them.

4. 32-bit Calling Conventions


(a) C Calling Convention

 Parameters are pushed in reverse order.

 Caller is responsible for cleaning the stack after call.

Example:

push 6

push 5

call AddTwo

add esp, 8 ; ✅ remove 2 parameters (4 bytes each)

(b) STDCALL Calling Convention

 Parameters also pushed in reverse order.

 Callee cleans the stack (RET instruction handles it).

Example:

AddTwo PROC

push ebp

mov ebp, esp

mov eax, [ebp+12]

add eax, [ebp+8]

pop ebp

ret 8 ; ✅ clean up 8 bytes (2 parameters)

AddTwo ENDP

5. Key Differences between C and STDCALL

C Calling STDCALL
Feature
Convention Convention

Callee (inside
Who cleans the stack? Caller
function)
C Calling STDCALL
Feature
Convention Convention

Supports variable No (fixed arguments


Yes (e.g., printf)
arguments? only)

No (RET size handles


Extra instruction needed? Yes (add esp, size)
it)

✅ Final Tip:

 Irvine32 library (used in assembly programming) uses STDCALL.

 Always check which convention is being used for correct stack


handling.

Saving and Restoring Registers + Stack Frames + Local Variables +


Reference Parameters + LEA + ENTER/LEAVE" (Irvine Book)

Saving and Restoring Registers

 Subroutines often save registers on the stack before changing


them.

 This allows restoring them later ➔ keeps program stable.

 Steps inside a subroutine:

1. push ebp ➔ save old EBP.

2. mov ebp, esp ➔ create new stack frame.

3. push the registers you’ll use (e.g., ecx, edx).

4. Work with stack parameters using [ebp+offset].

5. At the end: pop registers ➔ pop ebp ➔ ret.

✅ Key Point: Pushing registers after setting EBP avoids messing up


parameter offsets.

🧩 Stack Frame Structure (Inside a Function)

A typical stack frame after push ebp and mov ebp, esp looks like:
Stack Content Address

Parameter (from
[ebp + 8]
caller)

Return Address [ebp + 4]

Saved EBP [ebp]

[ebp - 4], [ebp - 8],


Local Variables
etc.

✅ Key Point: Stack grows downward from EBP.

📦 Local Variables

 Created below EBP ➔ reserved by doing sub esp, size.

 No default values at compile time, but can initialize at runtime.

Example (C++):

int x = 10;

int y = 20;

Assembly equivalent:

asm

CopyEdit

push ebp

mov ebp, esp

sub esp, 8 ; reserve space

mov DWORD PTR [ebp-4], 10 ; x

mov DWORD PTR [ebp-8], 20 ; y

mov esp, ebp ; remove locals

pop ebp

ret

✅ Important: Reset ESP before popping EBP to safely destroy local variables.
✨ Using Names for Local Variables

Instead of [ebp-4], you can define names:

X_local EQU DWORD PTR [ebp-4]

Y_local EQU DWORD PTR [ebp-8]

Now you can use:

asm

CopyEdit

mov X_local, 10

mov Y_local, 20

✅ Key Point: More readable code.

🔗 Reference Parameters

 Parameters passed by reference (like array pointers) are accessed via


[ebp+offset].

 Example:

mov esi, [ebp+12] ; Load array pointer into ESI

✅ Key Point: Always load pointer first, then dereference if needed.

Example: Fill an Array (ArrayFill)

Inside the procedure:

pushad ; Save all registers

mov esi, [ebp+12] ; Pointer to array

mov ecx, [ebp+8] ; Count

cmp ecx, 0

je L2 ; Skip if count is zero

L1:
call RandomRange

mov [esi], ax ; Store value

add esi, TYPE WORD ; Move to next element

loop L1

L2:

popad ; Restore registers

pop ebp

ret 8 ; Clean stack

✅ Key Point: Handle pointer + loop carefully when working with arrays.

LEA Instruction

 LEA (Load Effective Address) gets the address of a memory operand.

 Used when you need the address, not the value.

Example:

lea esi, [ebp-30] ; Load address of local array

✅ Key Point: Can't use OFFSET for runtime stack addresses — only LEA.

🎯 ENTER and LEAVE Instructions

 ENTER automatically:

1. push ebp

2. mov ebp, esp

3. sub esp, numbytes

Syntax:

ENTER numbytes, nestinglevel

 In real life, we always use nestinglevel = 0.

Example (equivalent):

enter 8, 0
; same as:

push ebp

mov ebp, esp

sub esp, 8

 LEAVE cleans up:

leave

; same as:

mov esp, ebp

pop ebp

✅ Key Point: Always use LEAVE if you used ENTER.

⚡ TL;DR (Summary)

Topic Key Idea

Save/Restore push/pop registers around


Registers subroutine work

Stack Frame Created using EBP and ESP

Allocated below EBP using sub esp,


Local Variables
size

Reference
Access via [ebp+offset]
Parameters

LEA Instruction Get address of stack variable

Auto-setup and cleanup of stack


ENTER/LEAVE
frames

8.4.8 WriteStackFrame Procedure — Simple Notes

 WriteStackFrame is a procedure in Irvine32 library.

 It displays the stack frame of the current procedure.

o Shows:
 Passed parameters

 Return address

 Local variables

 Saved registers

✍ Prototype (How to use it):

WriteStackFrame PROTO,

numParam:DWORD, ; Number of parameters

numLocalVal:DWORD, ; Number of local DWORD variables

numSavedReg:DWORD ; Number of saved registers

✨ Example Program:

main PROC

mov eax, 0EAEAEAEAh

mov ebx, 0EBEBEBEBh

INVOKE myProc, 1111h, 2222h

exit

main ENDP

assembly

CopyEdit

myProc PROC USES eax ebx, x:DWORD, y:DWORD

LOCAL a:DWORD, b:DWORD

; Define counts

PARAMS = 2

LOCALS = 2

SAVED_REGS = 2
mov a, 0AAAAh

mov b, 0BBBBh

INVOKE WriteStackFrame, PARAMS, LOCALS, SAVED_REGS

📋 Sample Output (Stack layout):

Addre
Value Description
ss

0000222 ebp+1
2nd parameter (y)
2 2

0000111
ebp+8 1st parameter (x)
1

0040108
ebp+4 Return address
3

0012FFF
ebp+0 Saved EBP
0

0000AAA
ebp-4 Local variable (a)
A

0000BBB
ebp-8 Local variable (b)
B

EAEAEAE
ebp-12 Saved EAX
A

EBEBEBE Saved EBX (ESP


ebp-16
B here)

🧠 Extra Tip:

 Another version exists: WriteStackFrameName

o Same as WriteStackFrame but also shows the procedure's


name.

WriteStackFrameName PROTO,

numParam:DWORD,
numLocalVal:DWORD,

numSavedReg:DWORD,

procName:PTR BYTE ; Name of the procedure

📁 Source Code Location:

 File: Irvine32.asm

 Path: C:\Irvine\Examples\Lib32

🎯 Summary:

WriteStackFrame helps you visualize the stack at any moment —


parameters, locals, saved registers — to debug and understand your
program better.

Section Review — Simple Notes

✅ True/False Questions:

1. True

o A stack frame always has the caller’s return address and the
subroutine’s local variables.

2. True

o Arrays are passed by reference to save time and memory


(no copying onto the stack).

3. True

o Prologue code of a subroutine always pushes EBP to save the


old base pointer.

4. False

o Local variables are created by subtracting from the stack


pointer (not adding).

5. True

o In 32-bit mode, the last argument pushed appears at EBP +


8.
6. True

o Passing by reference means storing the address of the


argument on the stack.

✍ Short Answer:

Q: What are the two common types of stack parameters?

A:

 Passed by Value (copy of data is pushed)

 Passed by Reference (address of data is pushed)

🎯 Quick Summary:

 Stack frames always hold return address + locals.

 Arrays and large data are passed by reference.

 Subroutines save EBP in prologue.

 Locals are made by subtracting stack pointer (ESP).

 Arguments are accessed from EBP + 8.

 Reference passing = push address.

 Types of stack parameters = Value and Reference.

You might also like