interrupts 1 stack 32 data auto code auto str index "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" byte padding '=' str raw 3 str base64 4 :loop ; read 3 bytes from stdin to $raw mov bx $raw mov cx 3 mov dx 0 :read_loop xor ax ax sys sub cx ax add bx ax jcz read_done cmp ax dx je read_done inc ax cmp ax dx je end dec ax jmp read_loop :read_done ; encode to base64 mov cx bx mov bx $raw sub cx bx mov dx $base64 jcz end ; base64[0] = index[raw[0] >> 2]; mov al *bx mov ah 2 shr al ah call get_index mov *dx al jcz output_padding dec cx ; base64[1] = index[((raw[0] & 3) << 4) | raw[1] >> 4)]; mov al *bx mov ah 3 and al ah mov ah 4 shl al ah jcz no_2nd_char inc bx push dx mov dl *bx shr dl ah or al dl pop dx :no_2nd_char inc dx call get_index mov *dx al jcz output_padding dec cx ;base64[2] = index[((raw[1] & 0xF) << 2) | (raw[2] >> 6)]; mov al *bx mov ah 0xF and al ah mov ah 2 shl al ah jcz no_3rd_char inc bx push dx mov ah *bx mov dl ah mov ah 6 shr dl ah or al dl pop dx :no_3rd_char inc dx call get_index mov *dx al jcz output_padding ;base64[3] = index[raw[2] & 0x3F]; mov al *bx mov ah 0x3F and al ah inc dx call get_index mov *dx al ; write to stdout mov bx $base64 mov cx 4 call write_stdout jmp loop :get_index push bx mov bx $index add bx al mov al *bx pop bx ret :output_padding push dx mov bx $base64 sub dx bx mov cx dx inc cx mov ax 1 mov dx 1 sys pop dx mov cx $base64 sub cx dx mov dx 3 add cx dx :padding_loop push cx mov ax 1 mov bx &padding mov cx 1 mov dx 1 sys pop cx dec cx jcz end jmp padding_loop :end mov ax 12 mov bx 0 sys ; bx = buffer, cx = byte count :write_stdout push ax push dx mov dx 1 :write_stdout_loop mov ax 1 sys sub cx ax jcz write_stdout_end add bx ax jmp write_stdout_loop :write_stdout_end pop dx pop ax ret