개발자 노트
메모리 번지 지정시 세그먼트 레지스터 사용 본문
메모리는 세그먼트 레지스터와 함께 번지를 지정해야한다.
그 다음에 모르는 것이 버퍼 어드레스라는 것이다. 이것은 디스크에서 읽은 데이터를 메모리의 어디에 저장할 것인지를 나타내는 주소 값이다.
보통, 본지는 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배수가 번지로 항상 더해지게 되므로, 어딘가 이상한 곳을 읽고 쓰게 될수도 있기 때문이다.
'▶ INBOX ◀' 카테고리의 다른 글
C++]소수점 자리 지정해서 출력 (0) | 2016.10.10 |
---|---|
word 단축키 (0) | 2016.10.04 |
C언어의 함수를 어셈블리어와 연계할 때 어셈블리어에서만 함수 앞에 언더바를 붙이는 이유 (0) | 2016.09.29 |
부트로더에 대한 이해 (0) | 2016.09.27 |
BIOS 설명 및 CMOS 셋업 (0) | 2016.09.27 |