Newsgroup: it.comp.lang.c
Titolo: Passaggio parametri a ritroso

printf("Stringa %d , %d \n",par1,par2);
La stringa di formato nello stack viene memorizzato per ultima posizione
visto che lo stack utilizza il principio LIFO (last in, firt out)? par2 in
penultima posizione? E par 1 nella prima posizione?
Ma la stringa di formato è il primo parametro che viene passato a printf
.... Quindi utilizzando la tecnica dei passaggi a ritroso non dovrebbe
essere memorizzata nella prima posizione dello stack?
Per cortesia spiegatemi(se volete) un pò cosa è e perchè avviene il
passaggio dei parametri a 'ritroso'.
Grz :-D
_________________________________________________


In alcune implementazioni il passaggio dei parametri avviene per così di 
re 'a ritroso', e la stringa di formato si trova in effetti in cima allo 
stack. Questo perchè la funzione printf() accetta un numero variabile di 
  argomenti, e per scoprire quanti sono essa guarda appunto la stringa 
di formato. Se questa fosse in fondo allo stack, printf() non saprebbe 
reperirla. Invece in questo modo il numero e la posizione dei parametri 
nello stack possono essere ricavati: nel tuo esempio i parametri oltre 
alla stringa sono due int, ed essendo la loro dimensione nota al 
compilatore, la loro posizione è ricavabile.

 compilatore, la loro posizione č ricavabile.
Ti ringrazio ma, la stringa di formato č il primo parametro di printf... non
dovrebbe stare all' inzio dello stack e quindi presa per ultimo rispettando
sempre il principio di LIFO????
Quindi:
printf("Stringa %d , %d \n",par1,par2);
STACK: |STRINGA | INT 1| INT 2|
String si trova nella prima posizione dello stack e quindi non dovrebbe
essere presa per ultima? INT 2 si trova all' ultima posizione dello stack
quindi non dovrebbe essere presa per prima? Il concetto non mi č tanto
chiaro ....
grazie per eventuali risposte

 grazie per eventuali risposte
La stringa di formato č l'ultimo parametro che viene messo sullo stack, 
dopo par2 e par1, ed č il primo che viene guardato da printf(), sempre 
ipotizzando il 'passaggio a ritroso'.


La funzione printf (e tutte o quasi quelle della libreria runtime) hanno una
calling convention di tipo C.
Ovvero:
- il push dei parametri viene fatto da destra a sinistra
- il ripristino dello stack e' a carico del chiamante
mettendo il tutto in pseudo asm, la tua
printf("Stringa %d , %d \n",par1,par2);
verra' tradotta in questo modo:
mov   registro1,stackpointer
push  par2
push  par1
push  "Stringa %d , %d \n"
call  printf
mov   stackpointer,registro1
Ciao,
Stefano

 ha scritto nel messaggio
news:3F311C99...@lombardiacom.it...

Quindi effettuando il cosidetto 'passaggio a ritroso' la stringa di formato
sarŕ l' ultimo parametro a 'depositarsi' per cosě dire nello stack. E poichč
questo ha la caratteristica del principio di LIFO, ovvero l' ultimo
parametro inserito č il primo ad uscire, la stringa sarŕ valutata dal printf
per primo. Questo č perchč printf puň avere un numero variabile di parametri
e per saperne il tipo e di conseguenza la loro posizione si serve della
stringa di formato cioč il parametro 'fisso', all' interno della quale sono
specificate le 'specifiche di conversione'... e sono proprio queste ad
indicare i tipi e quindi la posizione degli altri parametri.
Giusto?

 Giusto?
A parte il fatto che non è necessariamente vero che la funzione debba 
utilizzare per primo l'ultimo parametro posto nello stack, il discorso è 
giusto.

 - il ripristino dello stack e' a carico del chiamante
Questo su una macchina Intel.

 Ad esempio utilizzando la parola chiave pascal?
"pascal" non č una parola chiave in ANSI C, ma č utilizzata da alcuni 
compilatori per forzare il passaggio dei parametri "da sinistra a destra".
Comunque c'č un esempio molto piů semplice:
void funzione(int a, int b)
{
     printf("%d\n", b);
     printf("%d\n", a);
}
Questa funzione usa prima il parametro b che, secondo la calling 
convention di cui tu parli, č il secondo nello stack.

 mov   stackpointer,registro1
ciao

> mov   stackpointer,registro1
Lo fa questa mov, rimette lo  stack pointer dov'era prima delle push. In
questo  modo lo  stack e`  ripristinato. La pop  la usi  solo quando  ti
interessa il contenuto dello stack.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Not an editor command: Wq

 qua mancano i pop di ripristino stack ...
Beh, senza commentare il pseudo-assembly.....
rispondo solo al *tuo* commento:
<QUOTE>
mov   registro1,stackpointer
push  par2
push  par1
push  "Stringa %d , %d \n"
call  printf
mov   stackpointer,registro1
</QUOTE>
come vedi l'ultima istruzione esegue l'equivalente dei pop di ripristino.
Poi spesso e volentieri (la printf e' un caso a parte cmq) i "pop di
ripristino" non li devi vedere nel codice chiamante....
Tommy

 ha scritto nel messaggio
news:bgrs8d$6mu$1...@titan.btinternet.com...
si scusate tutti e due per l'errore di lettura veloce
ciao

 wrote in message
news:3F312AC...@lombardiacom.it...

Si. Ho esperienze dirette solo su macchine Intel, percio' a quelle mi
riferivo
Ciao,
Stefano