2010-04-24 8 views
42
LEA EAX, [EAX] 

Ho incontrato questa istruzione in un binario compilato con il compilatore Microsoft C. Chiaramente non può cambiare il valore di EAX. Allora perché è lì?Qual è il punto di LEA EAX, [EAX]?

+0

è l'ottimizzazione? – Potatoswatter

+0

@Potatoswatter: Sì, questa è una versione di binario, quindi l'ottimizzazione dovrebbe essere attiva. Inoltre, sto usando ollydbg per il disassemblaggio. –

+0

Avete la corrispondente istruzione C per questa gemma? – Wikser

risposta

79

È un NOP.

I seguenti sono usati tipicamente come NOP. Fanno tutti la stessa cosa ma danno come risultato un codice macchina di diversa lunghezza. A seconda delle esigenze di allineamento uno di loro è scelto:

xchg eax, eax   = 90 
mov eax, eax   = 89 C0 
lea eax, [eax + 0x00] = 8D 40 00 
+0

Grazie unicornaddict. Questo lo risolve. –

+3

++ questo ha senso –

+5

In realtà, non è strettamente un 'NOP', perché introduce una dipendenza dai dati su' EAX'. Le moderne CPU rilevano questo modello specifico come un 'NOP' e ignorano la dipendenza dei dati, ma alcune CPU meno recenti potrebbero non farlo. –

3
LEA EAX, [EAX] 

Infatti, non modifica il valore di EAX. Per quanto ho capito, è identico in funzione:

MOV EAX, EAX 

Hai visto nel codice ottimizzato, o il codice non ottimizzato?

+0

Il codice è ottimizzato. Ma come giustifica/spiega questo LEA? –

+0

@Frederick: se non fosse stato ottimizzato, immagino che avrebbe senso se il compilatore utilizza LEA per una sorta di calcolo e un caso speciale ha generato questa dichiarazione ridondante (questo accade in un codice non ottimizzato) –

+0

Questo è un binario rilasciato ai clienti da la mia compagnia. Quindi deve essere la versione ottimizzata. –

33

Da this articolo:

Questo trucco è usato da MSVC++ compiler per emettere le istruzioni NOP di diversa lunghezza (per imbottiture prima salto obiettivi). Ad esempio, MSVC++ genera il seguente codice se bisogno di 4 byte e 6 byte padding:

8d6424 00 lea [ebx + 00], ebx ; Imbottitura a 4 byte 8d9b 00000000
lea [esp + 00000000], esp; 6-byte imbottitura

La prima riga è contrassegnata come "NPAD 4" in liste di assemblaggio generati dal compilatore , ed il secondo è "NPAD 6". I registri (ebx, esp) possono essere scelti da da quelli raramente usati per evitare le false dipendenze nel codice da .

Quindi questa è solo una sorta di NOP, che appare subito prima delle destinazioni delle istruzioni jmp per allinearle.

È interessante notare che è possibile identificare il compilatore dalla natura caratteristica di tali istruzioni.

+2

Dire che è un 'NOP' è solo la metà della risposta (eppure, stranamente, quella selezionata). Spiegare perché vorresti fare questi 'NOP's è la risposta completa. Molto bene. –

+0

L'ho riscontrato utilizzando anche il compilatore MSVC++. –