Chapter 9 - Data Movement

9.1  Move (mov)

The mov command transfers a byte, word, or dword from the 2nd operand to the 1st operand.  It can transfer data between two registers, between a register and memory, but not from memory to memory.  It can also be used to load an immediate value into a register or memory.  Below are some examples.

Command Description
mov eax, ebx Move the 4 bytes in ebx to eax
mov eax, A Move memory address of variable A to eax
mov eax, [A] Move value at memory address A into eax
mov ecx, 1234 Move immediate value 1234 to ecx
mov [A], 73 Move immediate value 73 to memory at A
mov eax, A
mov dword [eax], 73
Move memory address of A to eax.  Move 73 to memory in eax.  [A] is now equal to 73.
mov cl, dl Move the byte at dl into cl
mov eax, [ecx+4] Move 4 bytes at memory address ecx+4 to eax
mov [ecx], 1234 Movie immediate value 1234 to memory address at [ecx]
mov eax, 0
mov ebx, 0xffff
mov al, bl
Move the byte with bl to al.  Register eax is now equal to 0xff (255).

9.2  Size Directives

The intended size of the of the data at a given memory address can usually be inferred from the assembly code instruction.  For example:

   mov [eax], A   ;if A is declared as a dd, then it will move 32 bits at [A] into eax


If the size of the data is ambiguous such as with immediate values, you must use a size directive.  For example:

   mov dword [eax], 73  ;it is not known if 73 should be stored in 1, 2, or 4 bytes so dword is used

Size directives are also necessary in printf commands.

   cinvoke printf,"%d", A            ;since variables have a size the directive is not needed
   cinvoke printf,"%d", dword [ecx]  ;the size of the data at memory address [ecx] is not known
 

Directive Size Example
byte 1 byte mov byte [eax], 73   ;move 73 into byte at [eax]
word 2 bytes mov word [eax], 73   ;move 73 into 2 bytes at [eax]
dword 4 bytes mov dword [eax], 73  ;move 73 into 4 bytes at [eax]


9.3  Memory Offets

The program below demonstrates how memory offsets can be used.  Each of the three variable A,B,C are stored in consecutive memory.  Since they store 4 byte values, you can use [A+4] to reference the value in [B].

offset.asm

format PE console
include 'win32ax.inc'

;=======================================
section '.code' code readable executable
;=======================================
start:
        cinvoke printf,"Value is %d %c", [A], 10
        cinvoke printf,"Value is %d %c", [A+4], 10
        cinvoke printf,"Value is %d %c", [A+8], 10
        invoke Sleep,-1

;======================================
section '.data' data readable writeable
;======================================
A       dd 33
B       dd 44
C       dd 55

;====================================
section '.idata' import data readable
;====================================
library msvcrt,'msvcrt.dll',kernel32,'kernel32.dll'
import msvcrt,printf,'printf'
import kernel32,Sleep,'Sleep'

Output

Value is 33
Value is 44
Value is 55


9.3  Exchange (xchg)

Use xchg to exchange two operands.  Here are some examples:

   xchg eax, ebx   ;swap the contents of registers eax and ebx
   xchg eax, [A]   ;swap contents of eax and variable A