Week 1: Computer Architecture & Number Systems
Overview
This week introduces the fundamental concepts needed for assembly programming: number systems, bitwise operations, and CPU architecture.
Day 1-2: Number Systems
Learning Objectives
- Master binary, decimal, and hexadecimal conversions
- Understand why computers use these systems
- Develop quick conversion skills
Theory
Binary (Base-2)
- Uses only 0 and 1
- Each position represents a power of 2
- Example:
1011= 1×2³ + 0×2² + 1×2¹ + 1×2⁰ = 8 + 0 + 2 + 1 = 11
Hexadecimal (Base-16)
- Uses 0-9 and A-F (A=10, B=11, … F=15)
- Each hex digit represents 4 bits
- Example:
0x2F= 2×16¹ + 15×16⁰ = 32 + 15 = 47 - Binary equivalent:
0010 1111
Conversion Techniques
Binary to Decimal:
1101 = 1×8 + 1×4 + 0×2 + 1×1 = 13
Decimal to Binary (Division Method):
13 ÷ 2 = 6 remainder 1
6 ÷ 2 = 3 remainder 0
3 ÷ 2 = 1 remainder 1
1 ÷ 2 = 0 remainder 1
Read upwards: 1101
Binary to Hex (Group by 4):
11010110
= 1101 0110
= D 6
= 0xD6
Hex to Binary:
0xA3
= A 3
= 1010 0011
Practical Exercises
Exercise 1: Basic Conversions
Convert these numbers:
- Decimal 255 → Binary → Hex
- Binary 11010110 → Decimal → Hex
- Hex 0xDEADBEEF → Binary → Decimal
- Decimal 1024 → Binary → Hex
- Binary 10101010 → Decimal → Hex
Exercise 2: Quick Mental Math
Practice these patterns:
- Powers of 2: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024…
- Common hex values: 0xF = 15, 0xFF = 255, 0xFFFF = 65535
- Bit positions: Bit 0 = 1, Bit 3 = 8, Bit 7 = 128
Exercise 3: Real-World Application
- An IPv4 address is 192.168.1.1. Convert each octet to binary and hex.
- A color code is #FF5733. What are the RGB values in decimal?
- A memory address is 0x1000. What is it in binary and decimal?
Daily Practice
- Spend 15 minutes daily on random conversions
- Use calculator only to check answers
- Focus on pattern recognition
Day 3-4: Bitwise Operations
Learning Objectives
- Understand AND, OR, XOR, NOT operations
- Learn bit shifting and rotation
- Apply bitwise operations to practical problems
Bitwise Operators
AND Operation (&)
Truth Table:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
Example:
1010
& 1100
------
1000
Use Case: Masking bits, checking if bit is set
OR Operation (|)
Truth Table:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
Example:
1010
| 1100
------
1110
Use Case: Setting bits, combining flags
XOR Operation (^)
Truth Table:
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
Example:
1010
^ 1100
------
0110
Use Case: Toggling bits, simple encryption, swap without temp variable
NOT Operation (~)
~1010 = 0101 (flips all bits)
Use Case: Inverting flags, creating masks
Shift Left (<<)
1010 << 1 = 10100
(Multiply by 2)
1010 << 2 = 101000
(Multiply by 4)
Shift Right (>>)
1010 >> 1 = 0101
(Divide by 2)
1010 >> 2 = 0010
(Divide by 4)
Practical Applications
Application 1: Checking if Bit is Set
Check if bit 3 is set in value:
value & (1 << 3)
If result != 0, bit is set
Example:
value = 0b1010 (10 in decimal)
mask = 1 << 3 = 0b1000
value & mask = 0b1010 & 0b1000 = 0b1000 (not zero, so bit 3 is set)
Application 2: Setting a Bit
Set bit 3:
value | (1 << 3)
Example:
value = 0b1010
mask = 1 << 3 = 0b1000
value | mask = 0b1010 | 0b1000 = 0b1010 (bit already set)
value = 0b0010
value | mask = 0b0010 | 0b1000 = 0b1010 (bit now set)
Application 3: Clearing a Bit
Clear bit 3:
value & ~(1 << 3)
Example:
value = 0b1010
mask = ~(1 << 3) = ~0b1000 = 0b11110111 (assuming 8-bit)
value & mask = 0b1010 & 0b11110111 = 0b0010 (bit 3 cleared)
Application 4: Toggling a Bit
Toggle bit 3:
value ^ (1 << 3)
Example:
value = 0b1010
value ^ 0b1000 = 0b0010 (bit 3 toggled off)
Application 5: XOR Swap (No Temp Variable)
a = 5 (0b0101)
b = 3 (0b0011)
a = a ^ b // a = 0b0101 ^ 0b0011 = 0b0110
b = a ^ b // b = 0b0110 ^ 0b0011 = 0b0101 (now 5)
a = a ^ b // a = 0b0110 ^ 0b0101 = 0b0011 (now 3)
Result: a = 3, b = 5 (swapped!)
Exercises
Exercise 1: Basic Operations
Calculate by hand:
0b1010 & 0b11000b1010 | 0b11000b1010 ^ 0b1100~0b1010(assume 8-bit)0b1010 << 20b1010 >> 1
Exercise 2: Extract RGB from Color
Given a 32-bit color value 0xAARRGGBB, extract:
- Alpha (AA):
(color >> 24) & 0xFF - Red (RR):
(color >> 16) & 0xFF - Green (GG):
(color >> 8) & 0xFF - Blue (BB):
color & 0xFF
Practice with: 0xFF5733AB
Exercise 3: Set, Clear, Toggle
Given value = 0b10110010:
- Set bit 0
- Clear bit 5
- Toggle bit 2
- Check if bit 4 is set
- Set bits 0, 1, and 2 simultaneously
Exercise 4: Count Set Bits
Write algorithm to count number of 1s in 0b10110101:
Algorithm:
count = 0
while value != 0:
if value & 1:
count++
value = value >> 1
Exercise 5: Check if Power of 2
A number is a power of 2 if it has only one bit set.
Check: value & (value - 1) == 0
Examples:
8 = 0b1000, 8-1 = 0b0111, 0b1000 & 0b0111 = 0 ✓
10 = 0b1010, 10-1 = 0b1001, 0b1010 & 0b1001 = 0b1000 ✗
Challenge Problems
- Reverse the bits in a byte (0b10110010 → 0b01001101)
- Find the rightmost set bit position
- Clear all bits except the rightmost set bit
- Implement fast modulo for powers of 2:
x % 8 = x & 7
Day 5-7: CPU Architecture Fundamentals
Learning Objectives
- Understand CPU components and their roles
- Learn the fetch-decode-execute cycle
- Master x86-64 register architecture
CPU Components
1. Arithmetic Logic Unit (ALU)
- Performs arithmetic operations (add, subtract, multiply, divide)
- Performs logical operations (AND, OR, XOR, NOT)
- Sets condition flags based on results
2. Control Unit (CU)
- Fetches instructions from memory
- Decodes instructions
- Coordinates execution across components
- Manages timing signals
3. Registers
- Fastest memory in CPU
- Directly accessible by instructions
- Store temporary values, addresses, status
4. Program Counter (PC/IP)
- Holds address of next instruction
- Called RIP in x86-64
- Automatically incremented after each instruction
5. Stack Pointer (SP)
- Points to top of stack
- Called RSP in x86-64
- Stack grows downward
6. Flags Register
- Stores CPU status bits
- Called RFLAGS in x86-64
- Includes Zero, Carry, Sign, Overflow flags
Memory Hierarchy
Speed ↑ Size ↓ Cost ↑
----------------------------
Registers (fastest, ~1 cycle)
↓
L1 Cache (~4 cycles)
↓
L2 Cache (~12 cycles)
↓
L3 Cache (~40 cycles)
↓
Main Memory/RAM (~100 cycles)
↓
SSD Storage (~50,000 cycles)
↓
HDD Storage (~5,000,000 cycles)
Instruction Cycle
Fetch Stage
- Read instruction from memory at address in RIP
- Load into instruction register
- Increment RIP to point to next instruction
Decode Stage
- Determine operation type (add, move, jump, etc.)
- Identify operands (registers, memory, immediate values)
- Prepare control signals
Execute Stage
- Perform the operation in ALU
- Access memory if needed
- Update registers
Store/Writeback Stage
- Write results back to register or memory
- Update flags if needed
Example: ADD RAX, RBX
Fetch: Get instruction bytes from memory[RIP]
Decode: Operation=ADD, Dest=RAX, Source=RBX
Execute: ALU adds RAX + RBX
Store: Result written to RAX, flags updated
x86-64 Register Architecture
General-Purpose Registers (64-bit)
| 64-bit | 32-bit | 16-bit | 8-bit high | 8-bit low | Common Use |
|---|---|---|---|---|---|
| RAX | EAX | AX | AH | AL | Accumulator, return values |
| RBX | EBX | BX | BH | BL | Base register |
| RCX | ECX | CX | CH | CL | Counter, loop iterations |
| RDX | EDX | DX | DH | DL | Data, I/O operations |
| RSI | ESI | SI | - | SIL | Source index (strings) |
| RDI | EDI | DI | - | DIL | Destination index (strings) |
| RBP | EBP | BP | - | BPL | Base pointer (stack frame) |
| RSP | ESP | SP | - | SPL | Stack pointer |
Extended Registers (64-bit only)
- R8, R9, R10, R11, R12, R13, R14, R15
- 32-bit: R8D, R9D, … R15D
- 16-bit: R8W, R9W, … R15W
- 8-bit: R8B, R9B, … R15B
Special-Purpose Registers
- RIP: Instruction pointer (program counter)
- RFLAGS: Status and control flags
- CF (Carry Flag, bit 0): Unsigned overflow/borrow
- PF (Parity Flag, bit 2): Even parity
- ZF (Zero Flag, bit 6): Result is zero
- SF (Sign Flag, bit 7): Result is negative
- OF (Overflow Flag, bit 11): Signed overflow
Segment Registers
- CS (Code Segment)
- DS (Data Segment)
- SS (Stack Segment)
- ES, FS, GS (Extra segments)
Register Usage Examples
Accumulator (RAX)
; Used for arithmetic
mov rax, 10
add rax, 5 ; RAX = 15
; Used for return values
mov rax, 42 ; Return 42 from function
ret
; Used for syscalls
mov rax, 1 ; Syscall number (write)
syscall
Counter (RCX)
; Loop counter
mov rcx, 10
loop_start:
; body
loop loop_start ; Decrements RCX, jumps if not zero
Source/Destination (RSI/RDI)
; String operations
mov rsi, source_string
mov rdi, dest_string
mov rcx, length
rep movsb ; Copy RSI to RDI
Stack Operations (RSP/RBP)
; RSP points to top of stack
push rax ; Decrements RSP, stores RAX
pop rbx ; Loads into RBX, increments RSP
; RBP used for stack frame
push rbp
mov rbp, rsp ; Set up stack frame
Exercises
Exercise 1: Register Mapping
List all accessible forms of RAX:
- 64-bit: RAX
- 32-bit: EAX
- 16-bit: AX
- 8-bit high: AH
- 8-bit low: AL
Do the same for RBX, RCX, RDX, RSI, RDI.
Exercise 2: Instruction Cycle Trace
Trace these instructions through fetch-decode-execute:
mov rax, 5
add rax, 3
mov rbx, rax
Exercise 3: Flag Prediction
Predict flag states after these operations:
1. mov rax, 5
sub rax, 5 ; CF=?, ZF=?, SF=?, OF=?
2. mov rax, 255
add rax, 1 ; CF=?, ZF=?, SF=?, OF=? (8-bit context)
3. mov rax, -1
add rax, 1 ; CF=?, ZF=?, SF=?, OF=?
Exercise 4: Memory Hierarchy
Calculate approximate time for:
- Reading a value from L1 cache (4 cycles, 2 GHz CPU)
- Reading from RAM (100 cycles, 2 GHz CPU)
- Reading from SSD (50,000 cycles, 2 GHz CPU)
Exercise 5: Register Reference Card
Create a cheat sheet with:
- All general-purpose registers
- Their 64/32/16/8-bit forms
- Common uses
- Calling convention roles (we’ll cover this later)
Mini-Project: CPU Simulator (Paper Exercise)
Create a simple CPU simulation on paper:
- 4 registers: A, B, C, D (8-bit each)
- 16 bytes of memory
- Instructions: MOV, ADD, SUB, JMP
- Flags: Z (zero), N (negative)
Execute this program:
MOV A, 5 ; A = 5
MOV B, 3 ; B = 3
ADD A, B ; A = A + B = 8
MOV [0], A ; Memory[0] = 8
SUB A, B ; A = A - B = 5
Track:
- Register values after each instruction
- Memory contents
- Flag states
- Instruction pointer
Week 1 Summary
Key Concepts Mastered
✓ Binary, decimal, and hexadecimal number systems ✓ Bitwise operations: AND, OR, XOR, NOT, shifts ✓ CPU architecture components ✓ Memory hierarchy ✓ Instruction cycle: fetch-decode-execute ✓ x86-64 register architecture
Skills Developed
✓ Quick number conversions ✓ Bit manipulation techniques ✓ Understanding CPU operation ✓ Register usage patterns
Preparation for Week 2
Next week, you’ll:
- Set up your development environment
- Write your first assembly program
- Learn about program structure and sections
- Implement basic I/O operations
Daily Practice Routine
- 15 min: Number conversions
- 15 min: Bitwise operation problems
- 30 min: Review register architecture
Resources
- Khan Academy: Computer Science basics
- Wikipedia: x86 architecture
- Intel 64 and IA-32 Software Developer Manuals (online)
Week 1 Assessment
Test your knowledge:
- Convert 0xCAFE to binary and decimal
- What is
0b10101010 ^ 0b11110000? - Name all 8 main general-purpose x86-64 registers
- What are the 4 stages of the instruction cycle?
- What is the difference between RAX and EAX?
- Which flag is set when subtraction results in zero?
- Calculate:
(42 >> 2) << 1in decimal - What is the fastest memory in the computer?
- Which register is used as the stack pointer?
- How do you check if bit 5 is set in a value?
Answers in next week’s material!
Congratulations on completing Week 1!
Week 2: Introduction to Assembly Language
Overview
This week you’ll set up your development environment, write your first assembly programs, understand program structure, and implement basic input/output operations.
Day 1-2: Development Environment Setup
Learning Objectives
- Install and configure assembler (NASM)
- Install and configure debugger (GDB)
- Set up text editor with assembly support
- Compile and run your first program
- Understand the assembly toolchain
Installation
Linux (Ubuntu/Debian)
# Update package list
sudo apt-get update
# Install NASM (Netwide Assembler)
sudo apt-get install nasm
# Install GDB (GNU Debugger)
sudo apt-get install gdb
# Install build essentials
sudo apt-get install build-essential
# Verify installations
nasm -v
gdb --version
macOS
# Install Homebrew if not already installed
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install NASM
brew install nasm
# Install GDB
brew install gdb
# Verify installations
nasm -v
gdb --version
Windows (WSL - Windows Subsystem for Linux)
# Enable WSL and install Ubuntu from Microsoft Store
# Then follow Linux instructions above
# Alternative: Install NASM for Windows directly
# Download from: https://www.nasm.us/
# Add to PATH environment variable
Text Editor Setup
VS Code (Recommended)
# Install VS Code
# Download from: https://code.visualstudio.com/
# Install extensions:
# 1. "x86 and x86_64 Assembly" by 13xforever
# 2. "ASM Code Lens" by maziac
# 3. "NASM" by Right-5
# Optional: Configure build tasks (tasks.json)
{
"version": "2.0.0",
"tasks": [
{
"label": "assemble",
"type": "shell",
"command": "nasm -f elf64 ${file} -o ${fileBasenameNoExtension}.o",
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "link",
"type": "shell",
"command": "ld ${fileBasenameNoExtension}.o -o ${fileBasenameNoExtension}",
"group": "build"
}
]
}
Vim/Neovim
" Add to .vimrc or init.vim
" Syntax highlighting
syntax on
filetype plugin indent on
" NASM-specific settings
autocmd BufRead,BufNewFile *.asm set filetype=nasm
autocmd FileType nasm setlocal expandtab shiftwidth=4 softtabstop=4
Your First Assembly Program
hello.asm
; hello.asm - First assembly program
; Purpose: Print "Hello, Assembly World!" to console
section .data
; Define our message
msg db 'Hello, Assembly World!', 0x0A ; 0x0A = newline
msg_len equ $ - msg ; Calculate length
section .text
global _start ; Entry point for linker
_start:
; Write message to stdout
; syscall: write(fd, buffer, count)
mov rax, 1 ; syscall number for write
mov rdi, 1 ; file descriptor: 1 = stdout
mov rsi, msg ; pointer to message
mov rdx, msg_len ; message length
syscall ; invoke system call
; Exit program
; syscall: exit(status)
mov rax, 60 ; syscall number for exit
xor rdi, rdi ; exit status: 0 = success
syscall ; invoke system call
Build Process
Step-by-Step Build
# Step 1: Assemble (source code → object file)
nasm -f elf64 hello.asm -o hello.o
# -f elf64: output format for 64-bit Linux
# hello.asm: input source file
# -o hello.o: output object file
# Step 2: Link (object file → executable)
ld hello.o -o hello
# ld: GNU linker
# hello.o: input object file
# -o hello: output executable
# Step 3: Run
./hello
Understanding the Output
Hello, Assembly World!
Build Script (Makefile)
# Makefile for assembly programs
ASM = nasm
ASMFLAGS = -f elf64
LINKER = ld
LDFLAGS =
# Default target
all: hello
# Build hello
hello: hello.o
$(LINKER) $(LDFLAGS) hello.o -o hello
hello.o: hello.asm
$(ASM) $(ASMFLAGS) hello.asm -o hello.o
# Clean build artifacts
clean:
rm -f *.o hello
# Phony targets
.PHONY: all clean
Usage:
make # Build
make clean # Clean
Understanding System Calls
What is a System Call?
- Interface between user program and operating system
- Requests OS services (I/O, memory, processes)
- x86-64 Linux uses the
syscallinstruction
Common Linux System Calls (x86-64)
| Syscall | RAX | Description | Parameters |
|---|---|---|---|
| read | 0 | Read from file | RDI=fd, RSI=buffer, RDX=count |
| write | 1 | Write to file | RDI=fd, RSI=buffer, RDX=count |
| open | 2 | Open file | RDI=filename, RSI=flags, RDX=mode |
| close | 3 | Close file | RDI=fd |
| exit | 60 | Exit program | RDI=status |
File Descriptors
- 0 = stdin (standard input)
- 1 = stdout (standard output)
- 2 = stderr (standard error)
Exercises
Exercise 1: Modify the Message
Change the message to print your name:
msg db 'Hello, [Your Name]!', 0x0A
Exercise 2: Multiple Messages
Print two lines:
section .data
msg1 db 'First line', 0x0A
len1 equ $ - msg1
msg2 db 'Second line', 0x0A
len2 equ $ - msg2
section .text
global _start
_start:
; Print first message
mov rax, 1
mov rdi, 1
mov rsi, msg1
mov rdx, len1
syscall
; Print second message
mov rax, 1
mov rdi, 1
mov rsi, msg2
mov rdx, len2
syscall
; Exit
mov rax, 60
xor rdi, rdi
syscall
Exercise 3: Exit with Different Status
; Exit with status code 42
mov rax, 60
mov rdi, 42
syscall
Check exit status:
./hello
echo $? # Prints: 42
Exercise 4: Using GDB
# Assemble with debug symbols
nasm -f elf64 -g -F dwarf hello.asm -o hello.o
ld hello.o -o hello
# Debug
gdb ./hello
# GDB commands:
(gdb) break _start # Set breakpoint
(gdb) run # Run program
(gdb) info registers # Show registers
(gdb) stepi # Step one instruction
(gdb) continue # Continue execution
(gdb) quit # Exit GDB
Troubleshooting Common Issues
Issue 1: “command not found: nasm”
# Check if installed
which nasm
# If not found, reinstall
sudo apt-get install nasm
Issue 2: “Permission denied”
# Make executable
chmod +x hello
./hello
Issue 3: “cannot execute binary file”
# Check if correct architecture
file hello
# Should show: ELF 64-bit LSB executable, x86-64
# If wrong architecture, reassemble with correct format
nasm -f elf64 hello.asm -o hello.o
Issue 4: Segmentation Fault
- Check that you’re using correct syscall numbers
- Verify register values before syscall
- Use GDB to find exact failure point
Day 3-4: Program Structure & Sections
Learning Objectives
- Understand assembly program organization
- Master different section types
- Learn data declaration directives
- Use special operators ($ and $$)
Section Types
.data Section
Purpose: Initialized data (variables with values)
section .data
; Syntax: label <directive> <value>
; Integer data
byte_var db 0x42 ; Define byte (1 byte)
word_var dw 0x1234 ; Define word (2 bytes)
dword_var dd 0x12345678 ; Define double word (4 bytes)
qword_var dq 0x123456789ABCDEF0 ; Define quad word (8 bytes)
; Multiple values (arrays)
array dd 1, 2, 3, 4, 5 ; Array of 5 dwords
matrix db 1, 2, 3, 4 ; 2x2 matrix as flat array
; Strings
string1 db 'Hello', 0 ; Null-terminated string
string2 db 'World', 0x0A, 0 ; With newline
; Floating-point
float_var dd 3.14159 ; Single precision (4 bytes)
double_var dq 2.71828 ; Double precision (8 bytes)
; Repeated values
zeros times 10 db 0 ; 10 bytes of zeros
buffer times 100 db ' ' ; 100 spaces
.bss Section
Purpose: Uninitialized data (reserved space)
section .bss
; Syntax: label <reserve_directive> <count>
; Reserve bytes
buffer1 resb 64 ; Reserve 64 bytes
buffer2 resb 256 ; Reserve 256 bytes
; Reserve words/dwords/qwords
word_buf resw 10 ; Reserve 10 words (20 bytes)
dword_buf resd 20 ; Reserve 20 dwords (80 bytes)
qword_buf resq 5 ; Reserve 5 qwords (40 bytes)
; Large buffers
large_buf resb 1024*1024 ; Reserve 1 MB
Why use .bss?
- Doesn’t increase executable file size
- OS allocates memory at runtime
- Automatically initialized to zero
.text Section
Purpose: Executable code
section .text
global _start ; Make _start visible to linker
_start:
; Your code here
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, len
syscall
; More code
mov rax, 60
xor rdi, rdi
syscall
; Additional functions
my_function:
; Function code
ret
.rodata Section
Purpose: Read-only data (constants)
section .rodata
; Constants that shouldn't be modified
pi dd 3.14159
version db 'Version 1.0', 0
error_msg db 'Error occurred!', 0x0A
msg_len equ $ - error_msg
Data Declaration Directives
Size Directives
| Directive | Size | Description | Example |
|---|---|---|---|
| DB | 1 byte | Define Byte | db 42, ‘A’, 0xFF |
| DW | 2 bytes | Define Word | dw 0x1234, 1000 |
| DD | 4 bytes | Define Double Word | dd 0x12345678 |
| DQ | 8 bytes | Define Quad Word | dq 0x123456789ABCDEF0 |
| DT | 10 bytes | Define Ten Bytes | dt 1.23 (extended precision) |
Reserve Directives
| Directive | Size | Description | Example |
|---|---|---|---|
| RESB | 1 byte | Reserve Bytes | resb 100 |
| RESW | 2 bytes | Reserve Words | resw 50 |
| RESD | 4 bytes | Reserve Double Words | resd 25 |
| RESQ | 8 bytes | Reserve Quad Words | resq 10 |
Special Operators
$ Operator (Current Position)
Returns the current address in the section
section .data
msg db 'Hello, World!', 0x0A
msg_len equ $ - msg ; Calculate length
; $ points to position after msg
; msg_len = current_position - start_of_msg = length
Example:
section .data
str1 db 'First' ; Address: 0x1000
len1 equ $ - str1 ; $ = 0x1005, len1 = 5
str2 db 'Second' ; Address: 0x1005
len2 equ $ - str2 ; $ = 0x100B, len2 = 6
$$ Operator (Section Start)
Returns the address of the beginning of current section
section .data
; $$ points to start of .data section
var1 dd 100
offset1 equ $ - $$ ; Offset from section start
var2 dd 200
offset2 equ $ - $$ ; Different offset
EQU Directive (Define Constant)
Defines a constant value (no memory allocated)
section .data
; Constants
BUFFER_SIZE equ 1024
MAX_USERS equ 100
EOF equ -1
; Calculated constants
msg db 'Hello'
MSG_LEN equ $ - msg
; Using constants
buffer resb BUFFER_SIZE
users resd MAX_USERS
Complete Program Example
; complete_example.asm
; Demonstrates all sections and directives
; Constants
BUFFER_SIZE equ 64
SUCCESS equ 0
FAILURE equ 1
section .data
; Messages
prompt db 'Enter your name: '
prompt_len equ $ - prompt
greeting db 'Hello, '
greeting_len equ $ - greeting
newline db 0x0A
; Numbers
counter dd 0
max_count dd 10
; Arrays
numbers dd 1, 2, 3, 4, 5
numbers_count equ ($ - numbers) / 4 ; Count of dwords
section .bss
; Buffers
name_buffer resb BUFFER_SIZE
temp_buffer resb 256
; Variables
result resq 1
status resd 1
section .rodata
; Constants (read-only)
version db 'v1.0.0', 0
author db 'Your Name', 0
section .text
global _start
_start:
; Print prompt
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, prompt
mov rdx, prompt_len
syscall
; Read name
mov rax, 0 ; sys_read
mov rdi, 0 ; stdin
mov rsi, name_buffer
mov rdx, BUFFER_SIZE
syscall
; Store bytes read
mov [result], rax
; Print greeting
mov rax, 1
mov rdi, 1
mov rsi, greeting
mov rdx, greeting_len
syscall
; Print name
mov rax, 1
mov rdi, 1
mov rsi, name_buffer
mov rdx, [result]
syscall
; Exit
mov rax, 60
mov rdi, SUCCESS
syscall
Exercises
Exercise 1: Data Declaration Practice
Create a program with:
- 5 different integer types (byte, word, dword, qword)
- 2 strings
- 1 array of 10 elements
- 1 floating-point number
Exercise 2: Calculate Sizes
section .data
array1 db 1, 2, 3, 4, 5
array1_len equ $ - array1 ; What is the value?
array2 dw 1, 2, 3, 4, 5
array2_len equ $ - array2 ; What is the value?
array3 dd 1, 2, 3, 4, 5
array3_len equ $ - array3 ; What is the value?
Calculate lengths and element counts for each array.
Exercise 3: Menu Program
Create a program that displays a menu:
=== Main Menu ===
1. Option One
2. Option Two
3. Option Three
4. Exit
Enter choice:
Use proper sections and calculate all string lengths.
Exercise 4: Buffer Allocation
Allocate buffers in .bss section:
- Input buffer: 256 bytes
- Output buffer: 512 bytes
- Temp storage: 1024 bytes
Exercise 5: Constants and Calculations
; Define constants
SCREEN_WIDTH equ 80
SCREEN_HEIGHT equ 25
SCREEN_SIZE equ SCREEN_WIDTH * SCREEN_HEIGHT
; Use them
section .bss
screen_buffer resb SCREEN_SIZE
Create similar constants for:
- Maximum string length
- Number of menu items
- Buffer size in KB
Mini-Project: Information Display
Create a program that displays:
====================================
System Information Display
====================================
Program: Your Program Name
Version: 1.0.0
Author: Your Name
Built: 2024
Press Enter to exit...
====================================
Requirements:
- Use all four section types (.data, .bss, .text, .rodata)
- Calculate all string lengths with $
- Use EQU for constants
- Wait for user input before exiting
Day 5-7: System Calls & Basic I/O
Learning Objectives
- Master Linux system call interface
- Implement input operations (read)
- Implement output operations (write)
- Handle file descriptors
- Create interactive programs
Linux System Call Interface
System Call Mechanism
- Place syscall number in RAX
- Place arguments in: RDI, RSI, RDX, R10, R8, R9
- Execute
syscallinstruction - Result returned in RAX
- Errors: RAX contains negative errno
System Call Table (x86-64 Linux)
| Number | Name | RAX | Arguments |
|---|---|---|---|
| 0 | read | 0 | RDI=fd, RSI=buf, RDX=count |
| 1 | write | 1 | RDI=fd, RSI=buf, RDX=count |
| 2 | open | 2 | RDI=pathname, RSI=flags, RDX=mode |
| 3 | close | 3 | RDI=fd |
| 60 | exit | 60 | RDI=status |
| 89 | readlink | 89 | RDI=path, RSI=buf, RDX=bufsiz |
Full list: /usr/include/asm/unistd_64.h
File Descriptors
Standard Descriptors
STDIN equ 0 ; Standard input
STDOUT equ 1 ; Standard output
STDERR equ 2 ; Standard error
Usage:
; Write to stdout
mov rdi, STDOUT
; Write to stderr
mov rdi, STDERR
; Read from stdin
mov rdi, STDIN
Output Operations (write syscall)
Basic Write
; ssize_t write(int fd, const void *buf, size_t count);
; Returns: number of bytes written, or -1 on error
section .data
msg db 'Hello!', 0x0A
msg_len equ $ - msg
section .text
global _start
_start:
mov rax, 1 ; syscall: write
mov rdi, 1 ; fd: stdout
mov rsi, msg ; buffer address
mov rdx, msg_len ; byte count
syscall ; RAX = bytes written
; Exit
mov rax, 60
xor rdi, rdi
syscall
Writing Multiple Strings
section .data
str1 db 'Line 1', 0x0A
len1 equ $ - str1
str2 db 'Line 2', 0x0A
len2 equ $ - str2
str3 db 'Line 3', 0x0A
len3 equ $ - str3
section .text
global _start
_start:
; Write string 1
mov rax, 1
mov rdi, 1
mov rsi, str1
mov rdx, len1
syscall
; Write string 2
mov rax, 1
mov rdi, 1
mov rsi, str2
mov rdx, len2
syscall
; Write string 3
mov rax, 1
mov rdi, 1
mov rsi, str3
mov rdx, len3
syscall
; Exit
mov rax, 60
xor rdi, rdi
syscall
Writing to stderr
section .data
error_msg db 'ERROR: Something went wrong!', 0x0A
error_len equ $ - error_msg
section .text
global _start
_start:
; Write to stderr
mov rax, 1
mov rdi, 2 ; stderr = 2
mov rsi, error_msg
mov rdx, error_len
syscall
; Exit with error code
mov rax, 60
mov rdi, 1 ; exit status: 1 = error
syscall
Input Operations (read syscall)
Basic Read
; ssize_t read(int fd, void *buf, size_t count);
; Returns: number of bytes read, 0 on EOF, -1 on error
section .bss
buffer resb 64 ; 64-byte buffer
section .text
global _start
_start:
; Read from stdin
mov rax, 0 ; syscall: read
mov rdi, 0 ; fd: stdin
mov rsi, buffer ; buffer address
mov rdx, 64 ; max bytes to read
syscall ; RAX = bytes actually read
; RAX now contains number of bytes read
; buffer contains the data
; Exit
mov rax, 60
xor rdi, rdi
syscall
Echo Program
; Reads input and writes it back
section .bss
input_buffer resb 256
section .text
global _start
_start:
; Read from stdin
mov rax, 0
mov rdi, 0
mov rsi, input_buffer
mov rdx, 256
syscall
; Save bytes read
mov r12, rax ; Store count in R12
; Write to stdout
mov rax, 1
mov rdi, 1
mov rsi, input_buffer
mov rdx, r12 ; Use saved count
syscall
; Exit
mov rax, 60
xor rdi, rdi
syscall
Interactive Programs
Prompt and Read
section .data
prompt db 'Enter your name: '
prompt_len equ $ - prompt
greeting db 'Hello, '
greeting_len equ $ - greeting
newline db 0x0A
section .bss
name resb 32
section .text
global _start
_start:
; Display prompt
mov rax, 1
mov rdi, 1
mov rsi, prompt
mov rdx, prompt_len
syscall
; Read name
mov rax, 0
mov rdi, 0
mov rsi, name
mov rdx, 32
syscall
mov r12, rax ; Save length
; Display greeting
mov rax, 1
mov rdi, 1
mov rsi, greeting
mov rdx, greeting_len
syscall
; Display name
mov rax, 1
mov rdi, 1
mov rsi, name
mov rdx, r12
syscall
; Exit
mov rax, 60
xor rdi, rdi
syscall
Multiple Inputs
section .data
prompt1 db 'Enter first number: '
plen1 equ $ - prompt1
prompt2 db 'Enter second number: '
plen2 equ $ - prompt2
result_msg db 'Numbers entered!', 0x0A
rlen equ $ - result_msg
section .bss
num1 resb 16
num2 resb 16
section .text
global _start
_start:
; Get first number
mov rax, 1
mov rdi, 1
mov rsi, prompt1
mov rdx, plen1
syscall
mov rax, 0
mov rdi, 0
mov rsi, num1
mov rdx, 16
syscall
; Get second number
mov rax, 1
mov rdi, 1
mov rsi, prompt2
mov rdx, plen2
syscall
mov rax, 0
mov rdi, 0
mov rsi, num2
mov rdx, 16
syscall
; Display result
mov rax, 1
mov rdi, 1
mov rsi, result_msg
mov rdx, rlen
syscall
; Exit
mov rax, 60
xor rdi, rdi
syscall
Exercises
Exercise 1: Simple Output
Create a program that prints:
********************
* Assembly Rules! *
********************
Exercise 2: Error Message
Write a program that:
- Prints normal message to stdout
- Prints error message to stderr
- Exits with code 1
Exercise 3: Name Collector
Prompt for and read:
- First name
- Last name
- Age Display all information back
Exercise 4: Character Counter
Read input and count how many characters were entered (use return value of read).
Exercise 5: Loop Input
Read and echo input 5 times in a loop.
Complete Project: Interactive Menu
; menu.asm - Interactive menu system
section .data
banner db '=========================', 0x0A
banner_len equ $ - banner
title db ' MAIN MENU', 0x0A
title_len equ $ - title
opt1 db '1. View Information', 0x0A
opt1_len equ $ - opt1
opt2 db '2. Settings', 0x0A
opt2_len equ $ - opt2
opt3 db '3. Exit', 0x0A
opt3_len equ $ - opt3
prompt db 'Enter choice: '
prompt_len equ $ - prompt
choice1_msg db 'You selected: View Information', 0x0A
choice1_len equ $ - choice1_msg
choice2_msg db 'You selected: Settings', 0x0A
choice2_len equ $ - choice2_msg
exit_msg db 'Goodbye!', 0x0A
exit_len equ $ - exit_msg
invalid_msg db 'Invalid choice!', 0x0A
invalid_len equ $ - invalid_msg
newline db 0x0A
section .bss
choice resb 2
section .text
global _start
_start:
; Print banner
mov rax, 1
mov rdi, 1
mov rsi, banner
mov rdx, banner_len
syscall
; Print title
mov rax, 1
mov rdi, 1
mov rsi, title
mov rdx, title_len
syscall
; Print banner again
mov rax, 1
mov rdi, 1
mov rsi, banner
mov rdx, banner_len
syscall
; Print options
mov rax, 1
mov rdi, 1
mov rsi, opt1
mov rdx, opt1_len
syscall
mov rax, 1
mov rdi, 1
mov rsi, opt2
mov rdx, opt2_len
syscall
mov rax, 1
mov rdi, 1
mov rsi, opt3
mov rdx, opt3_len
syscall
; Print newline
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
; Print prompt
mov rax, 1
mov rdi, 1
mov rsi, prompt
mov rdx, prompt_len
syscall
; Read choice
mov rax, 0
mov rdi, 0
mov rsi, choice
mov rdx, 2
syscall
; Check choice
mov al, [choice]
cmp al, '1'
je choice_1
cmp al, '2'
je choice_2
cmp al, '3'
je choice_3
jmp invalid_choice
choice_1:
mov rax, 1
mov rdi, 1
mov rsi, choice1_msg
mov rdx, choice1_len
syscall
jmp exit_program
choice_2:
mov rax, 1
mov rdi, 1
mov rsi, choice2_msg
mov rdx, choice2_len
syscall
jmp exit_program
choice_3:
mov rax, 1
mov rdi, 1
mov rsi, exit_msg
mov rdx, exit_len
syscall
jmp exit_program
invalid_choice:
mov rax, 1
mov rdi, 1
mov rsi, invalid_msg
mov rdx, invalid_len
syscall
exit_program