The primary instructions for moving integers from operand to operand and loading them into registers are MOV (Move), XCHG (Exchange), XLAT (Translate), CWD (Convert Word to Double), and CBW (Convert Byte to Word).
The most common method of moving data, the MOV instruction, can be thought of as a copy instruction, since it always copies the source operand to the destination operand. Immediately after a MOV instruction, both the source and destination operands contain the same value.
The statements in the following example illustrate each type of memory move that can be performed with a single instruction. Note that you cannot move memory operands to memory operands in one operation.
; Immediate value moves
mov ax, 7 ; Immediate to register
mov mem, 7 ; Immediate to memory direct
mov mem[bx], 7 ; Immediate to memory indirect
; Register moves
mov mem, ax ; Register to memory direct
mov mem[bx], ax ; Register to memory indirect
mov ax, bx ; Register to register
mov ds, ax ; General register to segment
; register
; Direct memory moves
mov ax, mem ; Memory direct to register
mov ds, mem ; Memory to segment register
; Indirect memory moves
mov ax, mem[bx] ; Memory indirect to register
mov ds, mem[bx] ; Memory indirect to segment register
; Segment register moves
mov mem, ds ; Segment register to memory
mov mem[bx], ds ; Segment register to memory indirect
mov ax, ds ; Segment register to general
; register
This next example shows several common types of moves that require two instructions.
; Move immediate to segment register
mov ax, DGROUP ; Load immediate to general register
mov ds, ax ; Store general register to segment
; register
; Move memory to memory
mov ax, mem1 ; Load memory to general register
mov mem2, ax ; Store general register to memory
; Move segment register to segment register
mov ax, ds ; Load segment register to general
; register
mov es, ax ; Store general register to segment
; register
The MOVSX and MOVZX instructions for the 80386/486 processors extend and copy values in one step. See Section 4.2.1.4, “Extending Signed and Unsigned Integers.”
The XCHG (Exchange) instruction exchanges the data in the source and destination operands. Data can be exchanged between registers or between registers and memory, but not from memory to memory:
xchg ax, bx ; Put AX in BX and BX in AX
xchg memory, ax ; Put "memory" in AX and AX in "memory"
; xchg mem1, mem2 ; Illegal- can't exchange between
; memory location
In some circumstances, register-to-register moves are faster with XCHG than with MOV. If speed is important in your programs, check the Reference to find the fastest clock speeds for various operand combinations allowed with MOV and XCHG.
The XLAT (Translate) instruction loads data from a table into memory. The instruction is useful for translating bytes from one coding system to another. The syntax is
XLAT[[B]] [[[[segment:]]memory]]
Summary: XLAT and XLATB are synonyms.
The BX register must contain the address of the start of the table. By default, the DS register contains the segment of the table, but you can use a segment override to specify a different segment. Also, you need not give the operand except when specifying a segment override. (See Section 3.2.3, “Direct Memory Operands,” for information about the segment override operator.)
Before the XLAT instruction executes, the AL register should contain a value that points into the table (the start of the table is position 0). After the instruction executes, AL contains the table value pointed to. For example, if AL contains 7, the assembler puts the eighth byte of the table in the AL register.
This example, illustrating XLAT, looks up hexadecimal characters in a table to convert an eight-bit binary number to a string representing a hexadecimal number.
; Table of hexadecimal digits
hex BYTE "0123456789ABCDEF"
convert BYTE "You pressed the key with ASCII code "
key BYTE ?,?,"h",13,10,"$"
.CODE
.
.
.
mov ah, 8 ; Get a key in AL
int 21h ; Call DOS
mov bx, OFFSET hex ; Load table address
mov ah, al ; Save a copy in high byte
and al, 00001111y ; Mask out top character
xlat ; Translate
mov key[1], al ; Store the character
mov cl, 12 ; Load shift count
shr ax, cl ; Shift high character into
; position
xlat ; Translate
mov key, al ; Store the character
mov dx, OFFSET convert ; Load message
mov ah, 9 ; Display character
int 21h ; Call DOS
Since moving data to a different-sized register is illegal, you must “sign-extend” integers to convert signed data to a larger register or register pair.
Sign-extending means copying the sign bit of the unextended operand to all bits of the extended operand. The instructions in the following list sign-extend values as shown. They work only on signed values in the accumulator register.
Instruction | Function |
CBW | Convert byte to word |
CWD | Convert word to doubleword |
CWDE | Convert word to doubleword extended (80386/486 only) |
CDQ | Convert doubleword to quadword (80386/486 only) |
On the 80386/486, the CWDE instruction converts a signed 16-bit value in AX to a signed 32-bit value in EAX. The CDQ instruction converts a signed 32-bit value in EAX to a signed 64-bit value in the EDX:EAX register pair.
This example converts signed integers using CBW, CWD, CWDE, and CDQ.
.DATA
mem8 SBYTE -5
mem16 SWORD -5
mem32 SDWORD -5
.CODE
.
.
.
mov al, mem8 ; Load 8-bit -5 (FBh)
cbw ; Convert to 16-bit -5 (FFFBh) in AX
mov ax, mem16 ; Load 16-bit -5 (FFFBh)
cwd ; Convert to 32-bit -5 (FFFF:FFFBh)
; in DX:AX
mov ax, mem16 ; Load 16-bit -5 (FFFBh)
cwde ; Convert to 32-bit -5 (FFFFFFFBh)
; in EAX
mov eax, mem32 ; Load 32-bit -5 (FFFFFFFBh)
cdq ; Convert to 64-bit -5
; (FFFFFFFF:FFFFFFFBh) in EDX:EAX
Summary: Conversion instructions do not operate on unsigned numbers.
The procedure is different for unsigned values. Unsigned values are extended by filling the upper bits with zeros rather than by sign extension. Because the sign-extend instructions do not work on unsigned integers, you must set the value of the higher register to zero.
This example shows sign extension for unsigned numbers.
.DATA
mem8 BYTE 251
mem16 WORD 251
.CODE
.
.
.
mov al, mem8 ; Load 251 (FBh) from 8-bit memory
sub ah, ah ; Zero upper half (AH)
mov ax, mem16 ; Load 251 (FBh) from 16-bit memory
sub dx, dx ; Zero upper half (DX)
The 80386/486 processors provide instructions that move and extend a value to a larger data size in a single step. MOVSX moves a signed value into a register and sign-extends it. MOVZX moves an unsigned value into a register and zero-extends it.
; 80386/486 instructions
movzx dx, bl ; Load unsigned 8-bit value into
; 16-bit register and zero-extend
These special 80386 and 80486 instructions usually execute much faster than the equivalent 8086-80286 instructions.