Quindi sto imparando l'assembly e ho imparato a conoscere ABI e ho ottenuto alcuni test di base lavorando usando la cdecl chiamata convenzione per usare lo stdlib di c in nasm. Ma ho visto altre Convenzioni di chiamata (come il registro di alta velocità / Clarion / JPI / watcom / borland (delphi), fastcall, ecc.). E mi chiedo, quali sono i reali vantaggi dell'uso di cdecl al posto di Clarion. Più specificamente Pushing invece di usare i registri.
Questi sono alcuni dei vantaggi che ho immaginato per favore fammi sapere quale di questi si applica.
-
Ho letto che cdecl è importante perché permette di usare parametri variabili, ma come vedo io, posso fare lo stesso usando i registri. I problemi sono conoscere il conteggio, il tipo e l'ordine dei param, ma quel problema esiste anche su cdecl. Può essere dedotto dalla stringa di formato (in printf) o dalla firma della funzione. E se esaurisco i registri posso spingere il resto dei parametri.
-
Immagino che le prestazioni non dovrebbero essere una grande cosa perché i produttori di cpus potrebbero aver ottimizzato tutto ciò che potevano a prescindere dalla convenzione di chiamata del sindaco (e questa volta è cdecl? ¿?). Ma se penso alle operazioni non elaborate (e ignoro le cache e i buffer di writeback), penso dovrebbe essere più veloce usare i registri invece dello stack (che dovrebbe trovarsi nella ram giusto?). Voglio dire, è come "inc eax" vs "aggiungi eax, 1" (ho ragione?).
-
Premendo i creo uno spazio di memoria che si spegne quando ritorno (proprio come la creazione di una variabile locale). Potrebbe sembrare utile (avere una var locale solo al momento della chiamata).
Ma, dato che la maggior parte dei parametri (nella mia esperienza) sono usati come valore di lettura, e pochissime volte abbiamo bisogno di essi come variabile, per memorizzare valori mutati, e quando lo fai si tratta effettivamente di strutture complesse che vengono passate come puntatori in ogni caso .
Quindi non vedo davvero il valore sulla creazione di uno spazio di memoria PRIMA di averne effettivamente bisogno.Come vedo, se io do ho bisogno di una variabile è meglio avere l'opzione per crearla (come in Clarion), ma se io don ' t sarebbe bello poterlo non crearlo (come non è possibile in cdecl).
-
Conservi i registri.
Non riesco nemmeno a pensare ad un lato positivo. AFAIK i registri sono utilizzati per i calcoli intermedi e, in quanto tali, sono di natura volatile. Se li considero volatili, potrei spingerli / pop / spostarli ogni volta che ho bisogno di "mantenere" il valore e solo in questi casi. In questo senso lo considero l'uso più efficiente (accedo solo alla ram quando ne ho bisogno).
Ma se non lo faccio, prova a "preservare i registri":
-
callee: Non ho la certezza di cosa farà il codice di chiamata con un registro (a meno che non sia documentato o aderisca alla stessa convenzione di chiamata). Sperando che li conservi, impone un limite artificiale al callee. Poiché il destinatario non ha idea di quali registri debbano essere veramente conservati, tenderanno a sovrastimare i registri non necessari. (come pusha / popa in x86?) Quali suoni davvero inefficienti per me.
-
chiamante: il chiamante non ha idea di quali registri useranno il callee [s] taint? [/ s], quindi li conserverà tutti. Finirà con lo stesso risultato inefficiente di prima.
Ho notato che linux syscalls e 8086 (dalle mie vecchie classi) usano i registri invece dello stack per passare i parametri. Che cosa è successo lì?
Quindi quelli sono i miei pensieri, grazie per tutti i chiarimenti possibili.
Note:
- Sto imparando, la maggior parte di questi sono presupposti basati su ciò che ho letto / provato finora. Sarò felice se mi correggerai come necessario (solo essere gentile).
- Capisco che questo sia tutto x86 CC, e in 64 ce n'è un altro (che non ho familiarità con).
- Non sto chiedendo quale sia il "migliore", voglio solo capire di più e chiarire i miei presupposti .
- Sto cercando i vantaggi della convenzione di chiamata da sola (in contrasto con gli altri). non dai suoi effetti collaterali (come i compilatori e la cpus in fase di ottimizzazione o la sua ubiquità)
- Fondamentalmente una domanda teorica per comprendere meglio il motivo per cui è stata scelta questa strada