Code Snippets
Low-Level
#NASM
#Primzahlen
#x86
Prime-Checker in x86 ASM
An interactive x86 assembly example that checks whether entered numbers are prime.
Prime Checker x86 ASM
This program checks whether an entered number is a prime number:
global _start
default rel
section .text
_start:
; Program entry point
call welcome ; Print welcome message
primeloop:
push rbp ; Save base pointer
mov rbp, rsp ; Set new base pointer
sub rsp, 16 ; Reserve 16 bytes for local variables
call read ; Wait for user input
; Check if input is 'q' (quit)
cmp byte [usrinput], "q" ; Compare first character to 'q'
je exit_0 ; If 'q', exit program
call parse_input ; Parse decimal input into RAX
; Prime check logic:
; If n < 2 -> not prime
; If n == 2 -> prime
; If n is even -> not prime
; Check if n < 2, n == 2, or n is even
cmp rax, 2
jl printnoprime ; n < 2 (not prime)
je printprime ; n == 2 (prime)
test rax, 1 ; Check whether n is odd
jz printnoprime ; n is even (not prime)
; Odd number prime check
; Algorithm:
; i = 3
; while i * i <= n (only odd i):
; if n % i == 0 then not prime
; else i += 2
; if loop ends, n is prime
mov [rbp - 8], rax ; Persist n for repeated use
mov rcx, 3 ; Start with smallest odd divisor
.1:
mov [rbp - 16], rcx ; Cache current divisor
mov rax, [rbp-8] ; Reload n for quotient comparison
xor rdx, rdx ; Zero high word before division
div rcx ; Divide n by i (quotient in RAX)
cmp rcx, rax ; Compare i to n / i threshold
jg printprime ; If i > n / i, no divisors remain
xor rdx, rdx ; Zero high word before division
mov rax, [rbp - 8] ; Reload n for modulus check
mov rcx, [rbp - 16] ; Restore i
div rcx ; Compute quotient and remainder
cmp rdx, 0 ; Test remainder
je printnoprime ; If n % i == 0, not prime
mov rcx, [rbp - 16] ; Reload i for next iteration
add rcx, 2 ; Move to next odd divisor
jmp .1 ; Repeat loop
welcome:
; Prints the welcome message
mov rsi, welcomemsg ; Load welcome message address
mov rdx, welcomemsg_len ; Load welcome message length
call print ; Print welcome message
ret
read:
; Reads user input
mov rsi, prompt ; Load prompt message address
mov rdx, prompt_len ; Load prompt message length
call print ; Print prompt
mov rax, 0 ; Syscall number: read
xor rdi, rdi ; File descriptor 0 (stdin)
mov rsi, usrinput ; Buffer for input
mov rdx, usrinput_len ; Input buffer size
syscall ; Perform read syscall
dec rax ; Exclude newline from byte count
mov [net_char_len], rax ; Persist input length (no newline)
mov byte [usrinput + rax], 0 ; Null-terminate input string
ret
; Convert decimal string in usrinput -> integer in RAX
; net_char_len = number of chars without newline
; Destroys RCX, RDX, RSI
parse_input:
xor rax, rax ; Result accumulator
mov rcx, [net_char_len] ; Loop count
mov rsi, usrinput ; Pointer to string
.convert_loop:
test rcx, rcx ; Stop when no characters remain
jz .done ; If zero, done
movzx rdx, byte [rsi] ; Load next ASCII digit
sub rdx, '0' ; Convert ASCII to digit (0..9)
imul rax, rax, 10 ; Shift accumulated value by base 10
add rax, rdx ; Add digit to result
inc rsi ; Move to next char
dec rcx ; Decrement loop count
jmp .convert_loop ; Repeat loop
.done:
ret
printnum:
mov rsi, usrinput ; Point RSI at input string
mov rdx, [net_char_len] ; Load input string length
call print ; Print input string
ret
printnoprime:
; Print: not a prime
call printnum ; Print input number
mov rsi, noprime ; Load 'not prime' message address
mov rdx, noprime_len ; Load message length
call print ; Print message
mov rsp, rbp ; Restore stack pointer
pop rbp ; Restore base pointer
jmp primeloop ; Repeat loop
printprime:
; Print: is a prime
call printnum ; Print input number
mov rsi, isprime ; Load 'is prime' message address
mov rdx, isprime_len ; Load message length
call print ; Print message
mov rsp, rbp ; Restore stack pointer
pop rbp ; Restore base pointer
jmp primeloop ; Repeat loop
print:
mov rax, 1 ; Syscall number: write
mov rdi, 1 ; File descriptor 1 (stdout)
syscall ; Perform write syscall
ret
exit_0:
xor rdi, rdi ; Exit status 0
exit:
mov rax, 60 ; Syscall number: exit
syscall ; Invoke exit
section .bss
usrinput resq 1 ; Reserve memory for user input
usrinput_len equ $ - usrinput ; Length of input buffer
net_char_len resq 1 ; Actual length of user input
section .data
welcomemsg db "This program checks whether a number is a prime number.", 10, "To quit enter ", 0x22, "q", 0x22, ".", 10, 0
welcomemsg_len equ $ - welcomemsg
prompt db 10, "Please enter a number: ", 0
prompt_len equ $ - prompt
noprime db " is not a prime number", 10, 0
noprime_len equ $ - noprime
isprime db " is a prime number", 10, 0
isprime_len equ $ - isprime