Machine-Level Programming III - Procedures

Class: CSCE-312


Notes:

Mechanisms in Procedures

Pasted image 20251002131942.png|250

Today

Stack Structure

x86-64 Stack

Pasted image 20251002132204.png|450

x86-64 Stack: Push

Pasted image 20251002132554.png|450

x86-64 Stack: Pop

Pasted image 20251002132631.png|450

Calling Conventions: Passing control

Code Examples:

Pasted image 20251002132818.png|550

Procedure Control Flow

Control Flow Example

Pasted image 20251002133633.png|350 Pasted image 20251002133807.png|350

Pasted image 20251002133819.png|350 Pasted image 20251002133838.png|350

Calling Conventions: Passing data

Registers:

Stack:
Pasted image 20251002134236.png|100

Data Flow Examples

Pasted image 20251002134646.png|550

Calling Conventions: Managing local data

Stack-Based Languages

Call Chain Example

Pasted image 20251002135320.png|500

Stack Frames

Pasted image 20251002135416.png|300

Example

Pasted image 20251002135733.png|325 Pasted image 20251002135554.png|325

x86-64/Linux Stack Frame

Pasted image 20251002135902.png|250

Example: incr

C Code:

long incr(long *p, long val) {
    long x = *p;
    long y = x + val;
    *p = y;
    return x;
}

Assembly instructions:

incr:
  movq    (%rdi), %rax
  addq    %rax, %rsi
  movq    %rsi, (%rdi)
  ret
Register Use(s)
%rdi Argument p
%rsi Argument val, y
%rax x, Return value

Example: Calling incr #1

Pasted image 20251007121942.png|500

Example: Calling incr #2

Pasted image 20251007122607.png|500

Example: Calling incr #3

Pasted image 20251007122810.png|500

Example: Calling incr #4

Pasted image 20251007122852.png|500

Example: Calling incr #5

Pasted image 20251007122919.png|500

Register Saving Conventions

x86-64 Linux Register Usage #1

Pasted image 20251007124421.png|300

x86-64 Linux Register Usage #2

Pasted image 20251007124518.png|300

Callee-Saved Example #1

Pasted image 20251007124550.png|500

Callee-Saved Example #2

Pasted image 20251007124806.png|500

Illustration of Recursion

Recursive Function

C code:

/* Recursive popcount */
long pcount_r(unsigned long x) {
  if (x == 0)
    return 0;
  else
    return (x & 1) 
           + pcount_r(x >> 1);
}

Assembly code:

pcount_r:
  movl    $0, %eax
  testq   %rdi, %rdi
  je      .L6
  pushq   %rbx
  movq    %rdi, %rbx
  andl    $1, %ebx
  shrq    %rdi         # (by 1)
  call    pcount_r
  addq    %rbx, %rax
  popq    %rbx
.L6:
  rep; ret

Recursive Function Terminal Case

Pasted image 20251007125121.png|600

Register Use(s) Type
%rdi x Argument
%rax Return value Return value

Recursive Function Register Save

Pasted image 20251007125717.png|600 Pasted image 20251007125748.png|100

Register Use(s) Type
%rdi x Argument

Recursive Function Call Setup

Pasted image 20251007125906.png|600

Register Use(s) Type
%rdi x >> 1 Rec. argument
%rbx x & 1 Callee-saved

Recursive Function Call

Pasted image 20251007130035.png|600

Register Use(s) Type
%rbx x & 1 Callee-saved
%rax Recursive call return value

Recursive Function Result

Pasted image 20251007130124.png|600

Register Use(s) Type
%rbx x & 1 Callee-saved
%rax Return value

Recursive Function Completion

Pasted image 20251007130237.png|600 Pasted image 20251007130246.png|100

Register Use(s) Type
%rax Return value Return value

Observations About Recursion

x86-64 Procedure Summary

Pasted image 20251007134721.png|200