Estoy tratando de entender cómo se construyen los marcos de pila y qué variables (parámetros) se empujan para apilarse en qué orden. Algunos resultados de búsqueda mostraron que el compilador C / C ++ decide en función de las operaciones realizadas dentro de una función. Por ejemplo, si se suponía que la función incrementaba un valor int pasado por 1 (similar al operador ++) y lo devolvía, colocaría todos los parámetros de la función y las variables locales en registros.
Me pregunto qué registros se utilizan para los parámetros devueltos o pasados por valor. ¿Cómo se devuelven las referencias? ¿Cómo elige el compilador entre eax, ebx, ecx y edx?
¿Qué necesito saber para entender cómo se usan, crean y destruyen los registros, las referencias de pila y montón durante las llamadas a funciones?
Respuestas:
Además de lo que dijo Dirk, un uso importante de los marcos de pila es guardar los valores anteriores de los registros para que puedan restaurarse después de una llamada a la función. Entonces, incluso en los procesadores donde los registros se usan para pasar parámetros, devolver un valor y guardar la dirección de retorno, los valores de esos registros se guardan en la pila antes de una llamada de función para que puedan restaurarse después de la llamada. Esto permite que una función llame a otra sin sobrescribir sus propios parámetros u olvidar su propia dirección de retorno.
Entonces, llamar a una función B desde la función A en un sistema "genérico" típico podría implicar los siguientes pasos:
Esta no es la única forma en que las llamadas a funciones pueden funcionar (y puedo tener uno o dos pasos fuera de servicio), pero debería darle una idea de cómo se usa la pila para permitir que el procesador maneje las llamadas a funciones anidadas.
fuente
push
ypop
son las dos operaciones fundamentales en una pila. Una pila es una estructura de último en entrar, primero en salir, como una pila de libros. Cuando túpush
, estás poniendo un nuevo objeto encima de la pila; cuandopop
estás tomando un objeto desde la parte superior de la pila. No está permitido insertar o eliminar objetos en el medio, solo puede operar en la parte superior de la pila. Puede leer más sobre las pilas en general y la pila de programas en particular en Wikipedia.Esto depende de la convención de llamada utilizada. Quien defina la convención de convocatoria puede tomar esta decisión como quiera.
En la convención de llamadas más común en x86, los registros no se utilizan para pasar parámetros; los parámetros se envían a la pila comenzando con el parámetro más a la derecha. El valor de retorno se coloca en eax y puede usar edx si necesita espacio adicional. Las referencias y los punteros se devuelven en forma de una dirección en eax.
fuente
Si comprende muy bien la pila, comprenderá cómo funciona la memoria en el programa y si comprende cómo funciona la memoria en el programa, comprenderá cómo funciona la función almacenar en el programa y si comprende cómo funciona la función almacenar en el programa, comprenderá cómo funciona la función recursiva y si comprende cómo funciona la función recursiva, comprenderá cómo funciona el compilador y si comprende cómo funciona, su mente funcionará como compilador y depurará cualquier programa muy fácilmente
Déjame explicarte cómo funciona la pila:
Primero debes saber cómo funciona la función almacenar en la pila:
Almacenamiento dinámico de valores de asignación de memoria dinámica. Pila de almacenamiento automático de asignación y eliminación de valores.
Vamos a entender con el ejemplo:
Ahora entienda partes de este programa:
Ahora veamos qué es la pila y qué son las partes de la pila:
Recuerde una cosa si alguna función obtiene "retorno" sin importar que haya cargado todas sus variables locales o cualquier cosa que regrese inmediatamente de la pila a su marco de pila. Significa que cuando cualquier función recursiva obtiene la condición base y colocamos el retorno después de la condición base para que la condición base no espere a cargar las variables locales que están situadas en la parte "else" del programa, inmediatamente devolverá el cuadro actual de la pila y ahora si un cuadro volver el siguiente cuadro está en el registro de activación Vea esto en la práctica:
Entonces, cada vez que una función encuentra la declaración return, elimina el marco actual de la pila.
mientras regresa del valor de la pila, regresará en orden inverso al orden en que se asignaron en la pila.
Estas son descripciones muy cortas y si quieres saber más sobre la pila y la doble recursión, lee dos publicaciones de este blog:
Más acerca de la pila paso a paso
Más acerca de la doble recursión paso a paso con stack
fuente
Lo que está buscando se llama Application Binary Interface - ABI.
Hay una especificación para cada compilador que detalla el ABI.
Cada plataforma generalmente especificará y ABI para soportar la interoperabilidad entre compiladores. Por ejemplo, las convenciones de llamadas x86 explican las convenciones de llamadas típicas para x86 y x86-64. Sin embargo, esperaría un documento más oficial que wikipedia.
fuente