2 minute read

Section vs Segment

linking vs exec view Section과 Segment의 차이부터 알아보자. 위 이미지에서 알 수 있듯이 Section은 Linking view에 속하는데 linker는

IA-32 Address System

IA32 address system
IA-32에서 메모리 관리를 segmentation & paging 두 부분으로 나눈다. 사진을 보면 CPU와 물리메모리 사이에서 두번의 주소변환이 일어나는데 CPU는 논리주소(logical address)를, segmentation 장치는 선형주소(linear address)를, paging 장치는 물리주소(physical address)를 반환한다.
여기서 CPU와 segmentation unit 간의 관계만 보겠다.
Segmentation Model
Pasted Graphic
논리주소는 (selector, offset) 쌍으로 구성된다. selector(16bit)는 세그먼트의 번호로 Description Table에서(아직은 몰라도 좋다) 세그먼트의 기본주소를 구할 수 있고, offset(32bit)을 더해서 선형주소를 계산할 수 있다. 이때 주소가 세그먼트가 가질 수 있는 주소의 한계치를 넘기면 오류가 발생한다.
IA-32에는 세그먼트를 가리킬 수 있는 6개의 세그먼트 레지스터가 있다. 즉 프로세스가 한 순간에 6개의 세그먼트를 가리키 수 있다는 뜻이다. 6개의 세그먼트 종류를 Stack, Data, Code Segment로 나눌 수 있다.

Segment Type

Segment Registers

1. Code Segment

Code Segment는 메모리에서 명령어가 저장된 부분이다. 그래서 프로세서는 명령어를 CS register와 EIP를 통해 실제 메모리 주소에서 불러온다. 참고로 이때 EIP는 CS와 다음 명령어의 주소간의 offset을 가지고 있다. 또한 CS register는 application program이 불러오는 것이 아닌 명령어나 내부 프로세서의 작업(procedure call, interrupt handling, task switching)으로 불러온다.

2. Data Segment

DS, ES, FS, GS register는 모두 Data Segment를 가리킨다. DS가 네개나 있는 이유는 자료구조를 효율적이고 안전하게 관리하기 위함이다. 예를 들어 DS reg는 현재모듈의 자료구조, ES reg는 상위모듈에서 들어오는 데이터, FS는 유동적으로 사용, GS는 다른 프로그램과 공유하는 용도 처럼 필요에 따라 다르게 DS를 사용할 수 있다.

3. Stack Segment

program, task, 실행되는 handler의 프로시저 스택이 저장되는 부분이다. 모든 stack operation(pull, push, etc.)는 Stack Segment를 참조한다. 또한 CS와 달리 application program이 SS를 불러올 수 있고 프로그램이 스택을 설정, 변경할 수 있다.
이후 시간이 되면 페이징까지 붙여서 설명하겠다.

Linux System

linux segment 사진은 아래가 낮은 주소, 위에가 높은 주소이다. Linux에서는 Segment를 5부분으로 나눈다.

Code Segment(Text Segment)

Code Segment는 말그대로 Code가 존재하는 구역이며 당연히 Readable, Executable하고 공격을 방지하기 위해 Writable하지 않다.

Data Segment

컴파일 시점에 값이 정해진 전역변수, 전역상수가 위치한다. 이때 Readable하다. Data segment는 Writeable, Non-Writeable 두 구역으로 나눈다.

Writeable Data Segment

전역변수가 위치하는 구역이다.

Non-Writeable Data Segment(.rodata)

전역상수가 위치하는 구역이다. read-only data구역이라 rodata구역이라 한다.

char *str_ptr="readonly";

이 코드에서 str_ptr은 전역변수로 data segment에 위치하지만 “readonly”는 전역상수로 rodata에 저장된다.

BSS(Block Started by Symbol) Segment

컴파일 시점에 값이 정해지지 않은 전역변수가 위치하는 구역. 초기화될 때 0으로 모두 초기화된다. 따라서 컴파일시 값을 정하지 않은 변수는 0으로 초기화된다.
BSS는 Readable, Writable하다.

Stack Segment

프로세스의 스택이 위치하는 구역. 함수의 인자(parameter)나 지역변수와 같은 임시변수가 저장된다. 따라서 스택은 동적 할당이 가능하다는 특징이 있다. 스택은 스택프레임 단위로 사용되는데 $rsp에서 $rbp까지로 스택프레임의 범위를 저장한다. 컴파일 전에는 스택에서 사용될 변수의 크기를 알 수 없기 때문에 컴파일시 작은 단위의 스택 세그먼트부터 먼저 저장한다. 스택이 아래로 자란다는 것은 스택이 계속 낮은 주소로 확장하기 때문이다. Stack은 readable, writable하다.

Heap Segment

스택과 마찬가지로 동적할당이 가능하다. 하지만 스택과 반대로 낮은 주소에서 높은 주소로 자란다. malloc(), calloc()에서 할당하는 메모리가 heap에 위치한다. Heap은 보통 readable, writable하다.

Categories:

Updated: