Hello Everyone,
I'm using a Windows 11 operating system and have installed the GCC compiler on my laptop. I've written a C program that successfully compiles and runs. However, I'm trying to gain a better understanding of how variables are stored in the memory of my laptop and the compiler's role in this process. Terms like 'compile time,' 'run time,' 'static memory allocation,' and 'dynamic memory allocation' are confusing to me.
I've attached my C code along with the generated assembly output.
Program Output
Assembly output
Memory layout categories:
Text Segment:
Read-only.
Contains CPU-executable machine code instructions.
Data Segment:
Initialized Data: Holds initialized global/static variables.
Uninitialized Data: Stores uninitialized global/static variables.
Stack:
Stores local variables
Heap:
Utilized for dynamic memory allocation.
My understanding is that laptop processor reads binary instructions from program memory to perform tasks. Program memory stores the instructions that make up a program, and these instructions guide the processor in executing specific tasks.
https://www.geeksforgeeks.org/difference-between-static-and-dynamic-memory-allocation-in-c/ link mention that static memory is allocated at compile time
So, when we mention memory allocation at compile-time, run time what exactly does that mean? My confusion arises from the fact that during compilation, the program isn't actually executed on hardware. So, I'm trying to undrstand how memory allocation can occur at compile time when there's no physical execution of the program?
I'm using a Windows 11 operating system and have installed the GCC compiler on my laptop. I've written a C program that successfully compiles and runs. However, I'm trying to gain a better understanding of how variables are stored in the memory of my laptop and the compiler's role in this process. Terms like 'compile time,' 'run time,' 'static memory allocation,' and 'dynamic memory allocation' are confusing to me.
I've attached my C code along with the generated assembly output.
C:
#include <stdio.h>
#include <stdlib.h>
/* Global initialized variable in the Data Segment */
int global_initialized_var = 42;
/* Global uninitialized variable in the Data Segment (BSS) */
int global_uninitialized_var;
/* Static variable in the Data Segment */
static int static_var = 30;
void stack_example() {
/* Local variable in the Stack */
int local_var = 10;
printf("Local Variable in Stack: %d\n", local_var);
}
int main() {
/* Text Segment: CPU-executable code */
printf("Hello from the Text Segment!\n");
/* Accessing Initialized Data in Data Segment */
printf("Initialized Global Variable: %d\n", global_initialized_var);
/* Accessing Uninitialized Data in Data Segment (BSS) */
printf("Uninitialized Global Variable: %d\n", global_uninitialized_var);
/* Accessing Static Data in Data Segment */
printf("Static Global Variable: %d\n", static_var);
/* Calling a function to demonstrate Stack usage */
stack_example();
/* Dynamic memory allocation in the Heap */
int *dynamic_var = (int *)malloc(sizeof(int));
*dynamic_var = 20;
printf("Dynamic Variable in Heap: %d\n", *dynamic_var);
free(dynamic_var);
return 0;
}
Code:
Hello from the Text Segment!
Initialized Global Variable: 42
Uninitialized Global Variable: 0
Static Global Variable: 30
Local Variable in Stack: 10
Dynamic Variable in Heap: 20
C:
.file "hello.c"
.globl _global_initialized_var
.data
.align 4
_global_initialized_var:
.long 42
.comm _global_uninitialized_var, 4, 2
.align 4
_static_var:
.long 30
.section .rdata,"dr"
LC0:
.ascii "Local Variable in Stack: %d\12\0"
.text
.globl _stack_example
.def _stack_example; .scl 2; .type 32; .endef
_stack_example:
LFB14:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $40, %esp
movl $10, -12(%ebp)
movl -12(%ebp), %eax
movl %eax, 4(%esp)
movl $LC0, (%esp)
call _printf
nop
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE14:
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC1:
.ascii "Hello from the Text Segment!\0"
.align 4
LC2:
.ascii "Initialized Global Variable: %d\12\0"
.align 4
LC3:
.ascii "Uninitialized Global Variable: %d\12\0"
LC4:
.ascii "Static Global Variable: %d\12\0"
LC5:
.ascii "Dynamic Variable in Heap: %d\12\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB15:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $32, %esp
call ___main
movl $LC1, (%esp)
call _puts
movl _global_initialized_var, %eax
movl %eax, 4(%esp)
movl $LC2, (%esp)
call _printf
movl _global_uninitialized_var, %eax
movl %eax, 4(%esp)
movl $LC3, (%esp)
call _printf
movl _static_var, %eax
movl %eax, 4(%esp)
movl $LC4, (%esp)
call _printf
call _stack_example
movl $4, (%esp)
call _malloc
movl %eax, 28(%esp)
movl 28(%esp), %eax
movl $20, (%eax)
movl 28(%esp), %eax
movl (%eax), %eax
movl %eax, 4(%esp)
movl $LC5, (%esp)
call _printf
movl 28(%esp), %eax
movl %eax, (%esp)
call _free
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE15:
.ident "GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"
.def _printf; .scl 2; .type 32; .endef
.def _puts; .scl 2; .type 32; .endef
.def _malloc; .scl 2; .type 32; .endef
.def _free; .scl 2; .type 32; .endef
Text Segment:
Read-only.
Contains CPU-executable machine code instructions.
Data Segment:
Initialized Data: Holds initialized global/static variables.
Uninitialized Data: Stores uninitialized global/static variables.
Stack:
Stores local variables
Heap:
Utilized for dynamic memory allocation.
My understanding is that laptop processor reads binary instructions from program memory to perform tasks. Program memory stores the instructions that make up a program, and these instructions guide the processor in executing specific tasks.
https://www.geeksforgeeks.org/difference-between-static-and-dynamic-memory-allocation-in-c/ link mention that static memory is allocated at compile time
So, when we mention memory allocation at compile-time, run time what exactly does that mean? My confusion arises from the fact that during compilation, the program isn't actually executed on hardware. So, I'm trying to undrstand how memory allocation can occur at compile time when there's no physical execution of the program?
Last edited:

