Exemples de Langage Assembleur

Exemples essentiels de programmation en langage assembleur pour la programmation de bas niveau

Key Facts

Category
Programming Languages
Items
2
Format Families
sample

Sample Overview

Exemples essentiels de programmation en langage assembleur pour la programmation de bas niveau This sample set belongs to Programming Languages and can be used to test related workflows inside Elysia Tools.

💻 Hello World en Assembleur assembly

🟢 simple ⭐⭐⭐⭐

Programme Hello World de base et concepts fondamentaux de programmation assembleur

⏱️ 25 min 🏷️ assembly, low-level, x86, system programming, machine code
Prerequisites: Computer architecture basics, Understanding of CPU architecture, Memory management
; Assembly Hello World Examples
; These examples use x86-64 assembly syntax (NASM)
; Target: 64-bit Linux/macOS/Windows

section .data
    hello_msg db "Hello, World!", 0
    greeting_msg db "Welcome to Assembly Programming", 0
    name_msg db "Your name: ", 0
    buffer db 256 dup(0)

section .bss
    input_buffer resb 256

section .text
    global _start

_start:
    ; === Basic Hello World ===
    mov rax, 1                  ; system call number for write
    mov rdi, 1                  ; file descriptor 1 (stdout)
    lea rsi, [rel hello_msg]     ; address of message
    mov rdx, hello_msg_len       ; length of message
    syscall                       ; make system call

    ; === Hello World with Variable ===
    mov rax, 1
    mov rdi, 1
    lea rsi, [rel greeting_msg]
    mov rdx, greeting_msg_len
    syscall

    ; === Input Simulation ===
    mov rax, 1
    mov rdi, 1
    lea rsi, [rel name_msg]
    mov rdx, name_msg_len
    syscall

    ; Read input (commented out as this is interactive)
    ; mov rax, 0                  ; system call for read
    ; mov rdi, 0                  ; file descriptor 0 (stdin)
    ; lea rsi, [rel input_buffer] ; buffer
    ; mov rdx, 255                ; max bytes to read
    ; syscall

    ; Exit program
    mov rax, 60                 ; system call for exit
    xor rdi, rdi                 ; exit code 0
    syscall

    ; === Function Example ===
print_message:
    push rbp                    ; save base pointer
    mov rbp, rsp                ; set new base pointer

    mov rax, 1                  ; system call for write
    mov rdi, 1                  ; stdout
    mov rsi, rdi                ; message from stack
    mov rdx, 8                  ; 8 bytes (64-bit pointer)
    syscall                       ; write message

    pop rbp                     ; restore base pointer
    ret                         ; return

section .data
    hello_msg db "Hello, World!", 10
    greeting_msg db "Welcome to Assembly Programming", 35
    name_msg db "Your name: ", 12
    name_msg_len equ $ - name_msg
    hello_msg_len equ $ - hello_msg
    greeting_msg_len equ $ - greeting_msg

section .bss
    input_buffer resb 256

; Alternative Hello World with registers only
section .text
    global _start_registers_ops

_start_registers_ops:
    ; Create message directly in registers
    mov r10, 0x574F4C6C           ; W
    mov r11, 0x6F7266C6           ; o
    mov r12, 0x726C64C2           ; r
    mov r13, 0x6C20646C           ; l
    mov r14, 0x20644D20           ;

; --- Data Definitions ---
section .data
    hello_msg_data db "Hello, World!", 10
    multiline_msg db "Line 1", 10, 13, 10
                db "Line 2", 10, 13, 10
                db "Line 3", 10
    newline db 10
    goodbye_msg db "Goodbye!", 0

    numbers dq 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    text db "Assembly programming", 0

section .bss
    input_buffer2 resb 256
    result_buffer resb 100
    counter resq 4

; --- Registers and Memory Operations ---
section .text
    global _start_registers

_start_registers:
    ; Initialize registers
    xor rax, rax              ; Clear RAX
    mov rbx, 42               ; RBX = 42
    mov rcx, 100              ; RCX = 100
    mov rdx, 314              ; RDX = 314 (integer immediate)

    ; Memory operations
    mov [counter], 0           ; Store 0 at counter address
    mov rbx, [counter]          ; Load from counter to RBX
    inc rbx                   ; RBX = RBX + 1
    mov [counter], rbx          ; Store back to memory

    ; --- Stack Operations ---
    push rax                   ; Save RAX on stack
    push rbx                   ; Save RBX on stack
    push rcx                   ; Save RCX on stack

    pop rcx                    ; Restore RCX from stack
    pop rbx                    ; Restore RBX from stack
    pop rax                    ; Restore RAX from stack

    ; --- Conditional Logic ---
    cmp rbx, 42                ; Compare RBX with 42
    je equal_to_42              ; Jump if equal

    not_equal_to_42:
        mov rax, 1              ; Return 1
        jmp done

    equal_to_42:
        mov rax, 0              ; Return 0

    done:
    ; Exit with status in RAX
    mov rdi, rax              ; Exit code from RAX
    mov rax, 60              ; System call for exit
    syscall

; --- Basic Arithmetic Operations ---
section .text
    global _start_arithmetic

_start_arithmetic:
    ; Addition
    mov rax, 10
    add rax, 5              ; RAX = 10 + 5 = 15
    call print_number        ; Print 15

    ; Subtraction
    mov rax, 20
    sub rax, 8              ; RAX = 20 - 8 = 12
    call print_number        ; Print 12

    ; Multiplication
    mov rax, 6
    imul rax, 7             ; RAX = 6 * 7 = 42
    call print_number        ; Print 42

    ; Division
    mov rax, 50
    mov rdx, 4
    xor rcx, rcx              ; Clear RCX for unsigned division
    idiv rdx                  ; RAX = RAX / RDX, RDX = remainder
    ; RAX = 12, RDX = 2
    call print_number        ; Print quotient
    mov rax, rdx              ; Move remainder to RAX
    call print_number        ; Print remainder

    jmp end_program

; --- Control Flow Examples ---
section .text
    global _start_control_flow

_start_control_flow:
    ; If-else-if structure (using jumps)
    mov rbx, 25              ; Age = 25

    cmp rbx, 18
    jl minor                ; Jump if less than
    je adult
    jge major

    minor:
        call print_minor
        jmp end_if

    adult:
    cmp rbx, 65
    jle senior
    jmp adult_65_or_younger

    major:
    call print_adult
    jmp end_if

    senior:
    call print_senior

    end_if:
    ; Switch-like structure (using jump table)
    mov rcx, 3              ; Day = 3

    cmp rcx, 1
    je print_monday
    cmp rcx, 2
    je print_tuesday
    cmp rcx, 3
    je print_wednesday
    cmp rcx, 4
    je print_thursday
    cmp rcx, 5
    je print_friday
    jmp print_weekend

print_monday:
    call print_monday_func
    jmp end_switch

print_tuesday:
    call print_tuesday_func
    jmp end_switch

print_wednesday:
    call print_wednesday_func
    jmp end_switch

print_thursday:
    call print_thursday_func
    jmp end_switch

print_friday:
    call print_friday_func
    jmp end_switch

print_weekend:
    call print_weekend_func

end_switch:
    jmp loop_example

loop_example:
    ; For loop example (countdown)
    mov rcx, 5              ; Counter = 5

countdown_loop:
    call print_counter
    dec rcx                  ; Decrement counter
    test rcx, rcx            ; Test if zero
    jnz countdown_loop        ; Continue if not zero

    ; While loop example
    mov rbx, 0              ; Counter = 0

while_loop:
    cmp rbx, 3              ; Compare with 3
    jge end_while           ; Exit if >= 3

    call print_counter
    inc rbx                  ; Increment counter
    jmp while_loop

end_while:
    jmp end_program

; --- Loops and Iteration ---
section .text

print_counter:
    push rax                  ; Save registers
    push rdx
    push rcx

    ; Convert number to string (simplified)
    lea rdi, [rel buffer]
    mov r10, rcx              ; Copy counter to R10
    call int_to_ascii       ; Convert to ASCII
    mov byte [rdi], 0        ; Null terminator
    call print_string

    pop rcx                   ; Restore registers
    pop rdx
    pop rax
    ret

; --- String Operations ---
section .text

print_string:
    push rax                  ; Save registers
    push rdi
    push rdx

    ; Calculate string length
    mov rax, rdi              ; String address
    xor rcx, rcx              ; RCX = 0
    mov rdx, rdi              ; Start address

find_end:
    cmp byte [rdx], 0        ; Check for null terminator
    je end_found            ; Found end if null
    inc rcx                  ; Increment count
    inc rdx                  ; Move to next byte
    jmp find_end           ; Continue searching

end_found:
    ; Print string (system call)
    mov rax, 1              ; write syscall
    mov rdi, 1              ; stdout
    lea rsi, [rel buffer]     ; String address
    mov rdx, rcx              ; String length
    syscall

    pop rdx                   ; Restore registers
    pop rdi
    pop rax
    ret

; Simple ASCII to integer conversion
int_to_ascii:
    ; Input: number in RCX, output buffer in RDI
    mov rax, rcx              ; Copy number to RAX
    mov rbx, 10              ; Divisor

convert_loop:
    test rax, rax            ; Check if zero
    je done_converting

    xor rdx, rdx              ; Clear RDX
    div rbx                  ; Divide by 10
    add rdx, '0'             ; Add ASCII '0' (48)
    push rdx                  ; Save digit
    jmp convert_loop

done_converting:
    ; Pop digits and build string
    mov rbx, rdi              ; Buffer position
    pop rcx                  ; Digit
    mov byte [rbx], cl          ; Store digit

    test rcx, rcx              ; Check if more digits
    jne more_digits
    mov byte [rbx], 0        ; Null terminator

    ret

more_digits:
    inc rbx                  ; Move buffer position
    jmp done_converting

print_number:
    push rax                  ; Save registers
    push rdi
    push rdx
    push rcx

    ; Convert RAX to ASCII
    lea rdi, [rel buffer]
    mov r10, rax              ; Copy number to R10
    call int_to_ascii       ; Convert to ASCII
    mov byte [rdi], 0        ; Null terminator
    call print_string

    pop rcx                   ; Restore registers
    pop rdx
    pop rdi
    pop rax
    ret

print_minor:
    mov rax, 1
    call print_message
    ret

print_adult:
    mov rax, 2
    call print_message
    ret

print_senior:
    mov rax, 3
    call print_message
    ret

print_monday_func:
    mov rax, 4
    call print_message
    ret

print_tuesday_func:
    mov rax, 5
    call print_message
    ret

print_wednesday_func:
    mov rax, 6
    call print_message
    ret

print_thursday_func:
    mov rax, 7
    call print_message
    ret

print_friday_func:
    mov rax, 8
    call print_message
    ret

print_weekend_func:
    mov rax, 9
    call print_message
    ret

; --- Memory and Pointers ---
section .text
global _start_memory

_start_memory:
    ; Allocate memory on stack
    sub rsp, 32              ; Allocate 32 bytes

    ; Store values in memory
    mov dword [rsp], 0x12345678    ; Little endian: 0x78563412
    mov dword [rsp + 4], 0x9abcdef0   ; Little endian: 0xf0cde9ba
    mov dword [rsp + 8], 0x13579ace   ; Little endian: 0xce9a5713

    ; Load and display
    mov eax, [rsp]
    call print_hex        ; Print first 32-bit value

    mov eax, [rsp + 8]
    call print_hex        ; Print second 32-bit value

    ; Restore stack
    add rsp, 32
    jmp end_program

print_hex:
    push rax                  ; Save registers
    push rcx
    push rdx
    push rsi
    push rdi
    push r8
    push r9
    push r10
    push r11

    ; Print in hex format
    lea rsi, [rel buffer]    ; Buffer address
    mov rdi, 0              ; No flags
    mov rax, rax              ; Value to print
    call print_hex_with_prefix

    pop r11
    pop r10
    pop r9
    pop r8
    pop rdi
    pop rsi
    pop rdx
    pop rcx
    pop rax
    ret

print_hex_with_prefix:
    ; RAX: value, RDI: flags, RSI: buffer address
    push rax                  ; Save registers
    push rbx
    push rcx
    push rdx
    push rsi
    push rdi

    ; Add prefix
    mov byte [rsi], '0'
    mov byte [rsi + 1], 'x'

    ; Convert to hex string
    mov rbx, rax              ; Copy value to RBX
    shr rbx, 32               ; Get high byte
    and rbx, 0xFF           ; Keep only low byte
    call byte_to_hex
    mov [rsi + 2], bl

    mov rbx, rax              ; Restore value
    and rbx, 0xFF           ; Get low byte
    call byte_to_hex
    mov [rsi + 3], bl

    mov byte [rsi + 4], ' '
    shr rax, 48               ; Get high 16 bits
    and rax, 0xFFFF           ; Keep only 16 bits
    shr rax, 8
    call byte_to_hex
    mov [rsi + 5], bl

    mov rbx, rax              ; Restore 16 bits
    and rbx, 0xFF
    call byte_to_hex
    mov [rsi + 6], bl

    shr rax, 8
    and rbx, 0xFF
    call byte_to_hex
    mov [rsi + 7], bl

    and rax, 0xFF
    call byte_to_hex
    mov [rsi + 8], bl

    mov byte [rsi + 9], 0   ; Null terminator
    call print_string

    pop rdi
    pop rsi
    pop rdx
    pop rcx
    pop rbx
    pop rax
    ret

byte_to_hex:
    ; Input: RBX = byte value (0-15), output: BL = ASCII hex character
    cmp rbx, 10
    jl less_than_10
    cmp rbx, 15
    jg greater_than_15

between_10_15:
    add rbx, 'A' - 10    ; Convert to A-F
    jmp done_hex

less_than_10:
    add rbx, '0'           ; Convert to 0-9
    jmp done_hex

greater_than_15:
    mov bl, '?'           ; Invalid byte
    jmp done_hex

done_hex:
    ret

; --- System Calls and OS Interaction ---
section .text
global _start_system

_start_system:
    ; Get current time
    mov rax, 201              ; sys_gettimeofday
    xor rdi, rdi              ; Clear RDI (struct pointer)
    lea rsi, [rel time_struct]
    xor rdx, rdx              ; Clear RDX (timezone pointer)
    syscall

    ; Extract seconds from time struct (64-bit)
    mov rbx, [rsi]          ; Get seconds value

    ; Print current time (simplified)
    lea rsi, [rel buffer]
    mov rdi, 1              ; stdout
    mov rdx, 50              ; Max length
    call format_time_string

    mov rax, 1
    syscall

    ; Get process ID
    mov rax, 39              ; sys_getpid
    syscall

    mov rbx, rax              ; Process ID
    lea rsi, [rel buffer]
    mov rdi, 1
    mov rdx, 20
    call format_process_id

    mov rax, 1
    syscall

    ; File operations (create file)
    mov rax, 2              ; sys_open
    lea rdi, [rel filename]
    mov rsi, 0x41            ; O_WRONLY | O_CREAT
    mov rdx, 0o600            ; rw-rw-rw-
    mov r10, 0o664            ; rw-rw-rw-
    syscall

    ; Save file descriptor
    mov r14, rax              ; Save file descriptor

    ; Write to file
    mov rax, 1              ; sys_write
    mov rdi, r14              ; File descriptor
    lea rsi, [rel file_content]
    mov rdx, file_content_len
    syscall

    ; Close file
    mov rax, 3              ; sys_close
    mov rdi, r14              ; File descriptor
    syscall

    jmp end_program

; --- Helper Functions ---
section .data
    filename db "assembly_output.txt", 0
    file_content db "This is written from assembly!", 32
    file_content_len equ $ - file_content

format_string:
    db "Current time: %ld seconds", 0

format_process_id:
    db "Process ID: %d", 0

buffer: 256

time_struct:
    .tv_sec dq 0          ; seconds since epoch
    .tv_usec dq 0         ; microseconds

section .bss
    time_struct: resb sizeof(time_struct)

; --- String Constants ---
section .data
    print_minor: db "You are a minor (under 18)", 0
    print_adult: db "You are an adult (18-64)", 0
    print_senior: db "You are a senior (65+)", 0

    print_monday: db "Monday", 0
    print_tuesday: db "Tuesday", 0
    print_wednesday: db "Wednesday", 0
    print_thursday: db "Thursday", 0
    print_friday: db "Friday", 0
    print_weekend: db "Weekend", 0

    hello_data:
    .long 0x6F726C6C6F20456C6C6F20
    .long 0x4F2064C6C692C656E
    .quad 0x50726578696C6C6F
    .quad 0x676F672A6D69736

    greeting_data:
    .long 0x57656C65736574206969
    .long 0x73206C6F67267616D
    .quad 0x726F726F676D72696E
    .quad 0x676C6F676D6C6B20

    name_data:
    .long 0x59686F6C620656C64
    .long 0x7320C3F972064656E
    .quad 0x6F75726965736C6C64

section .bss
    input_buffer: resb 256
    result_buffer: resb 256

    ; Length calculations
    hello_msg_len equ $ - hello_msg
    greeting_msg_len equ $ - greeting_msg
    name_msg_len equ $ - name_msg

; --- Program Exit ---
end_program:
    mov rax, 60             ; sys_exit
    xor rdi, rdi             ; Exit code 0
    syscall

💻 Gestion Mémoire Assembleur assembly

🟡 intermediate ⭐⭐⭐⭐⭐

Opérations avancées de mémoire dans langage assembleur

⏱️ 40 min 🏷️ assembly, x86, low-level, system programming
Prerequisites: Computer architecture fundamentals, Assembly language basics, System call knowledge, Memory management
; Assembly Memory Management Examples
; x86-64 assembly (NASM syntax)
; Shows stack allocation, heap allocation, and pointer operations

section .data
    prompt db "Enter a number: ", 0
    result_msg db "Result: %d", 0
    newline db 10

section .bss
    heap_buffer resb 4096    ; 4KB heap

section .text
    global _start

_start:
    ; Initialize stack frame
    push rbp                ; Save base pointer
    mov rbp, rsp            ; Set new base pointer

    ; === Stack Allocation ===
    sub rsp, 32              ; Allocate 32 bytes on stack
    mov dword [rsp], 100     ; Store first integer
    mov dword [rsp + 4], 200  ; Store second integer
    mov dword [rsp + 8], 300  ; Store third integer
    mov dword [rsp + 12], 400 ; Store fourth integer

    ; Display stack values
    call print_stack_values

    ; === Heap Allocation ===
    ; Request memory from operating system
    mov rax, 12              ; mmap system call
    mov rdi, 0              ; addr = NULL (let OS choose)
    mov rsi, 4096           ; size = 4KB
    mov rdx, 3              ; PROT_READ | PROT_WRITE
    mov r10, 0x22            ; MAP_PRIVATE | MAP_ANONYMOUS
    xor r8, r8              ; No flags
    syscall

    ; Check if allocation succeeded
    test rax, rax
    js allocation_failed    ; Jump if allocation failed
    mov r15, rax              ; Save heap pointer

    ; Write to heap
    mov dword [r15], 1000    ; Store value
    mov dword [r15 + 4], 2000 ; Store value
    mov dword [r15 + 8], 3000 ; Store value

    ; Display heap values
    call print_heap_values

    ; === Pointer Operations ===
    mov r12, r15              ; R12 = heap pointer
    mov r13, [r12]         ; R13 = *R12

    ; Pointer arithmetic
    add r13, 8              ; R13 = R13 + 8
    mov [r12 + 8], 4000     ; *(R12 + 8) = 4000

    ; Display updated heap values
    call print_updated_heap

    ; Pointer offset calculation
    mov r13, r15              ; R13 = heap pointer
    lea r14, [r13 + 16]    ; R14 = R13 + 16
    mov [r14], 5000     ; Store value at R14
    mov dword [r14 + 4], 6000 ; Store value at R14 + 4

    ; Display offset example
    call print_offset_example

    ; === Dynamic Memory Reallocation ===
    ; Free current allocation
    mov rax, 11              ; munmap system call
    mov rdi, r15              ; address to free
    mov rsi, 4096           ; size to free
    syscall

    ; Reallocate larger memory
    mov rax, 12              ; mmap system call
    mov rdi, 0              ; NULL
    mov rsi, 8192           ; 8KB
    mov rdx, 3              ; PROT_READ | PROT_WRITE
    mov r10, 0x22            ; MAP_PRIVATE | MAP_ANONYMOUS
    xor r8, r8              ; No flags
    syscall

    test rax, rax
    js allocation_failed
    mov r15, rax              ; New heap pointer

    ; Copy data from temporary storage
    mov rsi, rsp              ; Use stack as temporary storage
    mov dword [rsi], 1000   ; First value
    mov dword [rsi + 4], 2000 ; Second value
    mov dword [rsi + 8], 3000 ; Third value
    mov rdx, 12              ; 3 values to copy

    rep movsq
    copy data from RSI to [R15]
    mov rdi, r15              ; Destination (heap)
    mov rsi, rsp              ; Source (stack)
    syscall

    ; Display reallocated heap
    call print_reallocated_heap

    ; === Array Operations ===
    ; Allocate array on heap
    mov rax, 12              ; mmap system call
    mov rdi, 0
    mov rsi, 80              ; 20 integers * 4 bytes = 80 bytes
    mov rdx, 3              ; PROT_READ | PROT_WRITE
    mov r10, 0x22            ; MAP_PRIVATE | MAP_ANONYMOUS
    xor r8, r8
    syscall

    test rax, rax
    js allocation_failed
    mov r14, rax              ; Array pointer

    ; Fill array with values
    mov rdi, 0              ; Index = 0
    mov r10, 20              ; Array length

array_fill_loop:
    mov dword [r14 + rdi*4], rdi  ; array[index] = index
    inc rdi                  ; increment index
    cmp rdi, r10              ; Compare with array length
    jl array_fill_loop        ; Continue if index < length

    ; Display array
    call print_array

    ; === Memory Cleanup ===
    free_heap:
        ; Free array
        mov rax, 11              ; munmap
        mov rdi, r14              ; address
        mov rsi, 80              ; size
        syscall

        ; Free heap
        mov rax, 11              ; munmap
        mov rdi, r15              ; address
        mov rsi, 4096           ; size
        syscall

    free_stack:
        ; Restore stack
        add rsp, 32              ; Deallocate stack memory
        pop rbp                ; Restore base pointer

    ; Exit program
    mov rax, 60
    xor rdi, rdi
        syscall

allocation_failed:
    call print_error
    mov rax, 60
    mov rdi, 1              ; Exit code 1 (error)
        syscall

; --- Helper Functions ---

print_stack_values:
    push rax                  ; Save registers
    push rdi
    push rsi
    push rdx

    lea rsi, [rel stack_msg]
    mov rax, 1
    mov rdi, 1
    syscall

    ; Print values
    lea rdi, [rel stack_msg]
    mov eax, [rsp]           ; First value
    call print_int
    lea rdi, [rel second_msg]
    mov eax, [rsp + 4]     ; Second value
    call print_int
    lea rdi, [rel third_msg]
    mov eax, [rsp + 8]     ; Third value
    call print_int
    lea rdi, [rel fourth_msg]
    mov eax, [rsp + 12]    ; Fourth value
    print_int:
        push rax              ; Save number
        lea rsi, [rel format_buffer]
        mov rdx, 20
        call format_int
        mov rax, 1
        mov rdi, 1
        syscall
        pop rax              ; Restore number
        jmp print_string

    pop rdx
    pop rsi
    pop rdi
    pop rax
    ret

