Moving_Data ..
Mov
Move_to Destination, Source:
mov ebx 1 ; ebx = 1
mov eax ebx ; eax = 1
[Data: 24]
mov esi Data ; esi = Whatever Memory Address where ''Data'' is stored
mov eax D$esi ; eax = 24
[BytesData: B$ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
mov al B$BytesData+4 ; al = 4
[dWordsData: D$ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
mov eax 5 | mov al B$dWordsData+eax*4 ; al = 4
Movzx / Movsx
Move_to Destination (Reg32) , Source (Reg/Mem 8/16), Zero or Sign extended:
movzx ebx B$edi ; Byte at ebx = 1 >>> ebx = 1
movsx eax W$esi ; Word at esi = -03A >>> eax = -03A
LEA (Load Effective Address)
LEA loads in the destination register, the Address of a given Data (noted as Value):
[MyTable: 25 #32]
lea esi D$MyTable ; esi = MyTable Address
This is to say that upper statement does exactly the same as:
mov esi MyTable
LEA is often used as is in a wrong syntax assembler (like MASM) to retrieve the Address of a symbol previously declared with a Data typing.
Hopefully, the real interest of LEA, compared to MOV resides in its extended forms. These extended forms are nothing but the ones of Effective_Address notation:
[MyTable: 111 222 333 444 555]
mov D$WhatIndex 3 ;DD
; ....
; ....
mov ebx D$WhatIndex
lea eax D$MyTable+ebx*4
mov ecx D$eax ; ecx = 444
You can consider that upper LEA does the same as a mov instruction (which does *NOT* exist in the x86 instruction set), like:
mov eax MyTable+ebx*4
The multiplication (*4) can only be *2 / *4 / *8. The maximum syntax for LEA is, for example (you can add only one constant):
lea eax D$Table + ebx*4 + edx + 12
... what does, in one single instruction, the same as:
mov eax ebx | shl eax 2 | add eax MyTable | add eax edx | add eax 12
Besides use for retrieving an indexed pointer to a table, LEA can be deturned from its original target to perform fast integer multiplication with possible move and immediate addition in one instruction:
lea eax D$ebx*2-1 ; eax = (ebx*2)-1
lea eax D$ebx*2+ebx ; eax = ebx*3
lea eax D$ecx*4+24 ; eax = (ecx*4)+24
lea eax D$ebx*4+ebx ; eax = ebx*5
lea eax D$eax*8-02000 ; eax = (eax*8)-02000
lea eax D$eax*8+eax ; eax = eax*9
Xchg (Exchange)
mov eax 1 | mov ebx 2
xchg eax ebx ; eax = 2 / ebx = 1
Like as with the MOV instruction, one member can as well be a Memory Location :
xchg edi D$PreviousPointer
Push / Pop
Push and Pop, Store/Restore to/from the Stack the given member. So, you can use them, for example, to move some value from memory to memory (Note there is no particular instruction for this with x86 CPUs):
push D$Value1 | pop D$Value2 ; D$Value2 = D$Value1
Instead of:
mov eax D$Value1 | mov D$Value2 eax
I often use a Macro for exchanging the Values in two dWords Memories:
[Exchange | push #1 | push #2 | pop #1 | pop #2]
[Value1: 1 Value2: 2]
Exchange D$Value1 D$Value2 ; D$Value1 = 2, D$Value2 = 1
~~~~~~~