프로그램 컴파일 과정

변수 종류별 주소 공간
maptest1.c
- gcc의 경우 컴파일시 초기화되지 않은 지역변수는 0으로 초기화 한다.(stack-boundary=32비트 기준)
-
결과
- global_num_1(초기화하지않은 전역 변수)
- .bss
- 0x0804A02C에
00 00 00 00로 저장됨
- global_num_2(초기화한 전역 변수)
- .data
- 0x0804A018에
64 00 00 00으로 저장
- local_num_1(초기화하지 않은 지역 변수)
- stack
- 0xBFFFF384에
00 00 00 00으로 저장
- local_num_2(초기화한 지역변수)
- stack
- 0xBFFFF380에
C8 00 00 00으로 저장
- stack은 높은 주소에서 낮은 주소 방향으로 할당되므로, 변수가 생성될 때 스택의 위쪽(낮은 주소)에 위치한다. (local_num_2의 주소 < local_num_1의 주소)
- static_num_1(초기화하지않은 static 지역 변수)
- .bss
- 0x0804A028에
00 00 00 00으로 저장
- static_num_2(초기화한 static 지역 변수)
- .data
- 0x0804A01C에
00 00 00 00으로 저장
- 문자는 1바이트 크기의 정수값(ASCII 코드)으로 저장되므로,
char charA = 'a';의 경우 메모리에 0x61이 저장된다.
maptest1.c의 .rodata에는 14 ~ 30의 문자열 상수들이 있다.
배열 주소 공간
maptest2.c
-
결과
- global_char_arr_1(초기화하지않은 배열 전역변수)
- global_char_arr_2(초기화한 배열 전역변수)
- local_char_arr_1(초기화하지않은 배열 지역 변수)
- local_char_arr_2(초기화한 배열 지역 변수)
- char 배열,
int g3[5] = {'a', 'b', 'c', 'd', 'e'};의 경우 각 원소는 4바이트 정수로 변환되어 메모리에 0x61 00 00 00, 0x62 00 00 00, 0x63 00 00 00, 0x64 00 00 00, 0x65 00 00 00 형태로 저장된다.
- 정수 배열
int l3[5] = {1, 2, 3, 4, 5};의 경우도 각 정수는 4바이트 크기로 변환되어 0x01 00 00 00, 0x02 00 00 00, 0x03 00 00 00, 0x04 00 00 00, 0x05 00 00 00 형태로 저장된다.
-
문자열 주소 공간 확인 (.rodata)
- “My”, “World” → .data 영역 (직접 초기화 → 변수 따라감)
- 나머지 문자열 상수들 → .rodata
-
배열 전역 변수
- golobal_char_arr_1(초기화하지않은 배열 전역 변수)
- .rodata에 있는 문자열 상수 “Hi” copy
- .global_char_arr_1(0x0804A028)에 “Hi” 복사
- global_char_arr_2(초기화한 배열 전역 변수)
- data영역에 위치(0x0804A028)
- .text에서 읽은 문자열을 .rodata가 아닌 .data에 바로 초기화
-
배열 로컬 변수
- local_char_arr_1 (초기화하지않은 배열 지역 변수)
- .rodata에 있는 문자열 상수 “Array” Copy
- local_char_arr_2(초기화한 배열 지역 변수)
- stack(0xBFFFF377)에 위치
- .text에서 읽은 “World!”를 stack에 바로 초기화
- Little Endian
- 하위 바이트의 값을 작은 번지수에 저장
- 데이터를 저장할 때 역순으로 저장
- 주로 CISC 계열 : Intel, 80x86, AMD
포인터 주소 공간
maptest3.c
-
초기화 하지 않은 포인터 전역 변수
- global_char_ptr_1(초기화 하지 않은 포인터 전역 변수)
- .bss(0x0804A02C)에 위치
- global_char_ptr_1의 값은 NULL로 초기화 된다.(00 00 00 00)
- heap에 3만큼의 메모리 영역 생성(0x0804B008)
- 0x0804A02C에 할당한 메모리 주소(0x0804B008)를 리틀 엔디안으로 넣음
- .rodata에 있는 “Hi”를 global_char_ptr_1(0x0804B008)에 복사함
-
초기화한 포인터 전역 변수
- “My”는 .rodata(0x080486C0)에 위치
- global_char_ptr_2(초기화한 포인터 전역 변수)
- .data(0x0804A020)에 위치
- “My”의 위치(0x080486C0)를 C0 86 04 08(리틀 엔디안)로 저장
-
포인터 로컬변수
- local_char_ptr_1(초기화하지 않은 지역 변수)
- heap에 8 크기의 공간 할당(0x0804B018)
- .rodata에 있는 “Pointer”를 할당한 공간(0x0804B018)에 Copy
- local_char_ptr_2(초기화한 지역 변수)
- .rodata에 있는 “World!”의 주소(0x08486C3)을 local_char_ptr_2(0xBFFFF380)에 리틀 엔디안으로 저장
출처