print_heap_values:
    push rax
    push rdi
    push rsi
    push rdx

    lea rsi, [rel heap_msg]
    mov rax, 1
    mov rdi, 1
    syscall

    mov eax, [r15]           ; First value
    call print_int
    mov eax, [r15 + 4]       ; Second value
    call print_int
    mov eax, [r15 + 8]       ; Third value
    call print_int

    pop rdx
    pop rsi
    pop rdi
    pop rax
    ret

print_updated_heap:
    push rax
    push rdi
    push rsi
    push rdx

    lea rsi, [rel updated_msg]
    mov rax, 1
    mov rdi, 1
    syscall

    ; Display original values
    mov eax, [r12]         ; *R12 (was 1000)
    call print_int
    mov eax, [r12 + 8]     ; *(R12 + 8) (was 2000)
    call print_int

    ; Display updated values
    lea rdi, [rel updated_value_msg]
    mov eax, [r12]         ; *R12 (now 1000)
    call print_int
    lea rdi, [rel updated_at_msg]
    mov eax, [r12 + 8]     ; *(R12 + 8) (now 4000)
    call print_int

    lea rdi, [rlf_separator]
    mov rax, 1
    mov rdi, 1
    syscall

    pop rdx
    pop rsi
    pop rdi
    pop rax
    ret

print_offset_example:
    push rax
    push rdi
    push rsi
    push rdx

    lea rsi, [rel offset_msg]
    mov rax, 1
    mov rdi, 1
    syscall

    lea rdi, [rel base_pointer_msg]
    mov rbx, r12             ; Base pointer
    call print_hex
    lea rsi, [rlf_separator]
    mov rax, 1
    syscall

    lea rdi, [rel offset_value_msg]
    mov r13, [r13]         ; R13 = R12 + 16
    call print_hex
    lea rsi, [rlf_separator]
    mov rax, 1
    syscall

    lea rdi, [rlf_separator]
    mov rax, 1
    syscall

    pop rdx
    pop rsi
    pop rdi
    pop rax
    ret

print_reallocated_heap:
    push rax
    push rdi
    push rsi
    push rdx

    lea rsi, [rel reallocated_msg]
    mov rax, 1
    mov rdi, 1
    syscall

    ; Display all values
    lea rdi, [rlf_separator]
    mov eax, [r15]         ; First value
    call print_int
    lea rdi, [rlf_separator]
    mov eax, [r15 + 4]     ; Second value
    call print_int
    lea rdi, [r15 + 8]     ; Third value
    call print_int

    lea rsi, [rlf_separator]
    mov rax, 1
    syscall

    pop rdx
    pop rsi
    pop rdi
    pop rax
    ret

print_array:
    push rax
    push rdi
    push rsi
    push rdx

    lea rsi, [rel array_msg]
    mov rax, 1
    mov rdi, 1
    syscall

    lea rdi, [rlf_separator]
    mov r10, 0              ; Index = 0
array_print_loop:
    cmp r10, 20              ; Compare with array length
    jge array_done           ; Exit if done

    lea rdi, [rlf_format_int]
    mov rdi, 1
    mov eax, [r14 + r10*4]  ; array[index]
    call print_int
    lea rdi, [rlf_separator]
    mov rax, 1
    syscall

    inc r10                  ; Increment index
    jmp array_print_loop

array_done:
    pop rdx
    pop rsi
    pop rdi
    pop rax
    ret

print_int:
    ; Input: EAX = integer, RDI = buffer, RDX = max length
    ; Output: integer in RAX
    ; Note: Simplified - doesn't handle negatives or large numbers
    push rax
    push rdi
    push rsi

    lea rsi, [rdi]         ; String buffer address
    mov r8, rax              ; Copy number
    xor rbx, rbx              ; Clear RBX (no negative handling)
    add r8, '0'              ; Convert to ASCII

    ; Determine number of digits
    cmp r8, 10              ; Less than 10
    jl single_digit

    ; Two or more digits
    mov r9, 10
    digit_loop:
        xor rdx, rdx              ; Clear RDX for division
        xor r10, r10              ; Clear R10 for remainder
        div rbx, r9              ; Divide by 10
        add r11, '0'             ; ASCII '0'
        add r11, r10             ; Add remainder ASCII
        mov [rsi], r11         ; Store digit character
        inc rsi                  ; Move buffer position
        cmp r8, 10              ; Check if more digits
    jge digit_loop

    single_digit:
        add r11, '0'             ; ASCII '0'
        mov [rsi], r11         ; Single digit

    ; Terminate string
    mov byte [rsi], 0        ; Null terminator

    mov byte [rsi], 10       ; Newline
    mov byte [rsi + 1], 0     ; Newline

    pop rsi
    pop rdi
    pop rax
    ret

print_error:
    push rax
    push rdi
    push rsi

    lea rsi, [rel error_msg]
    mov rax, 1
    mov rdi, 2              ; stderr
    syscall

    pop rsi
    pop rdi
    pop rax
    ret

; --- String Constants ---
section .data
    stack_msg db "Stack values:", 0
    second_msg db "Value 1: ", 0
    third_msg db "Value 2: ", 0
    fourth_msg db "Value 3: ", 0

    heap_msg db "Heap values:", 0
    updated_msg db "Original: [1000, 2000], Updated: [1000, 4000]", 0
    updated_value_msg db "Updated at offset 16: 4000", 0

    base_pointer_msg db "Base pointer: ", 0
    offset_value_msg db "Value at R12+16: ", 0

    array_msg db "Array contents:", 0
    offset_msg db "Offset example pointer arithmetic:", 0

    reallocated_msg db "Reallocated heap (8KB) contents:", 0

    error_msg db "Error: Memory allocation failed!", 0
    format_buffer: db "%d"

    format_int: db "%d", 0
    format_hex: db "0x%016x", 0

    buffer: 256

rlf_separator db "--------------------", 10
    newline db 10

section .bss
    ; Variables
    input_buffer: resb 256
    result_buffer: resb 256

; Length calculations
    greeting_msg_len equ $ - greeting_msg
    hello_msg_len equ $ - hello_msg
    name_msg_len equ $ - name_msg

    ; Memory allocation sizes
    stack_size equ 32          ; 4 integers on stack
    heap_size equ 4096         ; 4KB on heap
    array_size equ 80           ; 20 integers (20 * 4 bytes)
    large_heap_size equ 8192      ; 8KB for reallocation

end_program:
    jmp _start_memory

; --- Static Data Examples ---
section .data
    static_int: dd 12345678
    static_float: dd 3.14159
    static_string: db "Hello from .data section", 0
    static_array: dd 1, 2, 3, 4, 5
    static_2d_array:
        dw 1, 2, 3, 4
        dw 5, 6, 7, 8

section .text
    global _start_static

_start_static:
    ; Access static data
    mov rax, [rel static_int]
    call print_hex        ; Print static_int as hex
    mov rdx, [rel static_float]
    call print_float

    ; Access static string
    mov rax, 1
    mov rdi, 1              ; stdout
    lea rsi, [rel static_string]
    mov rdx, static_string_len
    syscall

    ; Access static array
    mov rax, [static_array + 8]  ; Access element 2 (0-based index 2 = 3)
    call print_int        ; Should print 3

    ; Access 2D array
    mov rax, [static_2d_array + 8]  ; Access element at [1][0]
    call print_int        ; Should print 5

    ; Exit
    mov rax, 60
    xor rdi, rdi
    syscall

static_int_len equ $ - static_int
static_string_len equ $ - static_string

