printf(" a -> %x\n", &a); 결과가 가상주소?
다음은 제가 나름대로 이것저것 참고하여 정리한 내용입니다.
<가상메모리 공간 구조>
(1) user 영역 (0x00000000 ~ 0xbfffffff) (3GByte)
1) Text segment (0x00000000 ~ 0x00002fff) (12KByte)
CPU에 의해 실행되는 머신 코드들이 있는 영역.Read Only
2) data segment (0x00003000 ~ 0x00004fff) (16KByte)
전역변수와 static 변수가 저장되는 영역.
- Initalized data segment
data segment 라 불리는 영역이며,
초기화된 외부 변수 static 변수등이 저장되는 영역입니다.
예) static int a = 1;
- Uninitalized data segment : bss segment 라고 불리며,
이 영역을 프로그램이 실행될때 0 이나 NULL Pointer로
초기화 됩니다.
예) static int a; (외부 변수나, static 변수중
초기화 되지 않은 변수들)
3) Heap & Stack (0x00005000 ~ 0xbfffffff) (3GB - 28KB)
- Heap (0x00005000 부터 시작됨. )
동적 메모리 할당을 할경우 이곳에 할당이 됨(malloc)
Heap 영역은 uninitialzed data 영역의 top 과 stack 영역의
bottom 부분에 위치합니다.
- Stack (0xbfffffff 부터 시작됨. 변수가 선언될때마다 주소 감소)
함수 안의 auto변수(함수내 지역변수) 등이 저장되는 곳.
함수가 실행되는 동안에만 존재하며 함수의 실행이 종료되면
그 변수들도 사라집니다.
(2) kernel 영역 (0xc0000000 ~ 0xffffffff)(1GB)
------------------------------------------------------------
#include<stdio.h>
static int a, b, c; //uninitial data영역 (bss 영역)
void main()
{
static int l, m, n; //uninitial data 영역(bss 영역)
static int p=0, q=0, r=0; // initial data 영역(data 영역)
int i, j, k; //stack 영역 (유일하게 주소가 감소)
//전역변수
printf("\n 전역변수 \n");
printf(" a -> %x\n", &a);
printf(" b -> %x\n", &b);
printf(" c -> %x\n", &c);
//static 변수 (uninitial)
printf("\n static 변수 (uninitial) \n");
printf(" l -> %x\n", &l);
printf(" m -> %x\n", &m);
printf(" n -> %x\n", &n);
//static 변수 (initial)
printf("\n static 변수 (initial) \n");
printf(" p -> %x\n", &p);
printf(" q -> %x\n", &q);
printf(" r -> %x\n", &r);
//지역변수
printf("\n 지역변수 \n");
printf(" i -> %x\n", &i);
printf(" j -> %x\n", &j);
printf(" k -> %x\n", &k);
}
/*
<결과값>
전역변수
a -> 4237d0
b -> 4237d4
c -> 4237d8
static 변수 (uninitial)
l -> 4237e0
m -> 4237cc
n -> 4237dc
static 변수 (initial)
p -> 4237e4
q -> 4237e8
r -> 4237ec
지역변수
i -> 12ff7c
j -> 12ff78
k -> 12ff74
*/
-------> 의문
1. 결과값에 나온 위의 주소가 가상주소일까요?
2. 가상주소라면 전역변수와 static변수는 0x00003000~0x00004fff 사이의 주소이어야 할텐데...
어떻게 된 것인지 알고싶습니다.
이런 것을 알려면 어떤 자료를 찾아봐야하나요...
가상 주소 맞습니다..
가상 주소가 맞는데요
data 영역이나 bss 영역의 위치는 그렇게 고정된 것이 아니고
실제 데이터의 크기에 따라 변합니다.
printf 에서 포인터를 출력할 때는 %p 를 사용하는게 더 좋지만
nm 으로 심볼의 주소와 타입를 쉽게 볼 수 있습니다.
더 자세한 내용은 링커와 로더 쪽 자료를 찾아보세요..
댓글 달기