컴퓨터에는 운영모드에선 다양한 모드들이 존재합니다.

그중에서 리얼모드,보호모드,가상 8086모드등이 있지만 리얼모드의 메모리 관리방식에 대해서만 이야기 하겠습니다.

해당 모드의 레지스터 크기는 2바이트(2^16) 밖에 사용할수가 없습니다. 하지만 이상하게 느끼겟지만 리얼모드는 세그먼테이션은 1메가를 사용할수 있습니다. 이는 숫치상을 표기하면 2^20입니다.

그러면 리얼모드에서는 어떻게 이를 접근할수 있을까요 ? 바로 세그먼트의 도움을 빌리는거입니다. 자세하게는 세그먼트 레지스터의 값과 범용레지스터의 값을 합치는 방식입니다.

물론 바로 합치면 안되고 2^20을 표현하기 위해서 세그먼트의 값에 16을 곱해준후에 레지스터랑 합치면됩니다.

예로 세그먼트 값이 0x1000이고 레지스터가 0x1234입니다. 여기서 세그먼트에 16을 곱해주면 0x1000 * 16 = 0x10000이 나오게됩니다 이를 레지스터하고 더해주면 0x11234가 나오게 되는데 이게 물리주소가 됩니다.

이런 효과때문에 코드에서도 이런걸 생각해서 작성해야합니다. 예로 하드디스크를 읽는 다고 칩시다. 하드디스크의 1섹터는 보통 512바이트입니다. 이를 2진수로 표현하게되면 0x0200이지만 세그먼트에 값을 넣게되면 0x0020이 되게됩니다.

아래는 해당 어셈입니다.

    mov ah,0x02 ; sector mode
    mov al,0x01 ; sector read size
    mov ch,byte[DISK_TRACK_INDEX]
    mov cl,byte[DISK_SECTOR_INDEX]
    mov dh,byte[DISK_HEAD_INDEX]
    mov dl,0x00
    int 0x13 ; disk io service interrupt 0x13
    jc BOOT_ERROR_FUNC

    add si,0x0020 ; 0x0200이 아닌이유는 si가 세그먼트여서이다.
    mov es,si
카테고리: DevOpsLinux

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다