8086 메모리, 레지스터

옥영진·2021년 4월 25일
0

BOF

목록 보기
1/4

8086 메모리 구조

1) 기본적인 메모리 구조

8086 시스템의 기본적인 메모리 구조는 위와 같으며, 시스템이 운영에 필요한 기본적인 명령을 커널에서 찾기 때문에 커널 영역은 반드시 저 위치에 있어야 한다.

32bit 시스템에서는 CPU가 한꺼번에 처리할 수 있는 데이터가 32bit 단위이기 때문에 메모리에 주소를 할당할 수 있는 범위가 0 ~ 232-1 이다. 64bit 시스템은 0 ~ 264-1 범위를 갖는다.

2) segment


운영체제는 하나의 프로세스를 실행시키면 이 프로세스를 segment라는 단위로 묶어서 가용 메모리 영역에 위치시킨다. 하나의 segment는 위 그림처럼 stack, data, code로 구성되어 있다.

  • stack segment : 지역 변수가 들어 있는 곳으로, 자주 들어보았던 버퍼라는 것이 이곳에 자리잡게 된다.
    스택은 처음 생성될 때 필요한 크기만큼 만들어지고, 프로세스의 명령에 의해 데이터가 순차적으로 저장된다. 이 때, stack pointer(SP)라고 하는 레지스터가 스택의 맨 꼭대기를 가리킨다.

  • data segment : 프로그램 실행시 사용되는 데이터, 즉 전역 변수가 들어있다. data segment는 현재 모듈의 data structure, 상위 레벨로부터 받아들이는 데이터 모듈, 동적 생성 데이터, 다른 프로그램과 공유하는 공유 데이터 부분으로 나뉜다.

  • code segment : 시스템이 알아들을 수 있는 명령어들이 들어 있다. 명령어를 수행하면서 많은 분기와 점프, 시스템 호출 등을 수행하는데, 그 중에서도 분기와 점프는 메모리 상의 특정 위치에 있는 명령어를 지정해 주어야 한다. 하지만 segment는 메모리 상에 어느 위치에 지정될지는 컴파일 과정에서 알 수 없기 때문에 logical address를 사용한다.
    segment는 segment selector를 통해 자신의 시작 위치(offset)을 알 수 있고, 이 offset과 각 명령어의 logical address를 더해 실제 physical address를 구할 수 있게 된다.

8086 CPU 레지스터 구조

CPU가 프로세스를 실행하기 위해서는 프로세스를 CPU에 적재시켜야 하는데, 명령어와 데이터들을 적절하게 읽어오고 저장하기 위해서는 여러 가지 저장 공간이 필요하다. CPU가 이러한 행위들을 빠르게 처리하기 위해서는 CPU 내부에 존재하는 메모리를 사용하는데 이를 레지스터(register)라고 한다. 시스템의 프로그램 레지스터의 구조는 다음과 같다.

레지스터는 목적에 따라서 범용 레지스터, 세그먼트 레지스터, 플래그 레지스터, 인스트럭션 포인터로 구성된다.

  • 범용 레지스터 : 논리 연산, 수리 연산에 사용되는 피연산자, 주소를 계산하는데 사용되는 피연산자, 그리고 메모리 포인터가 저장되는 레지스터이다.
  • 세그먼트 레지스터 : code segment, data segment, stack segment를 가리키는 주소가 들어있는 레지스터이다.
  • 플래그 레지스터 : 프로그램의 현재 상태나 조건 등을 검사하는데 사용되는 플래그들이 있는 레지스터이다.
  • 인스트럭션 포인터 : 다음 수행해야 하는 명령어가 있는 메모리 상의 주소가 들어있는 레지스터이다.

범용 레지스터