; --- Data Alignment Examples ---
section .data
    aligned_data align 16
    db "This data is aligned on 16-byte boundary", 0
    unaligned_data db "This data has no alignment constraints", 0

    ; Aligned arrays
    aligned_array1 dd 1.0, 2.0, 3.0
    aligned_array2 dd 4.0, 5.0, 6.0

section .bss
    aligned_buffer resb 1024  ; 1KB aligned on page boundary

section .text
    global _start_aligned

_start_aligned:
    ; Demonstrate alignment
    lea rsi, [rel aligned_data]
    call print_string

    lea rsi, [rel unaligned_data]
    call print_string

    ; Show aligned addresses
    lea rsi, [rel aligned_array1]
    lea rdx, [rel aligned_array1]
    call print_hex_with_prefix
    mov byte [rsi], 10
    lea rsi, [rel aligned_array1 + 8]
    lea rdx, [rel aligned_array1 + 8]
    call print_hex_with_prefix

    mov rax, 60
    xor rdi, rdi
    syscall

    ret

print_hex_with_prefix:
    ; Input: RAX = value, RDI = flags, RSI = buffer
    push rax
    push rdi
    push rsi
    push rdx
    push rcx
    push r11

    ; Print "0x" prefix
    mov byte [rsi], '0'
    mov byte [rsi + 1], 'x'

    ; Convert to hex
    mov rax, rax              ; Value to print
    shr rax, 32               ; Get high byte
    and rbx, 0xFF           ; Keep only low byte
    call byte_to_hex
    mov [rsi + 2], bl

    shr rax, rax              ; Get high 16 bits
    and rax, 0xFFFF           ; Keep only 16 bits
    shr rax, rax              ; Get high byte
    and rbx, 0xFF           ; Keep low byte
    call byte_to_hex
    mov [rsi + 6], bl

    shr rax, rax              ; Get high byte
    and rbx, 0xFF           ; Keep low byte
    call byte_to_hex
    mov [rsi + 10], bl

    mov byte [rsi + 12], ' '
    mov byte [rsi + 13], 0   ; Null terminator
    call print_string

    pop r11
    pop rcx
    pop rdx
    pop rsi
    pop rdi
    pop rax
    ret

print_float:
    ; Print floating point number (simplified)
    ; Input: RDX = double precision float
    push rax
    push rdi
    push rdx

    ; Simple floating point printing (not comprehensive)
    ; This is a very basic implementation
    mov rbx, rdx              ; Move float to RBX
    mov rcx, 0              ; Initialize integer part
    integer_part trunc rbx      ; Extract integer part
    mov rdx, rbx
    sub rdx, integer_part    ; Get fractional part
    rdx = rdx * 10         ; Scale for 1 decimal place

    ; Print integer part
    lea rsi, [rel format_buffer]
    mov rax, integer_part
    call print_int
    lea rsi, [rlf_separator]
    mov rax, 1
    syscall

    ; Print decimal part
    lea rsi, [rlf_separator]
    mov rax, rdx
    call print_int

    pop rdx
    pop rdi
    pop rax
    ret

section .data
    format_float: db "%.1f", 0

rlf_separator db "; ", 10

; --- Type Examples ---
section .data
    char_data: db "A", "B", "C", "D", "E", 0
    word_data: dw 0x41424C42, 0x4F6E69742, 0x727465742, 0x6E6F6C6F
    dword_data: dq 0x123456789ABCDEF000, 0xFEDCBA9876543210
    qword_data: dq 0x0123456789ABCDEF000, 0x89ABCDEF0123456789, 0xFEDCBA9876543210, 0x0ABCDEF0123456789

section .bss
    char_array resb 6
    word_array resw 5
    dword_array resd 2
    qword_array resq 2

section .text
    global _start_types

_start_types:
    ; Character operations
    lea rdi, [rel char_data]
    mov al, [rdi + 1]     ; Get 'B'
    cmp al, 'A'           ; Compare with 'A'
    mov al, 'a'           ; Convert to lowercase if needed

    ; Print all characters
    char_loop:
        cmp al, 0              ; Check for null terminator
        je char_done
        call print_char
        inc rdi              ; Move to next character
        jmp char_loop

char_done:
    lea rsi, [rlf_separator]
    call print_string

    ; Word operations (little-endian)
    mov rsi, [rel word_data]
    mov r10, 0              ; Index 0
    word_loop:
    cmp r10, length(word_data) / 8
    jge word_done

    ; Get word at index r10
    mov rax, [rsi + r10*4]
    call print_hex
    lea rsi, [rlf_separator]
    inc r10
    jmp word_loop

word_done:
    lea rsi, [rlf_separator]
    call print_string

    ; Double word operations
    lea rsi, [rel dword_data]
    mov r10, 0              ; Index 0
    dword_loop:
    cmp r10, length(dword_data) / 8
    jge dword_done

    ; Get dword at index r10
    mov rax, [rsi + r10*8]
    mov rbx, rax              ; Low 32 bits
    shr rdx, 32                ; High 32 bits
    or rax, rbx              ; Combine high and low
    call print_hex
    lea rsi, [rlf_separator]
    inc r10
    jmp dword_loop

dword_done:
    lea rsi, [rlf_separator]
    call print_string

    ; Quad word operations
    lea rsi, [rel qword_data]
    mov r10, 0              ; Index 0
    qword_loop:
    cmp r10, length(qword_data) / 16
    jge qword_done

    ; Get quad word at index r10
    mov rax, [rsi + r10*16]     ; Low 64 bits
    mov rbx, [rsi + r10*16 + 8] ; High 64 bits
    call print_hex
    lea rsi, [rlf_separator]
    inc r10
    jmp qword_loop

qword_done:
    lea rsi, [rlf_separator]
    call print_string

    ; Exit
    mov rax, 60
    xor rdi, rdi
    syscall

print_char:
    push rax
    mov rax, 1
    mov rdi, 1
    mov rsi, rdi
    mov rdx, 1
    syscall
    pop rax
    ret

length:
    $ equ $ - word_data
    length: equ $ - dword_data
    length: equ $ - qword_data

end_program:
    jmp _start_types

; --- System Call Examples ---
section .text
    global _start_syscalls

_start_syscalls:
    ; === File Operations ===
    ; Create file
    mov rax, 2              ; sys_open
    lea rdi, [rel test_file]
    mov rsi, 0o641        ; O_WRONLY | O_CREAT
    mov rdx, 0o644        ; 0o640
    mov r10, 0o666        ; rw-rw-rw-
    syscall

    test rax, rax              ; Check for error
    js file_error

    mov r15, rax              ; Save file descriptor

    ; Write to file
    mov rax, 1              ; sys_write
    mov rdi, r15              ; File descriptor
    lea rsi, [rel file_content]
    mov rdx, file_content_len
    syscall

    ; Close file
    mov rax, 3              ; sys_close
    mov rdi, r15              ; File descriptor
    syscall

    ; === Directory Operations ===
    ; Create directory
    mov rax, 83             ; sys_mkdir
    lea rdi, [rel test_dir]
    mov rsi, 0o755        ; drwxr-xr-x
    syscall

    test rax, rax              ; Check for error
    js dir_error

    ; === Process Operations ===
    ; Fork process
    mov rax, 57             ; sys_fork
    syscall

    test rax, rax              ; Check fork result
    js parent_process

parent_process:
    ; Wait for child process
    mov rax, 61             ; sys_wait4
    xor rdi, rdi              ; No status request
    syscall

    jmp end_syscalls

child_process:
    ; Child process executes here
    mov rax, 60             ; sys_exit
    mov rdi, 0              ; Exit code 0
    syscall

file_error:
    call print_error
    jmp end_syscalls

dir_error:
    call print_error
    jmp end_syscalls

end_syscalls:
    jmp end_program

section .data
    test_file db "test_file.txt", 0
    test_dir db "test_directory", 0
    file_content db "This is test content written from assembly!", 0
    file_content_len equ $ - file_content

