ASMTools/rot13/main.asm
2024-08-23 10:59:26 -07:00

100 lines
1.9 KiB
NASM

global _start
; bss is the section for data like buffers that is zeroed out
section .bss
; Reserve 1KiB for the buffer size. Do not reserve more than `(2^65)-1` bytes,
; as that is the maximum size allowed (the counter register and/or the bytes
; read will overflow and cause bugs)
buf: resb 8192
; This should be equal to the buffer size, if it is smaller it's a waste, if
; it's bigger it can segfault.
BUF_S: equ 8192
section .text
_start:
; Read into buffer
xor rax, rax
mov rsi, buf
mov rdx,BUF_S
syscall
; Clear rcx (rcx to be the counter)
xor rcx,rcx
rot_loop:
; If counter is equal to max bytes,
cmp rcx, rax
; Done, jump to finish.
je done
; Set lowest byte of rdx to buf[rcx].
mov dl, byte [buf+rcx]
; If dl is greater than or equal to 'a',
cmp dl, 97
; Go to lowercase.
jge lower
; If dl is greater than or equal to 'A',
cmp dl, 65
; Go to uppercase.
jge upper
; Else, it's not a letter, inc rcx and go back to start of loop.
inc rcx
jmp rot_loop
lower:
; If dl is greater than 'z',
cmp dl, 122
; It's not a letter, so go to special char.
jg special
; If dl is less than or equal to 'm',
cmp dl, 109
; Add 13 letters.
jle up13
; Else, subtract 13.
jmp down13
; This loop does the exact thing as `lower` but uses uppercase letters instead.
upper:
cmp dl, 90
jg special
cmp dl, 77
jle up13
jmp down13
; This handles special chars, it just increments rcx and goes to the start of
; the loop.
special:
inc rcx
jmp rot_loop
; Adds 13 to dl, increments rcx, and goes to loop start.
up13:
add dl, 13
mov byte [buf+rcx], dl
inc rcx
jmp rot_loop
; Same as up13 but subtracts instead.
down13:
sub dl, 13
mov byte [buf+rcx], dl
inc rcx
jmp rot_loop
; If done, print buffer (it has been rot13ed) and exit(0)
done:
mov rdx, rax
mov rax, 1
mov rdi, 1
mov rsi, buf
syscall
cmp byte [buf+rax-1], 0xA
jne _start
mov rax, 60
xor rdi,rdi
syscall
; vim: set ft=nasm:
; vim: set ai: