assemblybinaryx86-16sign-extension

Zero/Sign extension in assembly without using MOVZX/MOVSX


I'm trying to do a zero or sign extension but without using MOVZX or MOVSX.
I basically want to mimic the said commands, but not use them. Is there a way to do it?
To add 0 from the left there's SHR but I'm not quite sure that it works the same because it changes the value...

I'm using Assembly 8086


Solution

  • All x86-16 CPUs provide the CBW (8-bit to 16-bit) and CWD (16-bit to 32-bit) instructions.

    If you want to do a "generic" sign extension (e.g. from 12-bit to 16-bit instead of from 8-bit to 16-bit), you might use the following algorithm that works on any CPU:

    Example: Sign-extending AX from 12-bit to 16-bit:

    ; Ensure that the value is really a 12-bit value
    AND AX, 0xFFF
    ; Extract the highest bit
    MOV CX, AX
    AND CX, 0x800
    ; Subtract that value twice
    SUB AX, CX
    SUB AX, CX
    

    The code above may be simplified by working on the high byte of AX only (e.g. AND AH, 0xF instead of AND AX, 0xFFF).