[OS 개발 6] 레지스터 세그먼트와 오프셋 개념


세그먼트:오프셋 주소 개념과 물리주소 변환 계산하기


레지스터의 종류에는 범용 레지스터, 세그먼트 레지스터, 컨트롤 레지스터 등, 다양한 역할을 담당하고 있는 레지스터들이 있는데, 이번 포스팅에서는 세그먼트 레지스터에 대해서 알아보도록 하겠습니다.

 

세그먼트 레지스터는 처음 인텔이 8086 CPU를 개발하는 과정에서 1Mb로 지정한 이유로 어드레스 버스와의 호환성 문제로 인해 사용하게 되었습니다. 어드레스 버스가 20비트가 필요함에도 불구하고, CPU는 16, 32, 64비트 단위로 호환되는 특성상, 20비트 어드레스 버스와 호환되기 어려웠기 때문입니다. 따라서 16비트 레지스터 2개를 이용하여 20비트 메모리에 접근하는 방식을 채택하였으며, 이를 위해 segment:offset 주소체계가 사용되었습니다.

 

즉, 세그먼트 레지스터를 사용하는 목적은 20비트의 물리주소 체계로 이루어진 어드레스 버스와 호환하기 위함이며, 특히 CS, DS, ES, FS, SS와 같은 각 세그먼트 레지스터들의 메모리 할당 영역이 중복되지 않도록 segment:offset 논리주소 체계를 사용하여 논리적으로 분리해주는 데에 그 목적이 있습니다.

 

20비트 어드레스 버스의 물리주소 범위는 다음과 같습니다.

0x00000 ~ 0xfffff

(2진수: 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111)


 

하지만 이러한 물리주소를 그대로 사용한다면 각 세그먼트 레지스터들의 물리주소 영역이 중복될 것입니다. 따라서 위에서 언급한 바와 같이, 이를 구별하기 위해 segment:offset 주소체계가 사용됩니다. 그리고 계산을 통해 실제 물리주소도 알 수 있습니다.

 

물리주소를 구하는 예를 들어 보겠습니다.

 

세그먼트 0x0200, 오프셋 0x0134 일 경우,

 

먼저 0x0200은 좌측으로 4비트 쉬프트 연산을 해줘야 합니다.

즉, 0x0200 -> 0x2000

 

오프셋 0x0134와 더하고 여기에서 0x10과 곱하기 연산을 해야 합니다. 물리주소 20비트로 만들어주기 위해서 말이죠. 즉 0x02134이 됩니다. 이를 정리해보면 다음과 같습니다.

 

0x0200(<<4) + 0x0134 = 0x02134

 

즉, 0x0200:0x0134 = (물리주소)0x02134

 

 



TAGS.

Comments