to_number:
mov eax, [num] ; is this necessary? Moves num back into eax
sub eax, '0' ; converts to numerical
ret
The first comment here suggests you are only interested in getting num back into EAX. Then a slightly more elegant solution would be to not call to_number but push/pop EAX on the higher level. Like so :
log:
push eax
call to_ascii ; converts eax to ascii
mov [num], eax ; num = eax
mov edx, 1
mov ecx, num
mov ebx, 1
mov eax, 4
int 80h ; output the current number
pop eax
ret
This might get you into trouble when you will want more items in the BSS section.
mov [num], eax ; num = eax
You are writing the dword value from EAX at a location that was setup as a single byte!
Either use num resd 1 or num resb 4
section .bss
num resb 1 ; this is for outputting the current number
At a number of places in your program you process a byte from the accumulator register. You consistently use EAX but it would be more to the point (and read a lot easier) if you used the AL register instead.