next_char: mov al,message[ebx]
mov result[ebx],al
add al,32h
Watch your order of operations. You save the character to al, then copy al to the result string, *then* modify al. Also, if you're converting an ASCII letter to upper case, you need to subtract because the upper case letters are less in value than the lower case letters. Also, it's 32 decimal, not 32 hexadecimal.
mov al,message[ebx]
sub al,32
mov result[ebx],al
A cooler way to convert ASCII is to clear the 5th bit, which is what the subtraction does, but you can more directly show your intentions with AND:
mov al,message[ebx]
and al,0DFh
mov result[ebx],al
But that's also not quite right because not all of the characters in your string are in the valid range of 'a' to 'z'. If you apply any unconditional transformation on those characters, you'll get weird results. Most notably, a space becomes a null character because 32 is 00100000b, and you're effectively clearing the only set bit.

You need to add some sanity checks:
next_char:
mov al,message[ebx]
cmp al,'a'
jb no_change
cmp al,'z'
ja no_change
and al,0DFh
no_change:
mov result[ebx],al
inc ebx
loop next_char