개발자 노트

메모리 번지 지정시 세그먼트 레지스터 사용 본문

▶ INBOX ◀

메모리 번지 지정시 세그먼트 레지스터 사용

heeyam 2016. 9. 29. 14:25
반응형

메모리는 세그먼트 레지스터와 함께 번지를 지정해야한다.

그 다음에 모르는 것이 버퍼 어드레스라는 것이다. 이것은 디스크에서 읽은 데이터를 메모리의 어디에 저장할 것인지를 나타내는 주소 값이다.

보통, 본지는 1개의 레지스터로 나타내면 좋을 것 같지만, BX만으로는 0~0xFFFF 까지의 값밖에 표현할 수 없다. 이것은 0부터 65,535 번지까지 밖에 나타낼 수 없다는 의미이다.

이것을 극복하기 위해, EBX 레지스터라는 것이 나중에 나와서 이것으로 4GB까지 다룰 수 있게 되었다. 이것은 cpu가 다룰 수 있는 최대 메모리 용량이므로, 문제 없다. 그러나 EBX가 사용될 수 있게 된 것은 훨씬 뒤의 이야기이고, BIOS들이 설계된 시대의 CPU는 32비트 레지스터를 붙이는 것이 좀 어려웠기 때문에, 할 수 없이 보조적인 역할을 하는 세그먼트 레지스터라는 것을 만들었다. 그리고 메모리의 번지를 지정할 때 이 세그먼트 레지스터를 사용하게 된 것이다.

ES:BX라는 표현이 바로 그것이며, MOV AL,[ES:BX]와 같이 사용한다. 이 경우의 메모리 번지는 EX*16 + BX로 계산하게 되어 있다. ES 레지스터로 번지를 대략 정한 후에 BX로 세세하게 지정한다.

이것으로 ES에 0xffff, BX에도 0xffff를 넣어서 1,114,095바이트, 즉 약 1MB의 메모리 번지를 지정할 수 있게 되었다. 이것만으로는 64MB에는 전혀 닿지 않지만, 당시의 인텔사에서는 그정도면 될 것이라 생각한 것 같다. 원조 BIOS가 설계된 것도 딱 이정도의 구조로 만족하고 있었으므로 이 책에서는 이 룰을 따르겠다.

이번에는 ES=0x0820이고, BX=0이므로, 이 디스크의 데이터가 로드되는 곳은 0x8200번지부터 0x83ff번지(1섹터)까지가 된다. 


어떤 메모리라도 세그먼트 레지스터와 함께 번지를 지정하지 않으면 안 된다는 규칙이 있다. 생략하면 거의 대부분의 경우 DS: 를 지정한 것이 된다.

지금까지 우리가 MOV CS,[1234]라고 생각한 것은 MOV CX,[DS:1234]의 의미였던 것이다. MOV AL,[SI]도 MOV AL,[DS:SI]라는 의미이다. 어셈블러에서는 매번 쓰는 것이 귀찮아서 생략해도 가능하게 되어있다.

이러한 룰 때문에 DS를 0으로 해 두지 않으면 안된다. 만약 DS가 0이 아니면, 그 16배수가 번지로 항상 더해지게 되므로, 어딘가 이상한 곳을 읽고 쓰게 될수도 있기 때문이다.

반응형
Comments