rep; nop
rep; nop
significa? pause
? rep nop
(senza il punto e virgola)? nop
semplice? Dopo qualche discussione nei commenti di un’altra domanda , mi sono reso conto che non so quale rep; nop;
rep; nop;
significa nell’assembly x86 (o x86-64). E anche io non sono riuscito a trovare una buona spiegazione sul web.
So che rep
è un prefisso che significa “ripeti l’istruzione successiva cx
volte” (o almeno lo era, nel vecchio assembly x86 a 16 bit). Secondo questa tabella riassuntiva su Wikipedia , sembra che il rep
possa essere usato solo con movs
, cmps
, cmps
, cmps
, cmps
(ma forse questa limitazione è stata rimossa sui nuovi processori). Quindi, penserei che il rep nop
(senza punto e virgola) ripeterà una operazione di nop
cx
volte.
Tuttavia, dopo ulteriori ricerche, sono diventato ancora più confuso. Sembra quel rep; nop
rep; nop
e rep; nop
pause
mappa nello stesso identico opcode , e la pause
ha un comportamento leggermente diverso rispetto al solo nop
. Alcuni vecchi messaggi del 2005 dicevano cose diverse:
Con queste diverse opinioni, non riuscivo a capire il significato corretto.
Viene usato nel kernel Linux (su entrambi i386 e x86_64 ), insieme a questo commento: /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
Viene anche utilizzato in BeRTOS , con lo stesso commento.
rep; nop
rep; nop
è effettivamente uguale all’istruzione di pause
(opcode F390
). Potrebbe essere usato per gli assemblatori che non supportano ancora l’istruzione di pause
. Su processori precedenti, questo semplicemente non ha fatto nulla, proprio come nop
ma in due byte. Sui nuovi processori che supportano l’hyperthreading, viene utilizzato come suggerimento per il processore che si sta eseguendo uno spinloop per aumentare le prestazioni. Dal riferimento alle istruzioni di Intel :
Migliora le prestazioni dei cicli di attesa spin. Quando si esegue un ciclo di “spin-wait loop”, un processore Pentium 4 o Intel Xeon subisce una severa penalizzazione delle prestazioni quando si esce dal ciclo perché rileva una ansible violazione dell’ordine di memoria. L’istruzione PAUSE fornisce un suggerimento al processore che la sequenza di codice è un ciclo di attesa-spin. Il processore utilizza questo suggerimento per evitare la violazione dell’ordine di memoria nella maggior parte delle situazioni, il che migliora notevolmente le prestazioni del processore. Per questo motivo, si consiglia di inserire un’istruzione PAUSE in tutti i loop di attesa di spin.
I prefissi che non si applicano a un’istruzione vengono ignorati. Tuttavia, le future CPU possono usare quella sequenza di byte per codificare una nuova istruzione. (sì, lo spazio per l’opcode x86 è così limitato da fare cose pazzesche come questa, e sì rende complicati i decodificatori).
In questo caso, significa che è ansible utilizzare la pause
in spinloops senza rompere indietro compat . Le vecchie CPU che non conoscono la pause
la decodificheranno come un NOP senza danni. Sulle nuove CPU, si ottiene il vantaggio della semplicità di risparmio energetico / HT e si evita la speculazione errata della memoria quando la memoria su cui si sta ruotando cambia e si esce dal ciclo di rotazione.
Collegamenti ai manuali di Intel e tonnellate di altre cose buone nella pagina delle informazioni del wiki dei tag x86: https://stackoverflow.com/tags/x86/info
Un altro caso di un prefisso di rep
senza significato che diventa una nuova istruzione su nuove CPU: lzcnt
è F3 0F BD /r
. Sulle CPU che non supportano tale istruzione (manca il flag della funzione LZCNT nel proprio CPUID), decodifica come rep bsr
, che funziona come bsr
. Quindi su vecchie CPU, produce 32 - expected_result
, e non è definito quando l’input era zero.
Un caso di prefisso di una rep
priva di significato che probabilmente non decodificherà mai in modo diverso: rep ret
è usato di default da gcc quando prende di mira CPU “generiche” (cioè non si rivolge a una CPU specifica con -march
o -mtune
, e non si -mtune
a AMD K8 o K10. Ci vorranno decenni prima che qualcuno possa creare una CPU che decodifica il rep ret
di qualsiasi altra cosa che non sia ret
, perché è presente nella maggior parte dei binari nella maggior parte delle distribuzioni Linux. Vedi cosa significa “rep ret”?