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