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?
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?
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 .
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
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!
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.
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.
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.
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.
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. –
Inoltre, si è dimenticato di elencare EBP ed ESP come chiamate conservate nelle comuni convenzioni di chiamata a 32 bit. –
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. –
Controllare questo: http://www.swansontec.com/sregisters.html – Jeffpowrs