section .bss input_buffer resb 8 output_buffer resb 8 section .text global _start ; read_input ; reads 5 bytes (40 bits) of input ; uses reg: rax, rdi, rsi, rdx ; uses mem: input_buffer read_input: ; linux x64 read(stdin, input_buffer, 5) mov rax, 0 mov rdi, 0 mov rsi, input_buffer mov rdx, 5 syscall ret ; write_output ; writes the output buffer to stdout ; uses reg: rax, rdi, rsi, rdx ; uses mem: output_buffer(ro) write_output: ; linux x64 write(stdout, output_buffer, 8) mov rax, 1 mov rdi, 1 mov rsi, output_buffer mov rdx, 8 syscall ret ; b32d ; decodes 8 RFC4648 characters (without checking its validity!) ; uses reg: rax, rbx ; uses mem: input_buffer, output_buffer b32d: ; reset rax (output) xor rax, rax ; set downwards counter mov bl, 8 .loop: ; get a character mov bh, byte [output_buffer] ; if is padding, exit cmp bh, 0x3d je .exit ; shift rax of one byte shl rax, 5 ; insert the new 5 bits or al, bh ; decrement counter dec bl jnz .loop .exit: ; save output mov [input_buffer], rax ret _start: nop .loop: ; read input call read_input ; read nothing cmp rax, 0 je .exit ; decode base32 call b32d ; print call write_output jmp .loop .exit: ; linux x64 exit(0) mov rax, 60 mov rdi, 0 syscall