Sei sulla pagina 1di 2

Los humanos retienen el conocimiento en su memoria, similar

a lo que hace un ordenador. Los ordenadores almacenan en


la memoria todos los programas mientras se ejecutan y luego, un análisis
de memoria es esencial para comprender cómo funcionan
los programas cuando el código no está disponible. La estructura
de la memoria de un programa en C se representa aquí. La memoria
se divide en segmentos que tienen diferentes propósitos.
En este curso, cuando presentamos una imagen de memoria, asumiremos
que las direcciones de memoria altas están en la parte superior
y las direcciones de memoria baja en la parte inferior. Pero,
esto es solo una convención. En la parte superior, se ubican
las variables de entorno y los argumentos. Luego, se coloca la
pila. Aunque explicaremos este elemento en detalle más adelante,
ahora digamos que es un espacio variable que crece de direcciones
altas a direcciones bajas. El siguiente segmento se corresponde
con el montículo, que crece en la dirección opuesta a la pila
(de direcciones bajas a las altas). Otro segmento se llama
.bss en el que se almacenan todas las variables no inicializadas.
Por el contrario, el segmento .data almacena las variables inicializadas.
Finalmente, en el último segmento, .text, se almacenan las
instrucciones del programa y sus constantes. En otras palabras,
en este último segmento se encuentra el código a ejecutar.
Solo como un breve resumen, describamos el papel de la
pila y el montículo. La pila es, de hecho, una parte muy importante,
de gran ayuda en el proceso de ingeniería inversa. La pila se encarga
de almacenar variables de tamaño limitado. Además, cada
vez que un programa cambia de una función a otra, usa la pila
para guardar valores importantes, como explicaremos más
adelante. Por otro lado, el montículo almacena variables dinámicas,
es decir, aquellas variables cuyos tamaños deben reservarse.
Con esto en mente, hay que resaltar la importancia de la pila
y el montículo, como las partes más relevantes de la
memoria de un ordenador para realizar ingeniería inversa.
Aquí podemos identificar algunos pequeños programas en C que manejan
variables inicializadas y no inicializadas. En el primer ejemplo,
a la izquierda, las variables "var" y "a" se inicializan y, por lo
tanto, se almacenan en el segmento .data. Por el contrario,
el ejemplo de la derecha muestra las variables "buf" y "b" que
no se inicializan y se ubican en el segmento .bss. Ahora
se presenta el ejemplo que involucra al montículo. En este
caso, la variable "var" reserva memoria para n caracteres.
Como es una reserva dinámica de la memoria de almacenamiento
dinámico, no podemos olvidar liberar esa memoria, es decir, llamar
a la función free, de lo contrario, la memoria en el almacenamiento
dinámico permanecerá reservada y puede producir problemas
en algún momento. Ahora es el turno de la pila. Aquí se proporciona
una breve descripción general. En la pila se llevan a cabo
dos operaciones principales, PUSH y POP. La operación PUSH consiste
en almacenar algo en la pila, mientras que la operación POP
hace lo contrario. Nuevamente, es importante identificar la dirección
de crecimiento de la pila. PUSH coloca elementos en la parte
superior de la pila, mientras que POP recupera elementos también
desde la parte superior. Si hacemos PUSH de los elementos 1,
2, 3 y 4, se ubican en orden inverso, es decir, el elemento 1
se ubica en las direcciones de memoria más altas y 4
en las direcciones más bajas. Como resultado, el comportamiento
de la pila sigue la estrategia LIFO, Last In First Out,
el último que llega es el primero en salir.
Aquí tenemos un ejemplo de un pequeño código que realiza
una suma de un par de números. Como se llama a la función
"sumar", los argumentos de esta función se almacenan en la pila
para posteriormente realizar la operación de suma. Pero, cuando
se ejecutan los programas, ¿cómo funciona la pila? ¡Lo aprenderás
en el siguiente video!

Potrebbero piacerti anche