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 [ ]", 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