2012-09-19 14 views
7

Sto lavorando con l'assembly ARM, dove devo scrivere una subroutine per la quale sto seguendo la convenzione di chiamata ARM (questa dovrà essere integrata con qualche implementazione di livello superiore separata da qualche parte altro) per il passaggio di parametri e valori di ritorno. Ora qui è qualcosa che non sono sicuro in generale quando si lavora con l'assemblaggio.Passare parametri e valori di ritorno per una subroutine nell'assieme

Quindi dalla convenzione se capisco bene gli argomenti vengono passati in ordine a partire dai registri r0 - r4 e quindi per altri argomenti vengono utilizzati gli stack. I valori di ritorno sono passati a r0.

Ora, ecco quello di cui sono confuso. Se dovessi salvare il contesto di r0 e spegnerlo dopo, non c'è modo di restituire il risultato, l'unico modo per farlo è corrompere il primo argomento. C'è una soluzione in qualche modo? Grazie in anticipo ragazzi!

risposta

6

Quando si restituisce il valore restituito in r0, il chiamante si aspetta che lo farà. Il chiamante non si aspetta che r0 contenga ancora lo stesso valore del primo parametro originale, perché r0 è specificamente dove si trova il valore di ritorno.

Normalmente il ARM calling convention requires that the subroutine preserves r4 through r11, non da r0 a r3. Quindi non c'è contraddizione in ogni caso.

+0

Quindi immagino che sia responsabilità del chiamante salvare il contesto di r0 prima di chiamare la funzione. – as3rdaccount

+0

Dal link che hai postato: * "da r0 a r3: usato per contenere i valori degli argomenti passati a una subroutine, e anche i risultati restituiti da una subroutine" *. – m0skit0

6

Perché non provarlo e vedere cosa fa il compilatore?

unsigned int fun (unsigned int a, unsigned int b) 
{ 
    return(a+b); 
} 

compilazione di oggetto e smontare

arm-none-eabi-gcc -O2 -c fun.c -o fun.o 
arm-none-eabi-objdump -D fun.o 

e il risultato è

00000000 <fun>: 
    0: e0810000 add r0, r1, r0 
    4: e12fff1e bx lr 

I due ingressi A e B vengono passati utilizzando r0 e r1. r0-r4 non deve essere preservato, in particolare r0 perché è il valore di ritorno che non può essere preservato. Quindi, dato che il codice C richiesto i due operandi vengono sommati, e poiché la convenzione di chiamata richiede che il risultato sia restituito in r0. r0 = r0 + r1.

Il compilatore deve conformarsi alla convenzione altrimenti il ​​codice che produce non funziona, quindi è sufficiente compilare codice e disassemblare per scoprire un po 'della convenzione di chiamata per un particolare compilatore e target.

Problemi correlati