format ELF64 executable
macro genclass class, class_len
{
;; Generate 16 bits (smallest) of randomness from the cpu
rdrand ax
;; Modulo into len range to index in
xor rdx, rdx
mov rbx, class_len
div bx
;; Save output letter into out_buf, bump rcx
add rdx, class
mov rdx, [rdx]
mov [rcx], rdx
inc rcx
inc rsi
}
segment readable executable
entry main
main:
;; No arg preload case
cmp [rsp], word 1
jne argparse
mov r8, qword 3
mov r9, qword 2
mov r10, qword 3
jmp generate
argparse:
;; Check args (need 3)
cmp [rsp], word 3
jle fail
;; load arg1
mov r8, [rsp+16]
mov r8, [r8]
and r8, 0xFF
sub r8, 48
;; load arg2
mov r9, [rsp+24]
mov r9, [r9]
and r9, 0xFF
sub r9, 48
;; load arg3
mov r10, [rsp+32]
mov r10, [r10]
and r10, 0xFF
sub r10, 48
generate:
;; Store which output byte we're up to in rcx
mov rcx, out_buf
;; Store chars generated in rsi
xor rsi, rsi
tripleter:
genclass consonants, consonants_len
genclass vowels, vowels_len
genclass consonants, consonants_len
dec r8
test r8, r8
jnz tripleter
symboler:
genclass symbols, symbols_len
dec r9
test r9, r9
jnz symboler
numberer:
genclass numbers, numbers_len
dec r10
test r10, r10
jnz numberer
;; Append new line to string
mov [rcx], word 10
inc rsi
;; Special case to caps the first character
xor rax, rax
mov al, byte [out_buf]
sub al, 32
mov rbx, out_buf
mov [rbx], al
;; Write
mov rdi, 1 ;; stdout
mov rdx, rsi
mov rsi, out_buf
mov rax, 0x01
syscall
;; Exit (code 0)
mov rdi, 0
mov rax, 0x3c
syscall
fail:
;; Write
mov rdi, 1 ;; stdout
mov rsi, usage
mov rdx, usage_len
mov rax, 0x01
syscall
;; Exit 1
mov rdi, 1
mov rax, 0x3c
syscall
segment readable writeable
usage db "usage: passmgen [<triplet#> <symbol#> <number#>]", 10
usage_len = $ - usage
numbers db "0123456789"
numbers_len = $ - numbers
vowels db "aeiou"
vowels_len = $ - vowels
consonants db "bcdfghjklmnpqrstvwxyz"
consonants_len = $ - consonants
symbols db "!@#$%&()-=_+[]{}\\|;<>/?."
symbols_len = $ - symbols
out_buf rb 64