범용 레지스터는 프로그래머가 임의로 조작할 수 있는 레지스터이다. 16bit 시스템에서는 각 레지스터를 AX, BX, CS 등으로 불렀지만 32bit 시스템으로 전환되면서 앞에 E(Extended)가 붙게 되었다. AX 레지스터의 상위 부분을 AH, 하위 부분을 AL이라고 한다. EAX, EBX, ECX, EDX 레지스터들은 프로그래머의 필요에 따라 아무렇게나 사용해도 되지만 원래는 각각의 목적이 있다.

  • EAX(Extended Accumulator Register) : 피연산자와 연산 결과의 저장소
  • EBX(Extended Base address Register) : data segment 안의 데이터를 가리키는 포인터
  • ECX(Extended Counter Register) : 문자열 처리나 루프를 위한
  • EDX(Extended Data Register) : I/O 포인터
  • ESI(Extended Source Index) : 문자열 처리에서 source를 가리킴
  • EDI(Extended Destination Index) : 문자열 처리에서 destination을 가리킴
  • ESP(Extended Stack Pointer) : stack segment의 맨 아래를 가리키는 포인터
  • EBP(Extended Base Pointer) : stack segment의 맨 꼭대기를 가리키는 포인터

세그먼트 레지스터

세그먼트 레지스터는 프로세스의 특정 세그먼트를 가리키는 포인터 역할을 한다.

CS 레지스터는 code segment를, DS, ES, FS, GS 레지스터는 data segment를, SS 레지스터는 stack segment를 가리킨다.

플래그 레지스터

플래그 레지스터는 상태 플래그, 컨트롤 플래그, 시스템 플래그들의 집합이다. 1, 3, 5, 15, 22~31번 비트는 예약되어 있어 소프트웨어에 의해 조작할 수 없게 되어 있고, 시스템이 리셋되면 이 레지스터는 0x00000002의 값을 가진다.

Status flags

  • CF(Carry flag) : 연산 수행시 carry 혹은 borrow가 발생하면 1이 된다.
  • PF(Parity flag) : 연산 결과 값이 1인 bit의 개수가 짝수일 경우 1이 된다.
  • AF(Adjust flag) : 연산 결과 carry 혹은 borrow가 3bit 이상 발생할 경우 1이 된다.
  • ZF(Zero flag) : 연산 결과가 0임을 나타낸다. IF문 같은 조건문이 만족될 경우 set 된다.
  • SF(Sign flag) : 연산 결과 최상위 비트의 값과 같다.
  • OF(Overflow flag) : 부호 있는 숫자의 연산 결과가 비트 범위를 넘어섰을 때 1이 된다.
  • DF(Direction flag) : 문자열 처리에 있어서 1일 경우 문자열 처리 instruction이 감소, 0일 경우 증가한다.

System flags

  • IF(Interrupt enable flag) : 프로세서에게 mask한 interrupt에 응답할 수 있게 하려면 1을 준다.
  • TF(Trap flag) : 디버깅을 할 때 single-step을 가능하게 하려면 1을 준다.
  • IOPL(I/O privilege level field) : 현재 수행 중인 프로세스 혹은 task의 권한 레벨을 가리킨다.
  • NT(Nested task flag) : interrupt의 chain을 제어하는 flag로, 1이면 이전 실행 task와 현재 task가 연결되어 있음을 나타낸다.
  • RF(Resume flag) : 디버그 예외에 대한 반응을 제어하기 위함으로, 1이면 디버그 fault를 무시하고 다음 명령어를 실행한다.
  • VM(Virtual-8086 mode flag) : 1이면 virtual-8086 모드를 사용한다.
  • AC(Alginment check flag) : 메모리 참조시 정렬 기능을 활성화한다.
  • VIF(Virtual interrupt flag) : IF flag의 가상 이미지이다.
  • VIP(Virtual interrupt pending flag) : interrupt가 pending(경쟁 상태) 되었음을 나타낸다.
  • ID(Identification flag) : CPUID instruction을 지원하는 CPU인지를 나타낸다.

인스트럭션 포인터

인스트럭션 포인터 레지스터는 다음 실행할 명령어가 있는 현재 code segment의 offset 값을 가진다. 쉽게 말하면 다음 수행할 명령어가 들어 있는 메모리 상의 주소가 들어 있다.

profile
안녕하세요 함께 공부합시다

0개의 댓글