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: rax(in: bytes read), rbx, rcx, r11 ; uses mem: input_buffer, output_buffer b32e: ; save the number of bits read in cl mov bl, 8 ; each byte contains 8 bits mul bl ; multiply al by 8 mov cl, al ; set up output counter xor r11, r11 ; set up processed bit counter xor ch, ch ; initialize output buffer with padding mov rbx, 0x3d3d3d3d3d3d3d3d mov qword [output_buffer], rbx .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 output counter inc r11 ; increase bit counter add ch, 5 cmp ch, cl jl .loop .exit: ret _start: nop .loop: ; try to read 5 bytes call read_input ; read nothing cmp rax, 0 je .exit ; swap endianness of input mov rbx, qword [input_buffer] bswap rbx ; correct position in qword shr rbx, 24 mov qword [input_buffer], rbx ; convert to base 32 call b32e ; print call write_output jmp .loop .exit: ; linux x64 exit(0) mov rax, 60 mov rdi, 0 syscall