RosettaCodeData/Task/Password-generator/X86-64-Assembly/password-generator.x86-64
2024-10-16 18:07:41 -07:00

295 lines
5.9 KiB
Text

format ELF64 executable 3
entry main
minlen equ 8
cmdno equ 3
cmdnos equ cmdno * 8
segment executable readable
main:
mov rax, qword [rsp]
mov rdi, cmdno
cmp rax, rdi
cmovg rax, rdi
cmp rax, 1
jle .printhelp
cmp rax, 2
jg .cmdloop
mov rdi, default
mov qword [cmdslot + 16], rdi
.cmdloop:
mov rdi, qword [rsp + rax * 8]
dec rax
mov qword [cmdslot + rax * 8], rdi
or rax, rax
jnz .cmdloop
.convert0:
mov rdi, qword [cmdslot + 8]
call atoq
cmp rax, minlen
jl .printhelp
mov qword [cmdslot + 8], rax
mov rdi, qword [cmdslot + 16]
call atoq
sub rax, 0
jle .printhelp
mov qword [cmdslot + 16], rax
.allocate:
mov rax, qword [cmdslot + 8]
xor rdx, rdx
mov rdi, 8
div rdi
add rax, 1
xor rdx, rdx
mul rdi
mov qword [cmdslot], rax
sub rsp, rax
mov rax, qword [cmdslot + 16]
mov rdi, rsp
.loop00:
mov rsi, qword [cmdslot + 8]
call mkpass
call check
or r9, r9
jz .loop00
call prints
dec rax
jnz .loop00
.exit:
add rsp, qword [cmdslot]
mov rax, 60
xor rdi, rdi
syscall
.printhelp:
mov rdi, helpmsg
call prints
jmp .exit
prints:
push rdx
push rsi
push rdi
push rax
xor rdx, rdx
cmp byte [rdi + rdx], 0
je .return
.stloop:
cmp byte [rdi + rdx], 0
je .printit
inc rdx
jmp .stloop
.printit:
mov rax, 1
mov rsi, rdi
mov rdi, 1
syscall
mov al, 0x0a
push rax
mov rax, 1
mov rsi, rsp
mov rdx, 1
syscall
pop rax
.return:
pop rax
pop rdi
pop rsi
pop rdx
ret
atoq:
push r8
push r9
push rdi
push rsi
push rdx
push rcx
xor rax, rax
xor r8, r8
mov r9, 1
cmp byte[rdi], 0
jz .exit
cmp byte[rdi], '-'
jne .stloop
mov r9, -1
inc rdi
.stloop:
cmp byte[rdi + r8], '0'
jl .calc0
cmp byte[rdi + r8], '9'
jg .calc0
mov sil, byte[rdi + r8]
sub rsi, '0'
push rsi
inc r8
jmp .stloop
.calc0:
xor rcx, rcx
mov rdi, 10
mov rsi, 1
.calc1:
pop rax
mul rsi
add rcx, rax
dec r8
jz .return
mov rax, rsi
mul rdi
mov rsi, rax
jmp .calc1
.return:
mov rax, rcx
imul r9
.exit:
pop rcx
pop rdx
pop rsi
pop rdi
pop r9
pop r8
ret
getchar:
push rdi
push rdx
rdrand rax
mov rdi, endchars - chars
xor rdx, rdx
div rdi
xor rax, rax
mov al, byte [chars + rdx]
pop rdx
pop rdi
ret
mkpass:
push rsi
push rax
mov byte [rdi + rsi], 0
.loop0:
dec rsi
call getchar
mov byte [rdi + rsi], al
or rsi, rsi
jnz .loop0
.return0:
pop rax
pop rsi
ret
check:
push rax
push rdx
push rcx
xor r9, r9
.upper:
xor rcx, rcx
.upper0:
xor rdx, rdx
mov rsi, endalphau - alphau
mov al, byte[rdi + rcx]
.upper1:
cmp al, byte[alphau + rdx]
je .lower
inc rdx
cmp rdx, rsi
jl .upper1
inc rcx
cmp byte[rdi + rcx], 0
jnz .upper0
jmp .return0
.lower:
xor rcx, rcx
.lower0:
xor rdx, rdx
mov rsi, endalphal - alphal
mov al, byte[rdi + rcx]
.lower1:
cmp al, byte[alphal + rdx]
je .numeric
inc rdx
cmp rdx, rsi
jl .lower1
inc rcx
cmp byte[rdi + rcx], 0
jnz .lower0
jmp .return0
.numeric:
xor rcx, rcx
.numeric0:
xor rdx, rdx
mov rsi, endnumeri - numeri
mov al, byte[rdi + rcx]
.numeric1:
cmp al, byte[numeri + rdx]
je .special
inc rdx
cmp rdx, rsi
jl .numeric1
inc rcx
cmp byte[rdi + rcx], 0
jnz .numeric0
jmp .return0
.special:
xor rcx, rcx
.special0:
xor rdx, rdx
mov rsi, endspecia - specia
mov al, byte[rdi + rcx]
.special1:
cmp al, byte[specia + rdx]
je .return1
inc rdx
cmp rdx, rsi
jl .special1
inc rcx
cmp byte[rdi + rcx], 0
jnz .special0
jmp .return0
.return1:
mov r9, 1
.return0:
pop rcx
pop rdx
pop rax
ret
segment readable
helpmsg:
db "Usage:", 0x0a
db "passgen nchars [ncount]", 0x0a, 0x0a
db "nchars = number of characters for each password", 0x0a
db "ncount = number of passwords to generate", 0x0a
db "If ncount is omitted, a default of 1 will be used.", 0x0a, 0x0a
db "A password generation program which will generate passwords", 0x0a
db "containing random ASCII characters from the following groups:", 0x0a, 0x0a
db "lower-case letters: a ──► z", 0x0a
db "upper-case letters: A ──► Z", 0x0a
db " digits: 0 ──► 9", 0x0a
db "other printable characters:", 0x0a
db 0x09, 0x21, 0x22, "#$%&", 0x27, "()*+,-./:;<=>?@[]^_{|}~", 0x0a
db 0x09, "(the above character list excludes white-space,"
db 0x09, " backslash and grave)", 0x0a, 0x0a
db "The generated password(s) must include at least one", 0x0a
db "(of each of the four groups):", 0x0a
db " lower-case letter,", 0x0a
db " upper-case letter,", 0x0a
db " digit (numeral), and", 0x0a
db " one 'other' character.", 0x0a, 0x0a
db "Created for Rosetta Code.", 0x0a
db "https:", 0x2f, 0x2f, "rosettacode.org/wiki/Password_generator", 0
chars:
alphau: db "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
endalphau:
db "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
alphal: db "abcdefghijklmnopqrstuvwxyz"
endalphal:
db "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
numeri: db "0123456789"
endnumeri:
db "01234567890123456789012345678901234567890123456789"
specia: db 0x21, 0x22, "#$%&", 0x27, "()*+,-./:;<=>?@[]^_{|}~"
endspecia:
endchars:
default: db '1', 0
segment readable writable
cmdslot: rq cmdnos