Memory contains the information processed in an application as well as the code of the application itself. Combining these two sets of information yields the state of an application.
Modern computers make use of several different types of memory and caches organized in a hierarchy to enable high performance1). In the context of memory corruption, we focus on CPU registers and Random Access Memory (RAM).
Registers are a small memory region built directly into the CPU. This is the most basic but also fastest type of memory one can access with assembly code. The exact number, sizes and types of registers depend on the processor architecture2).
RAM is often called the „main memory“ of applications. As long as there is enough free RAM available, all runtime data which can not be kept in registers is stored there. Nowadays, applications do not interact directly with physical memory. Instead the operating system provides each application an isolated environment with as much logical memory as the operating system is theoretically able to handle3).
There are two data structures used to organize the main memory of an application. While local variables and execution meta information are located on the stack, dynamically allocated memory is handled by the heap. Without going too much into detail about their implementations at this point, it is important to note the growth direction of both data structures. The heap grows from low memory addresses to high memory addresses. In contrast, the stack grows from high memory addresses to low memory addresses. Using this scheme, a collision of both data structures is avoided until the available memory is exhausted4).
|← Back to information about the author of this tutorial||Overview||Continue with program execution details →|