들어가기 앞서 해당 글은 '혼자 공부하는 컴퓨터구조 + 운영체제'를 참고로 작성되었습니다. 

 

간단한 cpu 내부 구조

 

 cpu는 제어 장치로 명령어를 해석하여 전기 신호로 동작하고, 필요한 데이터를 메모리로부터 불러와 레지스터에 임시로 저장하여 ALU는 레지스터의 값을 토대로 연산을 한다.

 

 레지스터(Register)

 레지스터는 ALU가 연산할 명령어와 데이터가 저장되는 장소다. 책에서 나온 기억해야할 레지스터는 다음과 같다.

 

 들어가기 전에 cpu의 레지스터는 이름과 종류, 그리고 각 갯수 등에 대해선 제조사마다 여려가지다. 해당 사항을 유념하자. 

  • 프로그램 카운터
  • 명령어 레지스터
  • 메모리 주소 레지스터
  • 메모리 버퍼 레지스터
  • 플래그 레지스터
  • 범용 레지스터
  • 스택 포인터
  • 베이스 레지스터

 프로그램카운터(PC: Program Counter)

 해당 레지스터에는 메모리에서 가져올 명령어의 주소를 저장한다.명령어 포인터(Instruction Pointer) 라고도 부른다.

 

 명령어 레지스터(IR: Instruction Register)

 말 그대로 해석할 명령어를 저장하는 레지스터다. 제어 장치는 해당 레지스터의 명령어를 해석하여 필요한 전기 신호를 보낸다. 

 

 메모리 주소 레지스터(MAR: Memory Adress Register)

 메모리의 주소를 저장하는 레지스터다. 여기서 처음에 든 의문점이 "프로그램 카운터와 뭐가 다른가?" 였다. 이는 레지스터들의 이름만 봐도 알 수 있듯이 역할이 다르다. 후에 서술할 cpu의 동작방식을 보면 이해가 간다.

 

 메모리 버퍼 레지스터(MBR: Memory Buffer Register)

 메모리 데이터 레지스터(MDR: Memory Data Register) 라고도 불리며 데이터나 명령어가 저장되는 장소다. 이 또한 명령어 레지스터가 있는데 왜 굳이 또 해당 레지스터가 있는지 의문이 들지만 cpu의 동작 방식을 보면 이해된다.

 

 

해당 레지스터들은 다음과 같이 동작한다.

 

 

 먼저 프로그램 카운터에 읽어 들일 메모리 주소가 저장된다. 프로그램 카운터에는 최초에는 시작 카운터, 후에는 다음에 읽어들일 메모리의 주소가 저장된다. 즉, 프로그램 카운터는 '읽어 들일 메모리의 가이드'를 하는 셈이다.

 참고로 프로그램 카운터에 값을 넣는 역할은 운영체제가 담당한다.

 

 

 프로그램 카운터에 저장된 주소가 메모리 주소 레지스터에 저장된다. 즉, 메모리 레지스터에는 현재 읽어 들일 메모리를 가지고 있는 것이다. 메모리 주소가 저장되면 제어장치는 해당 주소를 읽으라는 제어 신호를 보낸다. 

 

 

 제어 신호를 받은 메모리는 해당 주소의 데이터(또는 명령어)를 보내게 되고 해당 데이터는 메모리 버퍼 레지스터에 저장된다. 이 때 프로그램 카운터가 오르면서 다음에 읽을 메모리를 가리키게 된다.  

 이로서 프로그램 카운터와 메모리 주소 레지스터의 차이점이 명확해 졌다. 현재 작업(1000)을 완료하면 프로그램 카운터에 저장된 다음 작업(1001)을 시작할 것이고 이런식으로 카운터가 증가하며 순차적으로 작업을 해 나갈 것이다.

 

 

 메모리 버퍼 레지스터에 저장된 값이 명령어이면 명령어 레지스터에 저장된다. 그림엔 없지만 만약 데이터 값이면 어큐뮬레이터(accumulator)라는 레지스터에 저장된다. 

 

 여기서 드는 의문점은 "메모리 버퍼 레지스터의 값을 왜 또 굳이 나눠서 저장을 하나?" 이다. 

 

 메모리에서 받는 값은 데이터가 될 수도 있고 명령어가 될 수도 있다. 그 말은 즉, 명령어와 데이터를 처리하는 과정이 다를 수 있으며 이 둘을 유동적으로 활용하기 위해서는 하나의 저장 장소가 아닌 각각의 저장 장소를 만드는 것이 더 효율적이다.

 예를 들어 앞서 캐시 메모리에서 다루었듯이 캐시 메모리는 데이터를 예측하여 저장하는데, 명령어를 실행하는 동안 그 값을 미리 메모리 버퍼 레지스터에 저장하는 등으로 활용할 수 있을 것이다. 이는 버퍼에 대한 개념을 다시 상기하면 이해할 수 있는 내용이다.

 

 명령어 레지스터에 명령어가 저장이 되면 제어장치는 저장된 명령어를 읽어 명령어를 처리한다. 1000번에 담긴 명령어가 가령 '80번 주소의 데이터를 가져와라' 라는 명령어라면 80번주소를 메모리 레지스터에 저장하고, 해당 주소를 토대로 메모리에 요청하여 그 값을 메모리 버퍼 레지스터에 저장한 후, 해당 데이터는 어큐뮬레이터에 저장되는 식이다.

 이런식으로 1000번 주소의 작업이 끝나면 다음 주소인 1001번 주소의 작업을 시작하게 될 것이다. 만약 1001번 주소의 명령어가 '데이터를 더하라(ADD)라면 제어 장치는 ALU에 제어 신호를 보내 연산을 하고 결과값을 어큐뮬레이터에 저장한다.  

 

