diff --git a/rot13/.gitignore b/rot13/.gitignore new file mode 100644 index 0000000..2dba1ed --- /dev/null +++ b/rot13/.gitignore @@ -0,0 +1,2 @@ +rot13* +.gdb_history diff --git a/rot13/README.md b/rot13/README.md new file mode 100644 index 0000000..3ee3c04 --- /dev/null +++ b/rot13/README.md @@ -0,0 +1,6 @@ +Rot13 +===== +## A rot13 program in amd64 linux asm. + +Be warned: it does not appear to be possible to enter more than 4096 bytes, +because if you do, it gets truncated. diff --git a/rot13/main.asm b/rot13/main.asm new file mode 100644 index 0000000..6abe85c --- /dev/null +++ b/rot13/main.asm @@ -0,0 +1,99 @@ +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: diff --git a/rot13/main.o b/rot13/main.o new file mode 100644 index 0000000..16d979b Binary files /dev/null and b/rot13/main.o differ diff --git a/rot13/make.sh b/rot13/make.sh new file mode 100755 index 0000000..30b3b58 --- /dev/null +++ b/rot13/make.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +if [ "$1" == "rot13.dbg" ]; then + nasm -felf64 -g main.asm + ld main.o -o rot13.dbg + exit +fi +nasm -felf64 main.asm +ld main.o -s -o rot13