2016-12-24 2 views
1

La fonction simple (x86-64, -O2):Pourquoi gcc conserve-t-il un registre de sauvegarde d'appel en cours de lecture?

__attribute__((noinline,noclone,pure)) 
uint foo() { 
    register const uint* _reg asm ("r15"); 
    return *_reg; 
} 

La sortie assembleur pour cette fonction:

push r15  
mov  eax, [r15]  
pop  r15  
retn 

Pourquoi pop inutiles/instructions sont insérées pousse?

+5

Notez que ce que vous faites ici est [explicitement non supporté selon la documentation de GCC] (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables). –

+0

En outre, c'est une des raisons pour lesquelles asm est mal. – rubenvb

Répondre

1

Bonne question, et je n'ai pas la moindre idée, mais peut-être que le compilateur voit seulement dans votre déclaration que vous allez utiliser r15, l'enregistre à l'entrée de la fonction et le restaure avant la sortie de fonction. Le compilateur ne voit pas que vous lisez seulement le registre.

Le compilateur devrait être étendu avec la logique pour suivre si le registre est en cours d'écriture pour décider si le registre doit être enregistré ou non, une logique qui n'est pas triviale, pour sécuriser seulement deux instructions.