2009-11-09 14 views
83

Vorrei sapere qual è la differenza tra queste istruzioni è:Qual è la differenza tra MOV e LEA?

MOV AX, [TABLE-ADDR] 

e

LEA AX, [TABLE-ADDR] 
+2

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

+4

grazie nick. Prima di tutto, non avrei trovato una risposta a questa domanda esaminando quel collegamento. Qui stavo cercando informazioni specifiche, la discussione nel link che hai fornito è di natura più genrale. – naveen

+2

Ho upvoted @ duplex di Nick fa ma vtc'd solo ora. Riflettendomi, ero troppo frettoloso e ora con naveen che a) l'altra domanda non risponde "qual è la differenza" eb) questa è una domanda utile. Mi scuso per il mio errore - se solo potessi annullare vtc ... –

risposta

107
  • LEA significa carico effettivo Indirizzo
  • MOV significa Valore di caricamento

Insomma, LEA carichi un puntatore all'oggetto che stai indirizzando mentre MOV carica il valore reale a quell'indirizzo.

Scopo della LEA è di consentire di eseguire un calcolo indirizzo non banale e memorizzare il risultato [per un utilizzo successivo]

LEA ax, [BP+SI+5] ; Compute address of value 

MOV ax, [BP+SI+5] ; Load value at that address 

Dove non sono coinvolti solo costanti, MOV (attraverso calcoli costanti dell'assemblatore a volte può sovrapporsi ai casi più semplici di utilizzo di LEA. Dove il suo utile è se si dispone di un calcolo più parti con più indirizzi di base ecc

+3

+1 grazie per la spiegazione chiara, mi ha aiutato [risposta] (http://stackoverflow.com/a/25824111/183120) un'altra domanda. – legends2k

+0

Mi confonde che lea abbia "caricato" nel nome e la gente dice che "carica" ​​un indirizzo calcolato in un registro, perché tutti gli input per calcolare la posizione di memoria sono valori immediati o registri. AFAICT lea esegue solo un calcolo, non carica nulla, dove caricare significa toccare la memoria? –

+1

@josephGarvin IIRC il termine recupero verrà applicato a quell'aspetto; Il caricamento è solo come si sostituisce il valore in un registro con qualcosa da zero. per esempio. 'LAHF' è: _Laad FLAGS in AH register_. Nel CIL del CLR (che è una macchina astratta basata su stack di livello superiore, il termine _load_ si riferisce a mettere un valore nello stack nozionale ed è normalmente 'l' ..., e' s' ... equivalente fa l'opposto) . Queste note: https://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/load.html) suggeriscono che esistono effettivamente architetture in cui si applica la distinzione. –

10

Se si specifica solo un letterale, non v'è alcuna differenza. LEA ha più capacità, però, e si può leggere su di loro qui:

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

+0

Immagino, con l'eccezione che nell'assembler GNU non è vero quando si tratta di etichette nel segmento .bss? AFAIR non puoi davvero "legare TextLabel, LabelFromBssSegment" quando hai ottenuto smth. come '.bss \t .lcomm LabelFromBssSegment, 4', si dovrebbe' movl $ TextLabel, LabelFromBssSegment', non è vero? – JSmyth

+0

@JSmyth: Questo è solo perché 'lea' richiede una destinazione di registro, ma' mov' può avere una sorgente 'imm32' e una destinazione di memoria. Questa limitazione ovviamente non è specifica per l'assemblatore GNU. –

+0

Inoltre, questa risposta è fondamentalmente errata perché la domanda riguarda 'MOV AX, [TABLE-ADDR]', che è un carico. Quindi c'è una grande differenza. L'istruzione equivalente è 'mov ax, OFFSET table_addr' –

10

Dipende l'assemblatore usato, perché

mov ax,table_addr 

in MASM lavora come

mov ax,word ptr[table_addr] 

Così carica i primi byte da table_addr e NON lo scostamento a table_addr. Si consiglia di utilizzare invece

mov ax,offset table_addr 

o

lea ax,table_addr 

che funziona lo stesso.

lea funziona anche se table_addr è una variabile locale, ad es.

some_procedure proc 

local table_addr[64]:word 

lea ax,table_addr 
+0

grazie mille, è solo che non posso contrassegnare più di una risposta :( – naveen

+4

La differenza tra le istruzioni x86 MOV e LEA sicuramente non dipende dall'assemblatore –

0

La differenza è sottile ma importante. L'istruzione MOV è un 'MOVE' effettivamente una copia dell'indirizzo che l'etichetta TABLE-ADDR rappresenta. L'istruzione LEA è un 'Indirizzo effettivo carico' che è un'istruzione indiretta, il che significa che TABLE-ADDR punta a una posizione di memoria in cui viene trovato l'indirizzo da caricare.

L'uso efficace di LEA equivale all'utilizzo di puntatori in linguaggi come C, in quanto tale è un'istruzione potente.

+6

Penso che questa risposta sia al massimo confusionaria. "L'istruzione LEA è un 'Load Effective Address' che è un'istruzione indiretta, il che significa che TABLE-ADDR punta a una posizione di memoria in cui L'indirizzo da caricare è stato trovato. "In realtà LEA caricherà l'indirizzo, non il contenuto dell'indirizzo. Penso che in realtà l'interrogante debba essere rassicurato sul fatto che MOV e LEA possano sovrapporsi e fare esattamente la stessa cosa, in alcune circostanze –

21

L'istruzione MOV reg, addr significa leggere una variabile memorizzata all'indirizzo address nel registro reg. L'istruzione LEA reg, addr significa leggere l'indirizzo (non la variabile memorizzata all'indirizzo) nel registro reg.

Un'altra forma dell'istruzione MOV è MOV reg, immdata che significa leggere i dati immediati (ad es.costante) immdata nel registro reg. Si noti che se l'addr nel reg LEA, addr è solo una costante (cioè un offset fisso), allora l'istruzione LEA è essenzialmente esattamente la stessa di un equivalente registro MOV, istruzione immdata che carica la stessa costante dei dati immediati.

31

Nella sintassi 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 

Nella sintassi MASM, utilizzare OFFSET var per ottenere un mov-immediata invece di un carico.

+1

in Solo sintassi NASM. Nella sintassi MASM, 'mov eax, var' è un carico, uguale a' mov eax, [var] ', e devi usare' mov eax, OFFSET var' per usare un'etichetta come costante immediata –

+0

Chiaro, semplice e dimostra ciò che stavo cercando di confermare. Grazie. – JayArby

2

In sostanza ... "Sposta in REG ... dopo aver calcolato che ..." Sembra essere bello per altri scopi :)

se si dimentica solo che il valore è un puntatore è possibile utilizzarlo per ottimizzazioni del codice/minimizzazione ... che cosa mai ..

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

originaly sarebbe:

MOV EAX, EBX 
ADD EAX, ECX 
ADD EAX, 5 
+0

Sì, ['lea' è un'istruzione shift-and-add] (https://stackoverflow.com/questions/46597055/address-computation-instruction-leaq/46597375#46597375) che utilizza la codifica e la sintassi della macchina degli operandi della memoria , perché l'hardware sa già come decodificare ModR/M + SIB + disp0/8/32. –

Problemi correlati