Los programadores pueden tener preguntas sobre los marcos de la pila no en un término amplio (que es una entidad simple en la pila que sirve solo una llamada de función y mantiene la dirección de retorno, los argumentos y las variables locales), pero en un sentido estricto, cuando el término stack frames
se menciona en contexto de las opciones del compilador.
Si el autor de la pregunta lo ha querido decir o no, pero el concepto de un marco de pila desde el aspecto de las opciones del compilador es un tema muy importante, no cubierto por las otras respuestas aquí.
Por ejemplo, el compilador C / C ++ de Microsoft Visual Studio 2015 tiene la siguiente opción relacionada con stack frames
:
- / Oy (omisión de puntero de marco)
GCC tiene lo siguiente:
- -fomit-frame-pointer (No mantenga el puntero de cuadro en un registro para funciones que no lo necesitan. Esto evita las instrucciones para guardar, configurar y restaurar punteros de cuadro; también hace que un registro adicional esté disponible en muchas funciones )
El compilador Intel C ++ tiene lo siguiente:
- -fomit-frame-pointer (Determina si EBP se usa como un registro de propósito general en optimizaciones)
que tiene el siguiente alias:
Delphi tiene la siguiente opción de línea de comandos:
- - $ W + (Generar marcos de pila)
En ese sentido específico, desde la perspectiva del compilador, un marco de pila es solo el código de entrada y salida para la rutina , que empuja un ancla a la pila, que también se puede usar para la depuración y para el manejo de excepciones. Las herramientas de depuración pueden escanear los datos de la pila y usar estos anclajes para retroceder, mientras se ubican call sites
en la pila, es decir, para mostrar los nombres de las funciones en el orden en que se han llamado jerárquicamente. Para la arquitectura Intel, es push ebp; mov ebp, esp
o enter
para entrada y / mov esp, ebp; pop ebp
o leave
salida.
Es por eso que es muy importante comprender para un programador en qué consiste un marco de pila cuando se trata de opciones del compilador, porque el compilador puede controlar si generar este código o no.
En algunos casos, el compilador puede omitir el marco de la pila (código de entrada y salida para la rutina), y se puede acceder directamente a las variables a través del puntero de la pila (SP / ESP / RSP) en lugar del conveniente puntero base (BP / ESP / RSP). Condiciones para la omisión del marco de la pila, por ejemplo:
- la función es una función hoja (es decir, una entidad final que no llama a otras funciones);
- no hay intentos / finalmente o intentos / excepto o construcciones similares, es decir, no se utilizan excepciones;
- no se llaman rutinas con parámetros salientes en la pila;
- la función no tiene parámetros;
- la función no tiene código de ensamblaje en línea;
- etc ...
Omitir marcos de pila (código de entrada y salida para la rutina) puede hacer que el código sea más pequeño y más rápido, pero también puede afectar negativamente la capacidad de los depuradores para rastrear los datos en la pila y mostrarlos al programador. Estas son las opciones del compilador que determinan en qué condiciones una función debe tener el código de entrada y salida, por ejemplo: (a) siempre, (b) nunca, (c) cuando sea necesario (especificando las condiciones).