2009-12-06 16 views
90

Qual è lo scopo e l'uso effettivo dei registri ESI di EDI & nell'assemblatore?Scopo dei registri ESI e EDI?

So che vengono utilizzati per operazioni a stringa per una cosa.

Qualcuno può anche dare un esempio?

+6

Controllare questo: http://www.swansontec.com/sregisters.html – Jeffpowrs

risposta

62

Ci sono alcune operazioni che è possibile solo fare con DI/SI (o le loro controparti estese, se non hai imparato ASM nel 1985). Tra questi ci sono

REP STOSB 
REP MOVSB 
REP SCASB 

Quali sono, rispettivamente, operazioni per ripetizione (= massa) di memorizzazione, caricamento e scansione. Quello che fai è impostare SI e/o DI per puntare su uno o entrambi gli operandi, magari mettere un conteggio in CX e poi lasciarlo strappare. Queste sono operazioni che funzionano su un mucchio di byte alla volta, e in qualche modo mettono la CPU in automatico. Poiché non stai codificando esplicitamente i loop, essi fanno le loro cose in modo più efficiente (di solito) di un loop codificato a mano.

Nel caso ve lo stiate chiedendo: A seconda di come si imposta l'operazione, la memorizzazione ripetuta può essere qualcosa di semplice come il punzonamento del valore 0 in un grande blocco contiguo di memoria; MOVSB ​​è usato, penso, per copiare dati da un buffer (beh, qualsiasi mazzo di byte) a un altro; e SCASB è usato per cercare un byte che corrisponda ad un criterio di ricerca (o che cosa è – a cui si può cercare :))

Questa è la maggior parte di ciò che tali reg sono per .

+5

Suggerimento di ottimizzazione dal passato: * rep stosw * è molto più veloce di * rep stosb *, quindi se la copia di due e due byte si adatta quello che stai cercando di fare, usalo invece nel tuo codice assembly x86 a 16 bit ottimizzato a mano ... – Alexander

27

Opcode come MOVSB ​​e MOVSW che copiano in modo efficiente i dati dalla memoria indicata da ESI nella memoria indicata da EDI. Così,

mov esi, source_address 
mov edi, destination_address 
mov ecx, byte_count 
cld 
rep movsb ; fast! 
10

In aggiunta alle operazioni di stringa (MOVS/INS/STO/CMPS/SCASB/W/D/Q etc.) menzionato in altre risposte, ho voluto aggiungere che ci sono anche più " istruzioni di montaggio x86 moderni" che utilizzano almeno implicitamente EDI/RDI:

lo SSE2 MASKMOVDQU (e l'imminente AVX VMASKMOVDQU) di istruzioni selettivamente scrivere byte da un registro XMM alla memoria puntata da EDI/RDI.

63

SI = Sorgente Indice
DI = Destinazione

Come altri hanno indicato, hanno usi speciali con le istruzioni di stringa. Per la programmazione modalità reale, il registro ES segmento deve essere usato con DI e DS con SI come in

movsb es:di, ds:si 

SI e DI possono essere utilizzati anche come registri indice di uso generale. Ad esempio, il codice sorgente C

srcp [srcidx++] = argv [j]; 

compila in

8B550C   mov edx,[ebp+0C] 
8B0C9A   mov ecx,[edx+4*ebx] 
894CBDAC  mov [ebp+4*edi-54],ecx 
47    inc edi 

dove ebp+12 contiene argv, ebx è j e edi ha srcidx.Si noti che la terza istruzione utilizza edi moltiplicata per 4 e aggiunge ebp offset da 0x54 (la posizione di srcp); parentesi intorno all'indirizzo indicano indiretta.


Anche se non ricordo dove l'ho visto, ma this conferma la maggior parte di esso, e this (slide 17) altri:

AX = accumulatori
DX = parola doppia accumulatore
CX = contatore
BX = registro di base

Sembrano registri di uso generale, ma ci sono un certo numero di istruzioni che (inaspettatamente?) usano uno di loro - ma quale? - implicitamente.

3

Oltre ai registri in uso per le operazioni di massa, sono utili per la loro proprietà di essere preservati tramite una chiamata di funzione (call-preserve) nella convenzione di chiamata a 32 bit. ESI, EDI, EBX, EBP, ESP sono protetti da chiamate mentre EAX, ECX ed EDX non sono protetti da chiamate. I registri di call conservati sono rispettati dalla funzione di libreria C e i loro valori persistono attraverso le chiamate di funzione della libreria C.

Jeff Duntemann nel suo libricino di montaggio ha un codice di esempio per la stampa degli argomenti della riga di comando. Il codice usa esi ed edi per memorizzare i contatori poiché saranno invariati dalla funzione di libreria C printf. Per altri registri come eax, ecx, edx, non vi è alcuna garanzia che non vengano utilizzati dalle funzioni della libreria C.

https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025

Vedere punto 12.8 Come C vede Argomenti della riga di comando.

Si noti che le convenzioni di chiamata a 64 bit sono diverse dalle convenzioni di chiamata a 32 bit e non sono sicuro che questi registri siano conservati o meno.

+0

Non ho mai sentito "sacro" usato per descrivere ciò che la maggior parte della gente chiama "volatile"/"non volatile" o "callee-saved" vs "caller-saved". Mi piace "call-preserved"/"call-clobbered", poiché non implica che vengano effettivamente salvati ovunque. In ogni caso, ESI/RSI ed EDI/RDI non sono protetti da chiamate nell'ABI System V x86-64. –

+0

Inoltre, si è dimenticato di elencare EBP ed ESP come chiamate conservate nelle comuni convenzioni di chiamata a 32 bit. –

+1

Comunque, questo è un buon punto. Nel codice attuale, è più probabile che tu scelga EDI/ESI per qualcosa in base ai motivi della convenzione di chiamata piuttosto che perché sono speciali per qualsiasi istruzione. –

Problemi correlati