J'aimerais savoir quelle est la différence entre ces instructions:
MOV AX, [TABLE-ADDR]
et
LEA AX, [TABLE-ADDR]
LEA
signifie adresse de chargement effectifMOV
signifie valeur de chargementEn bref, LEA
charge un pointeur sur l'élément que vous adressez alors que MOV charge la valeur réelle à cette adresse.
Le but de LEA
est de permettre à un utilisateur d’effectuer un calcul d’adresse non trivial et de 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
Là où il n'y a que des constantes impliquées, MOV
(à travers les calculs constants de l'assembleur) peut parfois sembler se chevaucher avec les cas les plus simples d'utilisation de LEA
. C'est utile si vous avez un calcul en plusieurs parties avec plusieurs adresses de base, etc.
En syntaxe NASM:
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'un chargement.
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, ce qui signifie lire les données immédiates (c'est-à-dire constantes) immdata dans le registre reg. Notez que si l'adrr dans LEA reg, addr est juste une constante (c'est-à-dire un décalage fixe), alors cette instruction LEA est essentiellement identique à une instruction équivalente MOV reg et 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, cependant, et vous pouvez lire à leur sujet ici:
http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-1.html#HEADING1-136
Cela dépend de l'assembleur utilisé, car
mov ax,table_addr
dans MASM fonctionne comme
mov ax,Word ptr[table_addr]
Donc, il charge les premiers octets de table_addr
et PAS le décalage par rapport à table_addr
. Vous devriez utiliser à la place
mov ax,offset table_addr
ou
lea ax,table_addr
qui fonctionne de la même manière.
lea
version fonctionne aussi très bien si table_addr
est une variable locale, par exemple.
some_procedure proc
local table_addr[64]:Word
lea ax,table_addr
En gros ... "Passez à REG ... après le calcul ..." il semble que ce soit bien pour d'autres buts aussi :)
si vous oubliez que la valeur est un pointeur, vous pouvez l’utiliser pour optimiser/minimiser le code ...
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
à l'origine ce serait:
MOV EAX, EBX
ADD EAX, ECX
ADD EAX, 5