In A86 assember - assembles to a .COM executable:
dd 0ba02c6bfh, 0b8bd10c1h, 0e808b512h, 0ea870100h, 08700e9e8h, 010273eah
dd 0e0e8c2h, 06b51872h, 0c000ebe8h, 0b3c02e8h, 03368067dh, 0b2e901h
dd 0baaa5004h, 0fd8110c1h, 0cd7c1630h, 0bf3031bbh, 0a0571000h, 0ec880080h
dd 0c581c589h, 023c0081h, 0e7f087ch, 0823e38h, 027b00875h, 0e901d068h
dd 0b6400080h, 04f6f603h, 080d08a1ch, 0b60f80c4h, 07f06c7f4h, 088303000h
dd 0ac00813eh, 087ef828h, 0b00056e8h, 051e81dh, 0d83850adh, 0e7f157ch
dd 0a74fc38h, 0262ce088h, 0e901a368h, 01d2c003bh, 0580036e8h, 0b7efc38h
dd 0774d838h, 0f828e088h, 0800026e8h, 0127e1dfah, 0afd448ah, 0440afe44h
dd 074f838ffh, 0e8c28a05h, 0cafe000fh, 0ab7cee39h, 05a2405c6h, 021cd09b4h
dd 05e856c3h, 020b05e00h, 0c5bec3aah, 074c00a02h, 03c80460ah, 0fefa755bh
dd 046f675c8h, 0745b3cach, 0f8ebaae8h, 0eec1d689h, 08a3c8a03h, 07e180cah
dd 0cfd2c1feh, 0ebe8c342h, 0fed8d0ffh, 0c3f775cdh, 01e581e8fh, 0303c5ea8h
dd 0df6f652ah, 078bde03ch, 05e027500h, 01ec1603ch, 07d40793dh, 0603c8080h
dd 09f6f2838h, 040f17a3dh, 080f17a22h, 0403d7264h, 0793cdee1h, 0140740f1h
dd 01e2f7d32h, 02f488948h, 0a7c43b05h, 0a257af9bh, 0be297b6ch, 04609e30ah
dd 0b8f902abh, 07c21e13eh, 09a077d9eh, 054f82ab5h, 0fabe2af3h, 08a6534cdh
dd 0d32b4c97h, 035c7c8ceh, 082bcc833h, 0f87f154fh, 0650ff7eah, 02f143fdfh
dd 0a1fd687fh, 0c3e687fdh, 0c6d50fe0h, 075f13574h, 0898c335bh, 0e748ce85h
dd 08769676fh, 0ad2cedd3h, 0928c77c7h, 077e2d18eh, 01a77e8f6h
db 0bah, 01bh
That's a 454 byte executable.
Here's the (slightly smaller) code. Since A86 is an 8086 only assembler, I've had to hand code the 32bit extensions:
mov di,strings
mov dx,tree_data * 8 + 1
mov bp,code_data * 8
l1:
mov ch,8
call extract_bits
xchg dx,bp
call extract_bit
xchg dx,bp
jnc l2
add dx,ax
l2:
call extract_bit
jc l3
mov ch,6
call extract_bits
shr al,2
cmp al,11
push l27
jl get_string
l25:
add al,48+32
stosb
l27:
mov dx,tree_data * 8 + 1
l3:
cmp bp,end_data * 8
jl l1
convert:
mov bx,'01'
mov di,01000h
push di
mov al,[80h]
mov ah,ch
mov bp,ax
add bp,81h
cmp al,2
jl zero
jg l90
cmp byte ptr [82h],bh
jne l90
zero:
mov al,39
push done
get_string:
mov si,strings-1
or al,al
je l36
l35:
inc si
cmp byte ptr [si],';'+32
jne l35
dec al
jnz l35
l36:
inc si
l37:
lodsb
cmp al,';'+32
je ret
stosb
jmp l37
l90:
inc ax
mov dh,3
div dh
add al,28
mov dl,al
add ah,80h
db 0fh, 0b6h, 0f4h ; movzx si,ah
mov word ptr [80h],'00'
l95:
lodsb
sub al,bh
jle l100
call get_string2
mov al,29
call get_string2
l100:
lodsw
push ax
cmp al,bl
jl l150
jg l140
cmp ah,bh
je l140
mov al,ah
sub al,'0'-10
push l150
get_string2:
push si
call get_string
pop si
mov al,' '
stosb
ret
l140:
sub al,'0'-19
call get_string2
l150:
pop ax
cmp ah,bh
jle l200
cmp al,bl
je l200
mov al,ah
sub al,bh
call get_string2
l200:
cmp dl,29
jle l300
mov al,[si-3]
or al,[si-2]
or al,[si-1]
cmp al,bh
je l300
mov al,dl
call get_string2
l300:
dec dl
cmp si,bp
jl l95
done:
mov byte ptr [di],'$'
pop dx
mov ah,9
int 21h
int 20h
l41:
rcr al,1
dec ch
jz ret
extract_bits:
push l41
extract_bit:
mov si,dx
shr si,3
mov bh,[si]
mov cl,dl
and cl,7
inc cl
ror bh,cl
inc dx
ret
tree_data:
dw 01e8fh, 01e58h, 05ea8h, 0303ch, 0652ah, 0df6fh, 0e03ch, 078bdh
dw 07500h, 05e02h, 0603ch, 01ec1h, 0793dh, 07d40h, 08080h, 0603ch
dw 02838h, 09f6fh, 07a3dh, 040f1h, 07a22h, 080f1h, 07264h, 0403dh
dw 0dee1h, 0793ch, 040f1h, 01407h, 07d32h, 01e2fh, 08948h
db 048h
code_data:
dw 052fh, 0c43bh, 09ba7h, 057afh, 06ca2h, 0297bh, 0abeh, 09e3h
dw 0ab46h, 0f902h, 03eb8h, 021e1h, 09e7ch, 077dh, 0b59ah, 0f82ah
dw 0f354h, 0be2ah, 0cdfah, 06534h, 0978ah, 02b4ch, 0ced3h, 0c7c8h
dw 03335h, 0bcc8h, 04f82h, 07f15h, 0eaf8h, 0ff7h, 0df65h, 0143fh
dw 07f2fh, 0fd68h, 0fda1h, 0e687h, 0e0c3h, 0d50fh, 074c6h, 0f135h
dw 05b75h, 08c33h, 08589h, 048ceh, 06fe7h, 06967h, 0d387h, 02cedh
dw 0c7adh, 08c77h, 08e92h, 0e2d1h, 0f677h, 077e8h, 0ba1ah
db 01bh
end_data:
strings:
The text is stored using Huffman encoding. The command line is passed as a string so converting it is simple - split the string into groups of three and parse each group (hundreds, tens and units) following each with the current multiplier (millions, thousands, etc).