2009-11-09 2 views
83

Je voudrais savoir quelle est la différence entre ces instructions est:Quelle est la différence entre MOV et LEA?

MOV AX, [TABLE-ADDR] 

et

LEA AX, [TABLE-ADDR] 
+2

dupliquer: http://stackoverflow.com/questions/1658294/x86-asm-whats-the-purpose-of-the-lea-instruction –

+4

merci nick. Tout d'abord, je n'aurais pas trouvé de réponse à cette question en regardant ce lien. Ici, je cherchais une information spécifique, la discussion dans le lien que vous avez fourni est de nature plus générale. – naveen

+2

J'ai repoussé le dup de Nick il y a des années mais vtc'd juste maintenant. À la réflexion, j'étais trop hâte et maintenant avec naveen que a) l'autre question ne répond pas "quelle est la différence" et b) ceci est une question utile. Excuses à naveen pour mon erreur - si seulement je pouvais défaire vtc ... –

Répondre

107
  • LEA signifie charge Adresse efficace
  • MOV signifie Valeur de charge

En bref, LEA charge une pointeur vers l'élément que vous adressez alors que MOV charge la valeur réelle à cette adresse.

Le but de LEA est de permettre un 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 seulement 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. Là où son utilité est si vous avez un calcul en plusieurs parties avec plusieurs adresses de base, etc.

+3

+1 merci pour l'explication claire, m'a aidé [réponse] (http://stackoverflow.com/a/25824111/183120) une autre question. – legends2k

+0

Cela me rend confus que lea a "charger" dans le nom et les gens disent qu'il "charge" une adresse calculée dans un registre, parce que toutes les entrées pour calculer l'emplacement de la mémoire sont des valeurs immédiates ou des registres. AFAICT lea effectue seulement un calcul, il ne charge rien, où le chargement signifie toucher la mémoire? –

+1

@josephGarvin IIRC le terme fetch serait appliqué à cet aspect; La charge est juste comment vous remplacez la valeur dans un registre avec quelque chose à partir de zéro. par exemple. 'LAHF' est: _Load FLAGS dans AH register_. Dans le CIL du CLR (qui est une machine abstraite basée sur une pile de niveau supérieur, le terme _load_ se réfère à mettre une valeur sur la pile notionnelle et est normalement 'l' ..., et l'équivalent' s' ... fait l'inverse) . Ces notes: https://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/load.html) suggèrent qu'il existe effectivement des architectures où votre distinction s'applique. –

10

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:

http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-1.html#HEADING1-136

+0

Je suppose, à l'exception que dans GNU assembleur ce n'est pas vrai quand il s'agit d'étiquettes dans le segment .bss? AFAIR vous ne pouvez pas réellement "loler TextLabel, LabelFromBssSegment' quand vous avez eu smth. comme '.bss \t .lcomm LabelFromBssSegment, 4', vous auriez' movl $ TextLabel, LabelFromBssSegment', n'est-ce pas? – JSmyth

+0

@JSmyth: C'est uniquement parce que 'lea' requiert une destination de registre, mais' mov' peut avoir une source 'imm32' et une destination mémoire. Cette limitation n'est bien sûr pas spécifique à l'assembleur GNU. –

+0

En outre, cette réponse est fondamentalement fausse, car la question pose une question sur 'MOV AX, [TABLE-ADDR]', qui est une charge. Donc, il y a une différence majeure. L'instruction équivalente est 'mov ax, OFFSET table_addr' –

10

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.

La version lea fonctionne également bien si table_addr est une variable locale, par ex.

some_procedure proc 

local table_addr[64]:word 

lea ax,table_addr 
+0

merci beaucoup, c'est juste que je ne peux pas marquer plus d'un comme réponse :( – naveen

+4

La différence entre les instructions MOV x86 et Le LEA ne dépend absolument PAS de l'assembleur –

0

La différence est subtile mais importante. L'instruction MOV est un 'MOVe' en fait une copie de l'adresse que représente l'étiquette TABLE-ADDR. L'instruction LEA est une «adresse effective de chargement» qui est une instruction indirecte, ce qui signifie que TABLE-ADDR pointe vers un emplacement de mémoire où l'adresse à charger est trouvée.

L'utilisation efficace de LEA est équivalente à l'utilisation de pointeurs dans des langages tels que C, en tant que telle, c'est une instruction puissante.

+6

Je pense que cette réponse est confuse au mieux. "L'instruction LEA est une" adresse effective de chargement "qui est une instruction indirecte, ce qui signifie que TABLE-ADDR pointe vers un emplacement de mémoire auquel l'adresse à charger est trouvée. "En fait, LEA chargera l'adresse, pas le contenu de l'adresse Je pense que le questionneur doit être rassuré que MOV et LEA peuvent se chevaucher, et faire exactement la même chose, dans certaines circonstances –

21

L'instruction MOV reg, addr signifie lire une variable stockée à l'adresse addr dans le registre reg. L'instruction LEA reg, addr signifie lire l'adresse (pas la variable stockée à l'adresse) dans le registre reg.

Une autre forme de l'instruction MOV est MOV reg, immdata qui signifie lire les données immédiates (c.-à-d.constante) immdata dans le registre reg. Notez que si l'addr dans LEA reg, addr est simplement une constante (c'est-à-dire un décalage fixe) alors cette instruction LEA est essentiellement identique à une instruction MOV reg équivalente, immdata qui charge la même constante que les données immédiates.

31

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édiat au lieu d'une charge.

+1

Syntaxe NASM uniquement Dans la syntaxe MASM, 'mov eax, var' est une charge, identique à' mov eax, [var] ', et vous devez utiliser' mov eax, OFFSET var' pour utiliser une étiquette comme constante immédiate –

+0

Clair, simple et démontre ce que j'essayais de confirmer. Merci. – JayArby

2

En gros ... « Déplacer dans REG ... après le calculer ... » il semble être agréable à d'autres fins aussi bien :)

si vous oubliez juste que la valeur est un pointeur vous pouvez l'utiliser pour des optimisations/minimisation de code ... 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 
+0

Yup, ['lea' est une instruction shift-and-add] (https://stackoverflow.com/questions/46597055/address-computation-instruction-leaq/46597375#46597375) qui utilise un codage et une syntaxe de l'opérande mémoire , car le matériel sait déjà comment décoder ModR/M + SIB + disp0/8/32. –

Questions connexes