cpu 동작에 대해서는 책의 내용만으로는 부족한 감이 있어 해당 영상을 참고 하면 더욱 이해가 쉬울 것이다.

 

 

 범용 레지스터(general purpose register)

 이름 그대로 다양한 상황에 자유롭게 사용할 수 있는 레지스터다. 메모리 버퍼 레지스터는 데이터 버스로 주고받을 값만 저장하고, 메모리 주소 레지스터는 주소 버스로 내보낼 주소값만 저장하지만, 범용 레지스터는 데이터와 주소를 모두 저장할 수 있다.

 

 플래그 레지스터(flag register)

 cpu의 ALU의 연산 결과나 CPU의 상태에 대한 플래그 정보를 저장하는 레지스터다.

 플래그 레지스터에는 다음과 같은 1비트 정보들이 있는데, 주로 ALU의 연산 결과에 의해 해당 비트들의 값이 정해진다.

플래그 종류 의미
부호 플래그 연산한 결과의 부호를 나타낸다.
제로 플래그 연산 결과가 0인지 여부를 나타낸다.
캐리 플래그 연산 결과 올립수나 빌림수가 발생했는지를 나타낸다.
오버 플로우 플래그 오버플로우가 발생했는지를 나타낸다.
인터럽트 플래그 인터럽트가 가능한지를 나타낸다.
슈퍼바이저 플래그 커널 모드로 실행 중인지, 사용자 모드로 실행중인지를 나타낸다.

 

 

 스택 포인터(stack pointer)

 메모리에는 스택 영역이 있다. 스택 포인터는 이 영역의 꼭대기. 다시말해 스택 영역에 마지막으로 저장된 메모리 주소를 가리킨다. 스택 포인터의 값을 관리함으로써 스택 메모리 영역을 벗어나는 오버플로나 언더플로를 방지한다. 

 

 베이스 레지스터(base register)

 베이스 레지스터는 베이스 레지스터 주소 지정 방식에 쓰이는 레지스터다. 베이스 레지스터 주소 지정 방식은 변위 주소 지정 방식의 한 종류 인데, 변위 주소 지정 방식이란 명령어의 주소가 저장된 오퍼랜드 필드의 값에 특정값을 더하여 유효 주소를 얻어내는 방식이다.

 즉, 베이스 레지스터 주소 지정 방식이란 오퍼랜드에 저장된 값에 베이스 레지스터의 값을 더하여 유효 주소를 얻는 방식이다. 예를 들어 베이스 레지스터에는 베이스가 되는 시작 주소가 저장 돼 있고, 오퍼랜드에는 100이라는 값이 저장 돼 있으면 베이스 주소로부터 100만큼 떨어진 주소를 얻을 수 있다.

  비슷한 방법으로 상대 주소 지정 방식이 있다. 이는 프로그램 카운터 값을 더하여 유효 주소를 얻는 식이다.

 

 그렇다면 그냥 주소를 불러오면 되지 언뜻 보면 번거로워 보이는 해당 방식을 도입했을까?

 

  Array를 예로 들어 보겠다. Array는 주소의 배열인데, 만약 Array[3]에 접근할 때 변위 주소를 사용하면 해당 Array[3]는 명령어로 오퍼랜드 값에 3이 저장될 것이고 Array의 베이스 주소(시작 주소)로부터 3만큼 떨어진 주소를 찾아 줄 것이다. 만약 이와 같은 방법이 없다면 프로그래머는 Array[3]에 해당하는 정확한 주소를 명시적으로 알아야 할 것이며 이는 아주아주 불편할 수 밖에 없을 것이다. 

 

 

 해당 파트를 공부하면서 정말 많을 걸 느낀 것 같다. 처음 게임을 만들자고 공부를 시작했을 땐 학원에 절여져 굳이 컴퓨터에 대한 공부를 해야하나? 라고 했지만 지금은 전혀 아니다. 내가 어떤식으로 코딩을 해야 하는지에 대해 공부를 하면 할수록 감이 잡히는 느낌이다.

'개발공부 > 운영체제 등' 카테고리의 다른 글

운영체제 개괄  (0) 2023.12.10
CISC와 RISC  (1) 2023.11.21
여러 입출력 방법 (프로그램 , 인터럽트 , DMA)  (0) 2023.11.20
인터럽트(Interrupt)  (0) 2023.11.16
디바이스 컨트롤러(Device Controller)  (0) 2023.11.16

+ Recent posts