2011-01-09 10 views
5

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

+3

Perché passare i parametri nei registri è una cosa negativa? –

+0

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

+0

Quale architettura/ABI? – ephemient

risposta

0

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é:

  1. Perché vuoi? La tua funzione non potrebbe essere richiamabile in forma compilata da altre funzioni, creando un disordine di compatibilità.
  2. Le chiamate alle funzioni di sistema conformi all'ABI non funzionerebbero, a meno che il compilatore non fosse in grado di distinguere tra convenzioni di chiamata. Ora, so che in passato ci sono diverse convenzioni di chiamata per x86-32, ma nota come x64 è più semplice (AMD64 rispetto a quello che Microsoft ha fatto). Perché, quando si progetta il ARM calling convention, si consente così tante convenzioni di chiamata diverse? Crea un pasticcio di compatibilità.
+1

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

+1

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. –

+0

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

1

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; 
} 
+0

Bel trucco! La prima soluzione è solo C++, ho dimenticato di menzionare che avevo bisogno di una soluzione C. Grazie. – cojocar

+1

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. –

0

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.

+0

Non sono sicuro che si tratti o meno della domanda ... – Nanomurf

Problemi correlati