; === Constants ===
    O_RDONLY equ 0o000000
    O_WRONLY equ 0o000001
    O_RDWR equ 00000002
    O_CREAT equ 00000100
    O_EXCL equ 00000200
    O_TRUNC equ 00001000
    O_APPEND equ 0000200
    O_DIRECTORY = 00040000
    O_NOFOLLOW = 0100000
    O_SYNC = 0010000

    PROT_READ equ 0x1
    PROT_WRITE equ 0x2
    PROT_EXEC = 0x4

    MAP_PRIVATE equ 0x02
    MAP_ANONYMOUS equ 0x20
    MAP_SHARED equ 0x01
    MAP_DENYWRITE 0x100

    STDIN_FILENO equ 0
    STDOUT_FILENO equ 1
    STDERR_FILENO equ 2

    --- Environment Variables ---
section .data
    envp_home db "/home/user", 0
    envp_path db "/usr/bin:/bin", 0
    envp_lang db "en_US.UTF-8", 0

section .bss
    env_vars resb 64

    ; String length calculations
    file_content_len equ $ - file_content
    test_file_len equ $ - test_file
    test_dir_len equ $ - test_dir

    ; === Debugging Examples ===
section .text
    global _start_debug

_start_debug:
    ; Enable debugging output
    pushfq  ; Clear all flags

    ; Print register states
    call print_registers

    ; Stack manipulation example
    push r15
    push r14
    push r13
    push r12
    push r11
    push r10
    push r9
    push r8
    push rdx
    push rcx
    push rbx
    push rax

    ; Display initial stack state
    call print_stack_frame

    ; Modify stack
    pop rax
    mov rax, 999
    push rax
    inc qword ptr [rsp]    ; Access through modified pointer

    ; Display modified stack state
    call print_stack_frame

    ; Restore all registers
    pop rax
    pop rbx
    pop rcx
    pop rdx
    pop r9
    pop r10
    pop r11
    pop r12
    pop r13
    pop r14
    pop r15

    ; Exit with status 0
    mov rax, 60
    xor rdi, rdi
    syscall

; --- Utility Functions ---

print_registers:
    ; Print all general-purpose registers
    push rax
    push rdi
    push rsi
    push rdx

    ; General purpose registers
    lea rdi, [rl register_msg]
    mov rax, r15          ; R15
    mov rbx, r14          ; R14
    rcx, r13           ; RCX
    rdx, r12           ; RDX
    rsi, r11           ; R11
    r10, r10           ; R10
    r9, r9              ; R9
    r8, r8              ; R8

    call print_hex_with_prefix
    lea rsi, [rlf_separator]
    mov rax, r13           ; RCX
    lea rdx, [rlf_separator]
    mov rbx, r14           ; RBX
    call print_hex_with_prefix
    lea rdi, [rlf_separator]
    mov rax, r15           ; R15
    lea rdx, [rlf_separator]
    mov rbx, r12           ; RDX
    call print_hex_with_prefix

    ; Special purpose registers
    lea rdi, [rlf_sep2]
    mov rdi, [rlf_rip]
    call print_hex_with_prefix
    lea rdi, [rlf_separator]
    mov rdi, [rlf_rsp]
    call print_hex_with_prefix

    lea rdi, [rlf_separator]
    mov rdi, [rlf_flags]
    mov rax, rflags           ; RFLAGS register
    call print_hex_with_prefix

    lea rdi, [rlf_separator]
    mov rdi, [rlf_instruction_pointer]
    mov rax, [rip]             ; Instruction pointer
    call print_hex_with_prefix

    pop rdx
    pop rsi
    pop rax
    ret

print_stack_frame:
    ; Print stack frame information
    push rax
    push rdi
    push rsi
    push rdx

    lea rdi, [rl stack_msg]
    mov rbp, [rsp]           ; Get current base pointer

    lea rsi, [rl rbp_msg]
    mov rax, rbp
    call print_hex_with_prefix

    lea rdi, [rlf_separator]
    lea rdi, [rl rsp_msg]
    mov rax, rsp             ; Current stack pointer
    sub rax, rbp             ; Calculate size of frame
    call print_hex_with_prefix

    lea rdi, [rl_frame_end_msg]
    call print_string

    pop rdx
    pop rsi
    pop rax
    ret

print_hex_with_prefix:
    ; Input: RAX = value, RDI = flags, RSI = buffer, RDX = max length
    push rax
    push rdi
    push rsi
    push rdx
    push rcx

    add rsp, 32              ; Adjust for saves

    ; Determine value range and use appropriate format
    cmp rax, -2147483648       ; Most negative 32-bit int
    jl signed_32
    cmp rax, 2147483647        ; Most positive 32-bit int
    jle signed_32

signed_32:
    mov rdx, 11             ; Max digits for 32-bit signed int
    lea rsi, [rl format_int32]
    mov rcx, rax              ; Number to ASCII
    jmp print_number_core

unsigned_32:
    mov rdx, 10             ; Max digits for 32-bit unsigned int
    lea rsi, [rel format_uint32]
    mov rcx, rax              ; Number to ASCII
    jmp print_number_core

print_number_core:
    ; Print number using standard formatting
    ; RAX = number, RDI = flags, RSI = buffer, RDX = max length, RCX = number
    ; RBX is modified by print_number_core to return

    mov rdx, rax              ; Number
    lea rsi, [rsi]           ; Buffer address

    digit_loop:
    xor rcx, rcx              ; Clear RCX
    mov rax, rdx              ; Move number back
    div rcx, 10             ; Extract last digit
    add rbx, '0'             ; Convert to ASCII
    mov [rsi], rbx
    inc rsi                   ; Increment buffer position
    cmp rcx, 0
    jne digit_loop

    mov byte [rsi], 0       ; Null terminator
    call print_string
    add rsp, 32              ; Restore stack
    pop rcx
    pop rdx
    pop rdi
    pop rax
    ret

print_stack_msg: db "Stack frame:", 0
rlf_separator: db "--------------------", 10
rlf_rsp: db "RSP:", 0
rlf_rbp: db "RBP:", 0
rlf_instruction_pointer: db "RIP:", 0
rlf_flags: db "RFLAGS:", 0
rlf_frame_end_msg: db "End of frame", 0

rlf_separator: db "; ", 10
rlf_sep2: db "; ", 10

format_int32: db "%d", 0
format_uint32: db "%u", 0

register_msg: db "General Purpose:", 0
rlf_rip: db "RIP:", 0
rlf_rsp: db "RSP:", 0
rlf_flags: db "RFLAGS:", 0
rlf_instruction_pointer: db "RIP:", 0

format_hex: db "0x%016lx", 0

section .bss
    input_buffer resb 256
    result_buffer resb 256

    ; Constants
    STDIN_FILENO equ 0
    STDOUT_FILENO equ 1
    STDERR_FILENO equ 2

    ; Length calculations
    greeting_msg_len equ $ - greeting_data
    hello_data_len equ $ - hello_data
    name_msg_len equ $ - name_data

print_error:
    push rax
    push rdi
    push rsi

    lea rsi, [rel error_msg]
    mov rax, 1
    mov rdi, 2              ; stderr
    syscall

    pop rsi
    pop rdi
    pop rax
    ret

; --- Memory Management Examples ---
section .text
    global _start_memory_management

