Well...
mov cx, dx
shl ecx, 16
mov cx, ax
or maybe...
push dx
push ax
pop ecx
But, as a general rule, you'd want to stick with one size of register. For signed integers, or if your values are of a magnitude that it doesn't matter...
imul cx, ax, bx
; or
imul ecx, eax, ebx
Simplest thing, if you're doing 32-bit code, is to use 32-bit registers...
mov eax, 10
mov ebx, 10
mul ebx
"mul" will set the carry flag if the result overflows [e]ax and there's anything but zero in [e]dx. You could use this to determine if you need to bother with [e]dx at al... if that applies to what you're trying to do...
Best,
Frank