Skip to main content
Engineering LibreTexts

7.4: Conversion Instructions

  • Page ID
    19900
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    It is sometimes necessary to convert from one size to another size. For example, a byte might need to be converted to a double-word for some calculations in a formula. The process used for conversions depends on the size and type of the operand. The following sections summarize how conversions are performed.

    Narrowing Conversions

    Narrowing conversions are converting from a larger type to a smaller type (i.e., word to byte or double-word to word).

    No special instructions are needed for narrowing conversions. The lower portion of the memory location or register may be accessed directly. For example, if the value of 50 (0x32) is placed in the rax register, the al register may be accessed directly to obtain the value as follows:

    mov    rax, 50
    mov    byte [bVal], al
    

    This example is reasonable since the value of 50 will fit in a byte value. However, if the value of 500 (0x1f4) is placed in the rax register, the al register can still be accessed.

    mov    rax, 500
    mov    byte [bVal], al
    

    In this example, the bVal variable will contain 0xf4 which may lead to incorrect results. The programmer is responsible for ensuring that narrowing conversions are performed appropriately. Unlike a compiler, no warnings or error messages will be generated.

    Widening Conversions

    Widening conversions are from a smaller type to a larger type (e.g., byte to word or word to double-word). Since the size is being expanded, the upper-order bits must be set based on the sign of the original value. As such, the data type, signed or unsigned, must be known and the appropriate process or instructions must be used.

    Unsigned Conversions

    For unsigned widening conversions, the upper part of the memory location or register must be set to zero. Since an unsigned value can only be positive, the upper-order bits can only be zero. For example, to convert the byte value of 50 in the al register, to a quadword value in rbx, the following operations can be performed.

    mov    a1, 50
    mov    rbx, 0
    mov    b1, a1
    

    Since the rbx register was set to 0 and then the lower 8-bits were set to the value from al (50 in this example), the entire 64-bit rbx register is now 50.

    This general process can be performed on memory or other registers. It is the programmer's responsibility to ensure that the values are appropriate for the data sizes being used.

    An unsigned conversion from a smaller size to a larger size can also be performed with a special move instruction, as follows:

    movzx     <dest>, <src>
    

    Which will fill the upper-order bits with zero. The movzx instruction does not allow a quadword destination operand with a double-word source operand. As previously noted, a mov instruction with a double-word register destination operand with a double-word source operand will zero the upper-order double-word of the quadword destination register.

    A summary of the instructions that perform the unsigned widening conversion are as follows:

    Instruction Explanation
    movzx <dest>, <src>

    movzx <reg16>, <op8>
    movzx <reg32>, <op8>
    movzx <reg32>, <op16>
    movzx <reg64>, <op8>
    movzx <reg64>, <op16>

    Unsigned widening conversion.
    Note 1, both operands cannot be memory.
    Note 2, destination operands cannot be an immediate.
    Note 3, immediate values not allowed.

    Examples: movzx cx, byte [bVar]
    movzx dx, a1
    movzx ebx, word [wVar]
    movzx ebx, cx
    movzx rbx, c1
    movzx rbx, cx

    A more complete list of the instructions is located in Appendix B.

    Signed Conversions

    For signed widening conversions, the upper-order bits must be set to either 0's or 1's depending on if the original value was positive or negative.

    This is performed by a sign-extend operation. Specifically, the upper-order bit of the original value indicates if the value is positive (with a 0) or negative (with a 1). The upper-order bit of the original value is extended into the higher bits of the new, widened value.

    For example, given that the ax register is set to -7 (0xfff9), the bits would be set as follows:

    截屏2021-07-20 上午10.05.20.png

    Since the value is negative, the upper-order bit (bit 15) is a 1. To convert the word value in the ax register into a double-word value in the eax register, the upper-order bit (1 in this example) is extended or copied into the entire upper-order word (bits 31-16) resulting in the following:

    截屏2021-07-20 上午10.06.48.png

    There are a series of dedicated instructions used to convert signed values in the A register from a smaller size into a larger size. These instructions work only on the A register, sometimes using the D register for the result. For example, the cwd instruction will convert a signed value in the ax register into a double-word value in the dx (upper- order portion) and ax (lower-order portion) registers. This is typically by convention written as dx:ax. The cwde instruction will convert a signed value in the ax register into a double-word value in the eax register.

    A more generalized signed conversion from a smaller size to a larger size can also be performed with some special move instructions, as follows:

    movsx     <dest>, <src>
    movsxd    <dest>, <src>
    

    Which will perform the sign extension operation on the source argument. The movsx instruction is the general form and the movsxd instruction is used to allow a quadword destination operand with a double-word source operand.

    A summary of the instructions that perform the signed widening conversion are as follows:

    Instruction Explanation
    cbw Convert byte in al into word in ax. Note, only works for al to ax register.
    Examples: cbw
    cwd Convert word in ax into double-word in dx:ax. Note, only works for ax to dx:ax registers.
    Examples: cwd
    cwde Convert word in ax into double-word in eax. Note, only works for ax to eax register.
    Examples: cwde
    cdq Convert double-word in eax into quadword in edx:eax.
    Note, only works for eax to edx:eax registers.
    Examples: cdq
    cdqe Convert double-word in eax into quadword in rax.
    Note, only works for rax register.
    Examples: cdqe
    cqo Convert quadword in rax into word in double-quadword in rdx:rax.
    Note, only works for rax to rdx:rax registers.
    Examples cqo
    movsx <dest>, <src>

    movsx <reg16>, <op8>
    movsx <reg32>, <op8>
    movsx <reg32>, <op16>
    movsx <reg64>, <op8>
    movsx <reg64>, <op16>
    movsxd <reg64>, <op32>
    Signed widening conversion (via sign extension).
    Note 1, both operands cannot be memory.
    Note 2, destination operands cannot be an immediate.
    Note 3, immediate values not allowed.
    Note 4, special instruction (movsxd) required for 32-bit to 64-bit signed extension.
    Examples: movzx cx, byte [bVar]
    movzx dx, a1
    movzx ebx, word [wVar]
    movzx ebx, cx
    movzxd rbx, dword [dVar]

    A more complete list of the instructions is located in Appendix B.


    This page titled 7.4: Conversion Instructions is shared under a CC BY-NC-SA license and was authored, remixed, and/or curated by Ed Jorgensen.

    • Was this article helpful?