¿Hay alguna optimización sustancial al omitir el puntero del marco? Si lo he entendido correctamente al leer la página this, se usa cuando queremos evitar guardar, configurar y restaurar punteros de cuadros.¿Cuándo debería omitir el puntero de marco?
¿Se hace esto sólo para cada llamada a la función y si es así, ¿es realmente vale la pena para evitar unas pocas instrucciones para cada función? ¿No es trivial para una optimización? ¿Cuáles son las implicaciones reales de usar esta opción aparte de las limitaciones de depuración?
compilé el siguiente código C con y sin esta opción
int main(void)
{
int i;
i = myf(1, 2);
}
int myf(int a, int b)
{
return a + b;
}
,
# gcc -S -fomit-frame-pointer code.c -o withoutfp.s
# gcc -S code.c -o withfp.s
.
diff -u
'ing los dos archivos reveló el siguiente código de montaje:
--- withfp.s 2009-12-22 00:03:59.000000000 +0000
+++ withoutfp.s 2009-12-22 00:04:17.000000000 +0000
@@ -7,17 +7,14 @@
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
- pushl %ebp
- movl %esp, %ebp
pushl %ecx
- subl $36, %esp
+ subl $24, %esp
movl $2, 4(%esp)
movl $1, (%esp)
call myf
- movl %eax, -8(%ebp)
- addl $36, %esp
+ movl %eax, 20(%esp)
+ addl $24, %esp
popl %ecx
- popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
@@ -25,11 +22,8 @@
.globl myf
.type myf, @function
myf:
- pushl %ebp
- movl %esp, %ebp
- movl 12(%ebp), %eax
- addl 8(%ebp), %eax
- popl %ebp
+ movl 8(%esp), %eax
+ addl 4(%esp), %eax
ret
.size myf, .-myf
.ident "GCC: (GNU) 4.2.1 20070719
Podría alguien arrojar luz sobre los clave puntos del código anterior, donde -fomit-frame-pointer no realmente hacer la diferencia ?
Editar:objdump
's de salida sustituido por gcc -S
' s
Pruebe nuevamente la diferencia compilando con -S. Compare el lenguaje ensamblador: será mucho más legible. –
@Richard: ¡Hecho! ¡Gracias por mencionarlo! – PetrosB
Relacionados, vea [ARM: registro de enlace y puntero de marco] (http://stackoverflow.com/q/15752188). – jww