2010-04-26 10 views
7

GCC documentazione afferma in 6.30 Declaring Attributes of Functions:Utilizzando l'attributo "nudo" per funzioni in GCC

naked

Utilizzare questo attributo ARM, porti AVR, IP2K, RX e SPU per indicare che il specificata la funzione non ha bisogno di sequenze prologo/epilogo generate dal compilatore. Spetta al programmatore fornire queste sequenze. Le sole affermazioni che possono essere tranquillamente incluse in funzioni nude sono le istruzioni asm che non hanno operandi. Tutte le altre dichiarazioni, incluse le dichiarazioni delle variabili locali, le istruzioni if e così via, devono essere evitate. Le funzioni nude dovrebbero essere utilizzate per implementare il corpo di una funzione di assemblaggio, consentendo al compilatore di costruire la dichiarazione di funzione richiesta per l'assemblatore.

Posso chiamare in modo sicuro le funzioni utilizzando la sintassi C da funzioni nude o solo usando asm?

risposta

4

Se l'unica cosa che si fa nella funzione naked è chiamare un'altra funzione, è sufficiente utilizzare una singola istruzione di codice macchina JMP.

La funzione a cui si punta avrà un prologo valido e dovrebbe tornare direttamente al chiamante della funzione nuda poiché JMP non invia un indirizzo di ritorno nello stack.

+1

Ho fatto la mia domanda, perché nella fonte di FreeRTOS per AVR ho visto il seguente void vPortYield (void) __attribute__ ((naked)); void vPortYield (void) { \t portSAVE_CONTEXT(); \t vTaskSwitchContext(); \t portRESTORE_CONTEXT(); \t asm volatile ("ret"); } portSAVE_CONTEXT() e portRESTORE_CONTEXT() sono macrose con asm ma vTaskSwitchContext è una funzione. –

+2

Questa risposta non è corretta. Puoi fare qualsiasi cosa in una funzione nuda che faresti da qualsiasi altra parte purché tu realizzi l'ABI: questo significa che devi conoscere, capire ed essere in grado di prevedere in modo affidabile l'ABI che stai usando. Inoltre, la documentazione non è corretta, perché è possibile accedere in modo sicuro alle variabili globali dall'istruzione asm senza effetti collaterali indesiderati, ma se lo si deve inserire "memoria" nei clobbers. –

0

Le sole affermazioni che possono essere tranquillamente incluse nelle funzioni nude sono istruzioni asm che non hanno operandi. Tutte le altre dichiarazioni, comprese le dichiarazioni delle variabili locali, se le dichiarazioni e così via, dovrebbero essere evitate.

In base alla descrizione che hai già dato, suppongo che anche le chiamate di funzione non siano adatte alla parola chiave "naked".

5

È possibile chiamare in modo sicuro funzioni da una funzione nuda, a condizione che le funzioni chiamate abbiano un prologo completo ed un epilogo.

Si noti che è un po 'assurdo affermare che è possibile "tranquillamente" utilizzare il linguaggio assembly in una funzione nuda. Sei completamente responsabile per qualsiasi cosa tu usi il linguaggio assembly, così come lo sei per ogni chiamata che fai a funzioni 'sicure'.

Per garantire che la funzione chiamata generica non sia statica o in linea, dovrebbe essere in un'unità di compilazione separata.

Le funzioni "nude" non includono alcun prologo o epilogo: sono nudi. In particolare, non includono le operazioni sullo stack per le variabili locali, per salvare o ripristinare i registri o per tornare a una funzione di chiamata.

Ciò non significa che nessuno stack esiste: lo stack viene inizializzato nell'inizializzazione del programma, non in qualsiasi inizializzazione di funzione. Poiché esiste uno stack, i cosiddetti prologhi delle funzioni e gli epiloghi funzionano correttamente. Una chiamata di funzione può tranquillamente inviare il suo indirizzo di ritorno, tutti i registri utilizzati e lo spazio per eventuali variabili locali. Al ritorno (usando l'indirizzo di ritorno), i registri vengono ripristinati e lo spazio di stack viene rilasciato.

Le funzioni statiche o inline possono non avere un prologo completo ed un epilogo. Possono e possono dipendere dalla funzione chiamante per gestire lo stack e ripristinare i registri danneggiati.

Questo porta al punto successivo: è necessario il prologo e l'epilogo solo per incapsulare le operazioni della funzione chiamata.Se la funzione chiamata è anche sicura (nessuna variabile locale esplicita o implicita, nessuna modifica ai registri di stato), può essere statica e/o in linea sicura. Come con asm, sarebbe tua responsabilità assicurarti che sia vero.

Problemi correlati