C'è un modo per forzare gcc a passare i parametri di una funzione nello stack?Forza gcc per passare i parametri nello stack
Non voglio utilizzare i registri per il passaggio dei parametri.
Aggiornamento: I'am usando braccio-gcc da CodeSourcery
C'è un modo per forzare gcc a passare i parametri di una funzione nello stack?Forza gcc per passare i parametri nello stack
Non voglio utilizzare i registri per il passaggio dei parametri.
Aggiornamento: I'am usando braccio-gcc da CodeSourcery
Secondo: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
primi quattro registri R0-r3 (a1-a4) utilizzate per passare valori degli argomenti in una subroutine e per restituire un valore di risultato da una funzione. Possono anche essere utilizzati per contenere i valori intermedi all'interno di una routine (ma, in generale, solo tra chiamate di subroutine).
Ci sono, su ARM, nessun'altra convenzione di chiamata ma l'impostazione predefinita, che io conosca. Ed ecco perché:
Sì hai ragione. È una cosa strana per questo, specialmente per i motivi che hai menzionato. L'idea è che la funzione definita era il corpo principale di un thread - in un ambiente personalizzato (SO). Il sistema operativo personalizzato spingerebbe l'argomento del thread sullo stack. Per rispettare l'ABI, ci sono due soluzioni alternative: inserire l'argomento in r0 o dichiarare * thread_func (uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3, void * param) *. Grazie! – cojocar
Perché non metterli comunque nei registri? Dovresti conservare i registri attraverso i thread, ma devi comunque - immagina se hai cambiato thread durante l'esecuzione e i valori del registro della vecchia funzione sono stati lasciati sul posto ... se gli OS lo facessero, sarebbe molto caotico. –
Il thread viene creato dallo spazio utente e non vi sono API (syscall) per l'impostazione di un valore di registro per il thread appena creato. – cojocar
Si può provare a racchiudere i parametri in una struttura; per esempio, se la funzione è int calc_my_sum(int x, int y) {return x+y;}
si può cambiare come segue (brutto):
struct my_x_y {
int x, y;
my_x_y(): x(0), y(0) {} // a non-trivial constructor to make the type non-POD
};
int calc_my_sum(my_x_y x_and_y) {
// passing non-POD object by value forces to use the stack
return x_and_y.x + x_and_y.y;
}
In alternativa, si può semplicemente aggiungere 4 parametri fittizi di utilizzare i registri, in modo che altri parametri utilizzerà stack:
struct force_stack_usage {
int dummy0, dummy1, dummy2, dummy3;
}
int calc_my_sum(force_stack_usage, int x, int y) {
return x + y;
}
Bel trucco! La prima soluzione è solo C++, ho dimenticato di menzionare che avevo bisogno di una soluzione C. Grazie. – cojocar
Non è necessario un bizzarro costruttore C++ per ottenere ciò che si desidera. In C le strutture vengono semplicemente copiate nello stack. In C99 puoi anche chiamare la funzione con 'calc_my_sum ((my_x_y) {.x = 5, .y = 7})' o avvolgere una cosa del genere in una macro senza problemi. –
Dove memorizzare una variabile locale dipende da come lo si utilizzerà. Se è necessario ottenere l'indirizzo di una variabile locale, la variabile locale può essere memorizzata solo nello stack. Quindi, quando si passa la subroutine a un puntatore, questo parametro verrà passato attraverso lo stack.
Non sono sicuro che si tratti o meno della domanda ... – Nanomurf
Perché passare i parametri nei registri è una cosa negativa? –
Non è una brutta cosa. Voglio solo che i parametri vengano passati in questo modo perché sto // emulando // una routine di creazione thread (e allocazione stack). – cojocar
Quale architettura/ABI? – ephemient