Back to All Lectures

Lecture 8: Memory Access

Lectures on Computer Architecture

Click the thumbnail above to watch the video lecture on YouTube

By Dr. Kisaru Liyanage

8.1 Introduction

This lecture explores character data handling, string operations, and the compilation/linking/loading process. We examine byte and half-word memory operations, implement string manipulation functions, use library functions like scanf and printf, and understand how programs transform from source code to executable binaries. These topics bridge high-level programming concepts and low-level assembly implementation, essential for systems programming and understanding program execution.

8.2 Character Data and Encoding

8.2.1 ASCII Encoding

Basic 7-Bit Standard

ASCII Examples

'A' = 65 (0x41)
'a' = 97 (0x61)
'0' = 48 (0x30)
'\n' = 10 (0x0A)
'\0' = 0 (0x00)  ; null terminator

8.2.2 Latin-1 Encoding

Extended 8-Bit Standard

8.2.3 Unicode Encoding

Modern Universal Standard

Why Unicode?

8.3 Byte Load/Store Operations

8.3.1 Load Register Byte (LDRB)

Syntax

LDRB Rd, [Rn, #offset]   ; Load byte from memory

Operation

Example

; Memory[0x1000] = 0x42 ('B')
LDR R1, =0x1000
LDRB R0, [R1]
; R0 = 0x00000042

Use Cases

8.3.2 Store Register Byte (STRB)

Syntax

STRB Rd, [Rn, #offset]   ; Store byte to memory

Operation

Example

MOV R0, #0x41        ; 'A'
LDR R1, =0x2000
STRB R0, [R1]        ; Memory[0x2000] = 0x41

8.3.3 Load Register Signed Byte (LDRSB)

Syntax

LDRSB Rd, [Rn, #offset]  ; Load signed byte

Operation

Example

; Memory[0x1000] = 0xFE (-2 in signed byte)
LDR R1, =0x1000
LDRSB R0, [R1]
; R0 = 0xFFFFFFFE (-2 in 32-bit signed)
; Memory[0x1001] = 0x7F (+127)
LDRSB R0, [R1, #1]
; R0 = 0x0000007F (+127)

When to Use

8.3.4 Memory Alignment

LDRB Advantages

LDR Requirement

8.4 Half-Word Load/Store Operations

8.4.1 Load Register Half-word (LDRH)

Syntax

LDRH Rd, [Rn, #offset]   ; Load 16 bits

Operation

Example

; Memory[0x1000-0x1001] = 0xABCD
LDR R1, =0x1000
LDRH R0, [R1]
; R0 = 0x0000ABCD

Use Cases

8.4.2 Store Register Half-word (STRH)

Syntax

STRH Rd, [Rn, #offset]   ; Store 16 bits

Operation

Example

MOV R0, #0x1234
LDR R1, =0x2000
STRH R0, [R1]
; Memory[0x2000-0x2001] = 0x1234

8.4.3 Load Register Signed Half-word (LDRSH)

Syntax

LDRSH Rd, [Rn, #offset]  ; Load signed 16-bit

Operation

Example

; Memory = 0x8000 (-32768 as signed 16-bit)
LDRSH R0, [R1]
; R0 = 0xFFFF8000 (-32768 as signed 32-bit)

8.5 String Copy Example (strcpy)

8.5.1 C Implementation

Code

void strcpy(char x[], char y[]) {
    int i = 0;
    while ((x[i] = y[i]) != '\0') {
        i++;
    }
}

Algorithm

  1. Copy characters from y to x one at a time
  2. Stop when null terminator ('\\0') encountered
  3. Null terminator also copied

8.5.2 ARM Assembly Implementation

Register Allocation

R0: Base address of x (destination)
R1: Base address of y (source)
R4: Loop counter i
R2: Address of y[i]
R3: Value of y[i]
R12: Address of x[i]

Complete Assembly

strcpy:
    ; Prologue: Save R4 (must preserve)
    SUB SP, SP, #4
    STR R4, [SP, #0]
    ; Initialize counter
    MOV R4, #0           ; i = 0
loop:
    ; Calculate address of y[i]
    ADD R2, R4, R1       ; R2 = y + i
    ; Load y[i]
    LDRB R3, [R2, #0]    ; R3 = y[i]
    ; Calculate address of x[i]
    ADD R12, R4, R0      ; R12 = x + i
    ; Store to x[i]
    STRB R3, [R12, #0]   ; x[i] = y[i]
    ; Check for null terminator
    CMP R3, #0           ; Is y[i] == '\0'?
    BEQ done             ; If yes, exit loop
    ; Increment counter
    ADD R4, R4, #1       ; i++
    B loop               ; Continue loop
done:
    ; Epilogue: Restore R4
    LDR R4, [SP, #0]
    ADD SP, SP, #4
    MOV PC, LR           ; Return

8.5.3 Key Points

Why LDRB/STRB?

Register Preservation

Offsets Are Immediate

8.6 Library Functions: scanf and printf

8.6.1 scanf Function

Purpose

C Signature

int scanf(const char *format, ...);

Arguments

Example: Read Integer

C Code

int x;
scanf("%d", &x);  // Note: &x (address of x)

ARM Assembly

.data
formatS: .asciz "%d"
.text
    SUB SP, SP, #4       ; Space for x
    LDR R0, =formatS     ; R0 = address of "%d"
    MOV R1, SP           ; R1 = address where to store
    BL scanf
    LDR R2, [SP, #0]     ; R2 = x

8.6.2 printf Function

Purpose

C Signature

int printf(const char *format, ...);

Arguments

Example: Print Integer

C Code

printf("Result: %d\n", result);

ARM Assembly

.data
formatP: .asciz "Result: %d\n"
.text
    LDR R1, [SP, #0]     ; R1 = result (value, not address)
    ADD SP, SP, #4       ; Release stack space
    LDR R0, =formatP
    BL printf

8.6.3 Data Section and Format Strings

Data Section

.data
formatS: .asciz "%d"           ; Input format
formatP: .asciz "Result: %d\n"  ; Output format
array: .word 1, 2, 3, 4         ; Array
message: .asciz "Hello"         ; String

.asciz Directive

Pseudo-Operation: LDR Rd, =label

LDR R0, =formatS     ; Loads ADDRESS of formatS into R0

8.6.4 scanf vs printf Argument Differences

scanf: Needs Addresses

SUB SP, SP, #4
MOV R1, SP           ; R1 = address (where to store)
BL scanf

printf: Needs Values

LDR R1, [SP]         ; R1 = value (what to print)
BL printf

Why This Difference?

8.6.5 Calling Convention Rules

Follow Exact Order

Know Function Signatures

8.7 Compilation, Linking, and Loading

8.7.1 Translation Overview

Complete Process

C Program (.c)
↓ [Compiler]
↓ [Assembler]
Object Module (.o)
↓ [Linker]
Executable (a.out)
↓ [Loader]
Memory (running program)

8.7.2 Compiler

Function

Optimizations

Example

int add(int a, int b) {
    return a + b;
}

↓ Compiler

add:
    ADD R0, R0, R1
    MOV PC, LR

8.7.3 Assembler

Function

Tasks

  1. Translate instructions to binary opcodes
  2. Resolve local labels to addresses
  3. Generate symbol table
  4. Create relocation information

Object Module Structure

Header

Text Segment

Static Data Segment

Relocation Info

Symbol Table

Debug Info

8.7.4 Linker

Function

Tasks

1. Merge Segments

program.o:      lib.o:          Result:
[Text1]         [Text2]     →   [Text1+Text2]
[Data1]         [Data2]     →   [Data1+Data2]

2. Resolve Labels

3. Patch References

8.7.5 Static vs Dynamic Linking

Static Linking

Advantages

Disadvantages

Dynamic Linking

Advantages

Disadvantages

DLL (Dynamic Link Library) - Windows

8.7.6 Loader

Function

Loading Steps

1. Read Header

2. Create Virtual Address Space

3. Copy Segments to Memory

4. Set Up Arguments on Stack

Example

./program arg1 arg2

5. Initialize Registers

6. Jump to Startup Routine

8.8 Exercises

8.8.1 Common String Operations

String Length

int strlen(char *s) {
    int len = 0;
    while (s[len] != '\0')
        len++;
    return len;
}

String Reverse

void strrev(char *s) {
    int len = strlen(s);
    for (int i = 0; i < len/2; i++) {
        char temp = s[i];
        s[i] = s[len-1-i];
        s[len-1-i] = temp;
    }
}

8.8.2 Integer I/O

Read Two Integers, Print Sum

; Read x and y
; Print x + y

Read n, Print 1 to n

; Read n
; Loop from 1 to n, print each

8.8.3 Skills Required

Key Takeaways

  1. ASCII (7-bit), Latin-1 (8-bit), Unicode (32-bit) represent character data with increasing capacity.
  2. LDRB/STRB for byte operations, LDRH/STRH for half-words - smaller than word operations.
  3. Byte operations don't require alignment unlike word operations (LDR/STR).
  4. Sign extension (LDRSB/LDRSH) replicates sign bit to preserve signed values.
  5. Strings in C are char arrays terminated with null character ('\\0' = 0).
  6. scanf and printf are library functions called via BL instruction.
  7. scanf needs addresses (where to store), printf needs values (what to print).
  8. Format strings stored in .data section using .asciz directive.
  9. Arguments passed in R0-R3 following ARM calling convention.
  10. Compilation chain: Compile → Assemble → Link → Load → Execute.
  11. Static linking includes libraries in executable, dynamic linking loads at runtime.
  12. Loader sets up virtual memory, copies segments, initializes stack with arguments.

Summary

Character data handling and library function usage bridge high-level programming concepts and assembly implementation. Understanding byte/half-word operations enables efficient string manipulation and compact data storage. The scanf/printf functions demonstrate how assembly code interfaces with system libraries, requiring careful attention to calling conventions and argument types. The compilation, linking, and loading process reveals how source code transforms into running programs, involving multiple stages with distinct responsibilities. Static and dynamic linking represent different trade-offs between self-containment and flexibility. These concepts are essential for systems programming, understanding program structure, and debugging low-level issues. This knowledge prepares us for advanced topics including operating systems, compilers, and system-level optimization.