_start_memory_management:
    ; Initialize stack
    push rbp
    mov rbp, rsp

    ; Allocate different sized memory blocks
    mov rdi, 0x1000        ; 4KB
    mov rsi, 0x2000        ; 8KB
    mov rdx, 0x3000        ; 12KB

    ; Get memory from OS
    mov rax, 9              ; mmap system call
    xor rdi, rdi              ; Let OS choose address
    mov rsi, 0x1000          ; 4KB
    mov rdx, 0x07              ; PROT_READ | PROT_WRITE
    mov r10, 0x22            ; MAP_PRIVATE | MAP_ANONYMOUS
    xor r8, r8
    syscall

    test rax, rax
    js memory_error

    ; Save heap pointer
    mov [heap_pointer], rax

    ; === Memory Operations ===
    ; Write to different memory areas
    mov dword [rdi], 0x12345678
    mov dword [rsi], 0x9ABCDEF0
    mov dword [rsi], 0x13579ACE
    mov dword [rdx], 0x2468ACE

    ; Read and display values
    call display_memory_contents

    ; Memory comparison
    mov rax, [rdi]          ; Get first dword
    mov rbx, [rsi]          ; Get second dword
    cmp rax, rbx            ; Compare values

    je values_equal
    values_not_equal:
        lea rsi, [rlf_memory_different_msg]
        call print_string
        jmp end_memory_management
    values_equal:
        lea rsi, [rlf_memory_same_msg]
        call print_string

    end_memory_management:
    ; Clean up
    ; Free allocated memory
    mov rax, 11          ; munmap
    mov rdi, [heap_pointer]
    mov rsi, 0x1000      ; Size
    syscall

    mov rax, r11          ; free stack allocation
    sub rsp, rax          ; Restore stack pointer

    pop rbp
    ret

display_memory_contents:
    lea rsi, [rlf_memory_contents]
    mov r10, 0              ; Counter

memory_display_loop:
    cmp r10, 4              ; Number of dwords
    jge memory_done

    lea rdi, [rlf_item_1]
    mov rax, [rdi]          ; Get value
    call print_hex
    lea rdi, [rlf_separator]
    inc r10
    jmp memory_display_loop

memory_done:
    lea rsi, [rlf_separator]
    call print_string

    ret

values_different:
    lea rsi, [rlf_memory_different_msg]
    call print_string
    ret

values_equal:
    lea rsi, [rlf_memory_same_msg]
    call print_string
    ret

; --- Advanced Pointer Examples ---
section .text
    global _start_pointers

_start_pointers:
    ; Create base pointers
    mov r12, 0x1000        ; Base pointer 1
    mov r13, 0x2000        ; Base pointer 2
    mov r14, 0x3000        ; Base pointer 3

    ; Create pointer array
    mov [pointer_array], r12
    mov [pointer_array + 8], r13
    [pointer_array + 16], r14

    ; Print pointer addresses
    lea rsi, [rlf_pointer_array_msg]
    call print_string

    lea rsi, [rlf_pointer_addr_1]
    mov rax, [pointer_array]
    call print_hex_with_prefix
    lea rsi, [rlf_pointer_addr_2]
    mov rax, [pointer_array + 8]
    call print_hex_with_prefix
    lea rsi, [rlf_pointer_addr_3]
    mov rax, [pointer_array + 16]
    call print_hex_with_prefix

    ; Pointer arithmetic
    lea r15, [pointer_array + 24]  ; R15 = array end
    sub r15, pointer_array        ; R15 = array start
    lea rsi, [rlf_pointer_arithmetic_msg]
    call print_string
    lea rsi, [rlf_array_end_addr]
    mov rax, r15
    call print_hex_with_prefix
    lea rsi, [rlf_array_start_addr]
    mov rax, [pointer_array]
    call print_hex_with_prefix

    ; Exit
    mov rax, 60
    xor rdi, rdi
    syscall

rlf_pointer_array_msg: db "Pointer array:", 0
rlf_pointer_addr_1: db "Pointer 1: ", 0
rlf_pointer_addr_2: db "Pointer 2: ", 0
rlf_pointer_addr_3: db "Pointer 3: ", 0
rlf_array_end_addr: db "Array end: ", 0

rlf_separator: db "; ", 10
rlf_pointer_arithmetic_msg: db "Pointer arithmetic (end - start): ", 0
rlf_array_start_addr: db "Array start: ", 0
rlf_array_end_addr: db "Array end: ", 0

section .data
    pointer_array: resq 4
    heap_pointer: resq 1

; --- Error Handling ---
section .text
global _start_error_handling

_start_error_handling:
    ; Try division by zero
    mov rax, 10
    xor rdx, rdx              ; Division by zero
    div idiv rdx              ; Divide RAX by RDX

    test rdx, rdx              ; Check if division was attempted
    jz division_success  ; No division attempted

division_error:
    lea rsi, [rlf_division_error_msg]
    call print_string
    jmp end_error_handling

division_success:
    lea rsi, [rlf_division_success_msg]
    call print_string
    jmp end_error_handling

    ; Access memory out of bounds
    mov rax, 0              ; Invalid pointer
    mov [rax], 42            ; This will cause segmentation fault
    jmp segmentation_fault

segmentation_fault:
    lea rsi, [rlf_seg_fault_msg]
    call print_string
    jmp end_error_handling

invalid_memory_access:
    lea rsi, [rlf_invalid_access_msg]
    call print_string

end_error_handling:
    mov rax, 60             ; Exit code
    xor rdi, rdi
    syscall

rlf_division_error_msg: db "Division by zero attempted!", 0
rlf_division_success_msg: "Division successful", 0
rlf_seg_fault_msg: db "Segmentation fault - invalid memory access!", 0
rlf_invalid_access_msg: db "Invalid memory access!", 0

; --- Performance Measurement ---
section .text
global _start_performance

_start_performance:
    ; Get start time
    mov rax, 201              ; sys_gettimeofday
    xor rdi, rdi
    lea rsi, [rel time_struct]
    syscall

    ; Perform some operations
    mov rcx, 1000           ; Initialize loop counter

performance_loop:
    ; Simple computation in loop
    imul r13, r13        ; Multiply
        add r13, r12        add r13, r11
        loop performance_loop
        dec rcx

    ; Get end time
    mov rax, 201              ; sys_gettimeofday
    xor rdi, rdi
    lea rsi, [rel time_struct]
    syscall

    Calculate time difference
    sub r13, [rsi]          ; end time start time (microseconds)
    sub r12, [rsi + 8]      ; start time seconds
    sub r13, [rsi + 8]      ; end time seconds

    ; Calculate operations per second
    mov r15, 1000
    imul r15, r12          ; Operations * time difference
    idiv r15, r13          ; Operations per second

    ; Print results
    lea rsi, [rlf_performance_msg]
    call print_string
    lea rsi, [rlf_time_elapsed_msg]
    call print_float
    lea rdi, [rlf_ops_per_sec_msg]
    call print_string

    mov rax, 60
    xor rdi, rdi
    syscall

section .data
    time_struct:
    .tv_sec dq 0
    .tv_usec dq 0

rlf_performance_msg: db "Performance Results:", 0
rlf_time_elapsed_msg: db "Time elapsed: %.2f s", 0
rlf_ops_per_sec_msg: db "Operations per second: %.2f ops/s", 0

rlf_separator: db "; ", 10

format_float: db "%.2f", 0

; --- Input/Output Operations ---
section .text
global _start_io_operations

_start_io_operations:
    ; Setup buffer
    sub rsp, 256
    lea rdi, [rsp]        ; Input buffer
    mov byte [rdi], 0       ; Initialize buffer

    ; Simple input simulation (commented out in real programs)
    ; mov rax, 0              ; sys_read
    ; mov rdi, 0              ; stdin
    ; lea rsi, [rsp]        ; buffer
    ; mov rdx, 255             ; max bytes to read
    ; syscall

    ; Simulate user input
    lea rdi, [rsp]
    mov rsi, [rel simulated_input]
    mov rdx, 20             ; max length
    call print_string
    syscall

    ; Read from standard input
    ;mov rax, 0              ; sys_read
    ;mov rdi, 0              ; stdin
    ;lea rsi, [rsp]        ; buffer
    ;mov rdx, 100             ; max bytes to read
    ;syscall

    ; Print what was read (simulated)
    lea rsi, [rlf_input_read_msg]
    call print_string
    mov rax, 1
    syscall

    jmp end_io_operations

end_io_operations:
    mov rax, 60             ; Exit
    xor rdi, rdi
    syscall

section .bss
    input_buffer: resb 256

