section .data rfc4648 db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' 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 ; b32e ; encodes 40 bits (5 bytes) to 8 RFC4648 base32 characters ; uses reg: rbx, r11 ; uses mem: input_buffer, output_buffer b32e: ; set up output counter xor r11, r11 .loop: ; clear rbx xor rbx, rbx ; get a byte from the input mov bl, byte [input_buffer + 4] ; mask and shift to get 5 bits which is a number in 0 ~ 31 and bl, 0xf8 shr bl, 3 ; shift left the input buffer shl qword [input_buffer], 5 ; convert to base32 add rbx, rfc4648 mov bl, byte [rbx] mov byte [output_buffer + r11], bl ; increase counter inc r11 ; check counter ; when the counter reaches 8 it means that 8 characters (40 bits) ; have been processed and written cmp r11, 8 js .loop ret _start: nop .loop: ; try to read 5 bytes call read_input ; read nothing cmp rax, 0 je .exit ; swap endianness of input mov rax, qword [input_buffer] bswap rax ; correct position in qword shr rax, 24 mov qword [input_buffer], rax ; convert to base 32 call b32e ; print call write_output jmp .loop .exit: ; linux x64 exit(0) mov rax, 60 mov rdi, 0 syscall