Quelle est la différence entre MOV et LEA?
-
19-09-2019 - |
Question
Je voudrais savoir quelle est la différence entre ces instructions est:
MOV AX, [TABLE-ADDR]
et
LEA AX, [TABLE-ADDR]
La solution
-
LEA
signifie la charge Adresse efficace -
MOV
signifie Valeur de charge
En bref, LEA
charge un pointeur sur l'élément que vous vous adressez alors que MOV charge la valeur réelle à cette adresse.
Le but de LEA
est de permettre une pour effectuer un calcul d'adresse non trivial et stocker le résultat [pour un usage ultérieur]
LEA ax, [BP+SI+5] ; Compute address of value
MOV ax, [BP+SI+5] ; Load value at that address
Où il y a juste des constantes impliquées, MOV
(par des calculs constants de l'assembleur) peut parfois sembler se chevaucher avec les cas les plus simples d'utilisation de LEA
. Il est utile si vous avez un calcul en plusieurs parties avec plusieurs adresses de base etc.
Autres conseils
Dans la syntaxe MSNA:
mov eax, var == lea eax, [var] ; i.e. mov r32, imm32
lea eax, [var+16] == mov eax, var+16
lea eax, [eax*4] == shl eax, 2 ; but without setting flags
Dans la syntaxe MASM, utilisez OFFSET var
pour obtenir un mov immédiatement au lieu d'une charge.
L'instruction MOV reg, addr moyens lire une variable stockée à addr adresse dans le registre Reg. L'instruction LEA reg, addr moyens de lecture de l'adresse (non la variable stockée à l'adresse) dans le registre Reg.
Une autre forme de l'instruction MOV MOV est reg, immdata ce qui signifie que de lire les données immédiates (par exemple constant) immdata dans le registre Reg. Notez que si le addr dans reg LEA, addr est juste une constante (par exemple un décalage fixe) alors que l'instruction LEA est essentiellement identique à un reg équivalent MOV, instruction immdata qui charge la même constante en tant que données immédiates.
Si vous spécifiez uniquement un littéral, il n'y a pas de différence. LEA a plus de capacités, bien que, et vous pouvez lire à ce sujet ici:
Cela dépend de l'assembleur utilisé, parce que
mov ax,table_addr
dans MASM fonctionne comme
mov ax,word ptr[table_addr]
Il charge les premiers octets de table_addr
et pas le décalage table_addr
. Vous devez utiliser à la place
mov ax,offset table_addr
ou
lea ax,table_addr
qui fonctionne de la même.
version lea
fonctionne aussi bien si table_addr
est une variable locale par exemple.
some_procedure proc
local table_addr[64]:word
lea ax,table_addr
En gros ... "Déplacer dans REG ... après le calculer ..." il semble être agréable à d'autres fins aussi bien:)
si vous venez oublier que la valeur est un pointeur vous pouvez l'utiliser pour des optimisations de code / minimisation ... ce que jamais ..
MOV EBX , 1
MOV ECX , 2
;//with 1 instruction you got result of 2 registers in 3rd one ...
LEA EAX , [EBX+ECX+5]
EAX = 8
Originalement il serait:
MOV EAX, EBX
ADD EAX, ECX
ADD EAX, 5
La différence est subtile mais importante. L'instruction MOV est un « mouvement » en fait une copie de l'adresse que l'étiquette TABLE-ADDR signifie. L'instruction LEA est une « charge d'adresses efficace » qui est une instruction indirected, ce qui signifie que les points TABLE-ADDR à un emplacement de mémoire à laquelle l'adresse de chargement est trouvée.
L'utilisation efficace LEA équivaut à utiliser des pointeurs dans des langages tels que C, en tant que telle est une instruction puissante.