rlf_input_read_msg: db "Input read (simulated): ", 0
simulated_input: db "John", 0
format_input: db "Name: %s", 0
rlf_separator: db "; ", 10

rlf_input_read_msg_len equ $ - rlf_input_read_msg

; --- String Manipulation ---
section .text
global _start_string_ops

_start_string_ops:
    ; Allocate working buffers
    sub rsp, 512              ; Allocate buffers
    lea rdi, [rsp]        ; Source buffer
    lea rsi, [rsp + 256]    ; Destination buffer

    ; Test different string operations
    lea rsi, [rel str1_msg]
    lea rsi, [rl str2_msg]
    lea rsi, [rl str_concat_msg]
    call print_string

    ; String concatenation
    strcat rsi, rdi
    strcat rsi, rsi + 256

    lea rsi, [rl concatenated_msg]
    call print_string

    ; String comparison
    lea rdi, [rl str1_msg]
    lea rsi, [rl str2_msg]
    call string_compare

    lea rsi, [rl_string_equal_msg]
    call print_string

    ; String length
    lea rsi, [rl str1_msg]
    mov rcx, rsi
    call get_string_length
    lea rsi, [rl str_len_msg]
    call print_string

    ; Exit
    add rsp, 512              ; Restore stack
    mov rax, 60
    xor rdi, rdi
    syscall

string_compare:
    strcmp rdi, rsi           ; Result: 0=equal, <0=less, >0=greater
    je strings_equal
    jl strings_less
    strings_greater:
        lea rsi, [rl_strings_greater_msg]
        call print_string
        jmp string_done

strings_less:
        lea rsi, [rl_strings_less_msg]
        call print_string
        jmp string_done

strings_equal:
        lea rsi, [rl_strings_equal_msg]
        call print_string

string_done:
    ret

get_string_length:
    xor rax, rax              ; Return string length
    ret

rlf_str1_msg: db "String 1: ", 0
rlf_str2_msg: db "String 2: ", 0
rlf_string_concat_msg: db "Concatenated: ", 0

rlf_string_equal_msg: db "Strings are equal", 0
rlf_strings_greater_msg: db "String 1 comes after String 2", 0
rlf_string_len_msg: db "String length: ", 0

rlf_separator: db "; ", 10
format_input: db "%s", 0
rlf_separator2: db "; ", 10

print_string:
    push rax
    push rdi
    push rsi
    mov rax, 1
    mov rdi, 1
    syscall
    pop rsi
    pop rdi
    pop rax
    ret

; --- Data Conversion ---
section .text
global _start_data_conversion

_start_data_conversion:
    ; Number to ASCII conversion examples
    numbers_to_convert = [10, -5, 0, 5, 100, 1000]

    ; Convert each number to string
    mov r10, 0              ; Index counter
    convert_numbers_loop:
    cmp r10, length(numbers_to_convert)
    jge convert_done

    mov eax, numbers_to_convert(r10)  ; Get current number
    mov ebx, eax              ; EBX = number as integer
    push rax                  ; Save register

    ; Handle negative numbers
    test ebx, ebx
    jge positive_number
    mov r14, '-'           ; Add minus sign for negative
    neg ebx             ; Negate
    jmp convert_to_ascii

positive_number:
    mov r14, '+'           ; Add plus sign for positive

convert_to_ascii:
    mov r15, 10              ; Max digits
    digit_count = 0
    digit_loop:
        xor rcx, rcx          ; Clear RCX
        mov r8, r15              ; RBX = remaining digits
        idiv rcx, 10          ; Extract last digit
        jz digit_done

        ; Convert digit to ASCII
        add r8, '0'         ; Add ASCII '0' to digit
        mov r13, r8              ; R13 = ASCII digit
        add r14, r13              ; R14 = ASCII digit
        inc digit_count
        cmp digit_count, 2     ; Have at least 2 digits
        jl single_digit

    single_digit:
        inc digit_count         ; Count = 1
        jmp digit_done

    digit_done:
    ; Terminate string
    mov byte [rsi], r14
    inc rsi                  ; Move buffer position
    jmp end_convert_numbers

positive_number:
    mov r15, 10              ; Max digits
    digit_count = 0
    digit_loop2:
        xor rcx, r15          ; Clear RCX
        idiv rcx, 10          ; Extract last digit
        jg digit_done2

    digit_done2:
    ; Terminate string
    mov byte [rsi], r14
    inc rsi                  ; Move buffer position
    jmp end_convert_numbers

    display_converted:
    lea rsi, [rlf_converted_msg]
    call print_string

    increment_index:
    inc r10
    jmp convert_numbers_loop

convert_done:
    pop rbx
    pop rax
    pop rax
    ret

display_converted:
    push rax
    push rdi
    push rsi
    add rsp, 32              ; Allocate space for 4 values

    ; Display converted numbers
    mov r10, 0              ; Index counter
    display_loop:
    cmp r10, length(numbers_to_convert)
    jge display_done

    lea rdi, [rlf_converted_msg]
    mov eax, numbers_to_convert(r10)
    call print_number
    inc r10
    jmp display_loop

display_done:
    add rsp, 32              ; Restore stack
    pop rsi
    pop rdi
    pop rax
    ret

end_convert_numbers:
    pop rbx
    pop rax
    ret

end_program:
    jmp _start_main

; --- File I/O with Buffering ---
section .text
global _start_file_io

_start_file_io:
    ; Setup
    sub rsp, 4096         ; Allocate large buffer
    lea rdi, [rsp]        ; Read buffer
    lea rsi, [rsi + 2048]  ; Write buffer

    ; Read from stdin with buffering
    mov rax, 0              ; sys_read
    mov rdi, 0              ; stdin
    lea rsi, [rsi]        ; Read buffer
    mov rdx, 4096            ; Large buffer
    syscall

    test rax, rax              ; Check for end of file
    jl end_file_io

    read_buffer_loop:
    ; Process read data
    lea rdi, [rlf_buffer_file_read_msg]
    call print_string
    add rsi, rdx          ; Move buffer position
    cmp rsi, [rsi + 4096]  ; Check end of buffer
    jl read_buffer_loop

    end_file_io:
    ; Calculate how much data was read
    lea rdi, [rsi]        ; Start address
    sub rdx, [rsi]        ; End address
    mov r15, rdx          ; Bytes read

    lea rsi, [rlf_bytes_read_msg]
    call print_string

    % Close stdin (if opened via sys_open)
    mov rax, 3              ; sys_close
    mov rdi, 0              ; stdin
    syscall

    jmp end_file_io

    % Write to stdout with buffering
write_buffered_output:
    ; Write buffer contents to stdout
    mov rax, 1              ; sys_write
    mov rdi, 1              ; stdout
    lea rsi, [rsi + 2048] ; Write buffer
    mov rdx, rdx          ; Number of bytes written
    syscall

    test rax, rax              ; Check for write error
    jl write_error

    lea rsi, [rlf_buffer_written_msg]
    call print_string
    jmp end_file_io

write_error:
    lea rsi, [rlf_write_error_msg]
    call print_string

end_file_io:
    add rsp, 4096         ; Restore stack
    pop rbp
    jmp end_program

rlf_buffer_file_read_msg: db "Read %d bytes from stdin", 0
rlf_bytes_read_msg: db "Bytes read: %d", 0
rlf_buffer_written_msg: db "Written %d bytes to stdout", 0
rlf_write_error_msg: db "Error writing to stdout", 0
rlf_separator: db "; ", 10
rlf_bytes_read_msg_len equ $ - rlf_bytes_read_msg
rlf_buffer_written_msg_len equ $ - rlf_buffer_written_msg

rlf_bytes_read_msg_len equ $ - rlf_bytes_read_msg
rlf_buffer_written_msg_len equ $ - rlf_buffer_written_msg
rlf_separator2: db "; ", 10

--- End of Examples ---

% Close all examples
end_section