본문 바로가기

CS/혼자 공부하는 컴퓨터구조와 운영체제

04 - CPU의 작동 원리

04 - 1 ALU 와 제어 장치

ALU   

CPU 내부 계산을 담당한다.

ALU가 받아들이는 정보

  1. 피연산자 : 피연산자는 레지스터로부터 얻어온다.
  2. 제어 신호 : 제어신호는 제어 장치로부터 얻어온다.

ALU가 내보내는 정보

  1. 결과 값 : 메모리로 바로 가지 않고 레지스터에 일시적으로 저장한다.
  2. 플래그 : 플래그는 연산 결과에 대한 추가정보이다. 이 플래그는 플래그 레지스터에 저장된다.

플래그 종류

1. 부호 플래그 - 결과가 양수, 음수 인지 나타냄

2. 제로 플래그 - 결과가 0인지 아닌지 나타냄

3. 캐리 플래그 - 결과가 올림수나 빌림수가 발생했는지 나타냄

4. 오버플로우 플래그 - 오버플로우가 발생했는지 나타냄

5. 인터럽트 플래그 - 인터럽트가 가능한지 나타냄

6. 슈퍼바이저 플래그 - 커널 모드, 사용자 모드 중 어떤 모드인지 나타냄

 

제어 장치 

 

제어 장치는 제어 신호를 내보내고, 명령어를 해석하는 부품이다. 제어 신호는 컴퓨터 부품들을 관리, 작동 시키기 위한 전기 신호이다.

 

각 CPU 마다 제어장치 구현 방식이나 명령어 해석 방식, 제어 신호를 받고 내보내는 방식이 조금씩 상이하기 때문에 가장 대표적인 정보에만 알아본다.

 

제어장치가 받아들이는 정보

  1. 클럭 : 컴퓨터의 부품들을 움직이게 하는 시간 단위. 클럭 주기에 맞춰서 연산, 메모리 명령어 읽기 등이 실행된다. 다만, 한 클럭마다 작동하는 것은 아니고, 그냥 클럭이라는 시간 단위에 맞게 상승,하강 펄스에 마춰서 작동 하는 것일 뿐이다. 즉, 하나의 명령어가 여러 클럭에 걸쳐 실행 될 수 있다.
  2. 해석해야할 명령어 : CPU 가 해석해야 할 명령어는 명령어 레스터에 저장된다. 이 레지스터에서 해석할 명령어를 받고 해석한 다음, 제어 신호로 각 컴퓨터 부품들에게 명령어에 맞는 수행 내용을 전달한다.
  3. 플래그 : 플래그 레지스터로부터 플래그 즉, ALU 의 연산 결과의 추가 정보를 받는다.
  4. 제어 버스로 전달된 제어 신호 : 제어 신호는 CPU 뿐 아니라 입출력장치를 비롯한 CPU 외부 장치도 발생 가능하고 제어 버스를 통해 외부에서 전달된 제어 신호를 받는다.

04_2 레지스터

프로그램 속 명령어와 데이터는 실행 전후 반드시 레지스터에 저장된다.

CPU 내에 레지스터는 그 종류가 다양하고 당연히 역할도 다 다르다. 당연히 레지스터의 종류도 정말 많지만 여기서는 대중적인 레지스터 8가지를 알아본다.

먼저 이 중 4가지를 알아보고 순서를 살펴본다.

  1. 프로그램 카운터 : 메모리에서 가져올 명령어 주소를 저장하는 레지스터 ( 명령어 포인터라고도 한다.)
  2. 명령어 레지스터 : 해석할 명령어, 방금 메모리에서 읽은 명령어를 저장
  3. 메모리 주소 레지스터 : 메모리의 주소를 저장하는 레지스터. CPU 가 읽어 들이고자 하는 주소 값을 주소 버스로 보낼 때 메모리 주소 레지스터를 거친다.
  4. 메모리 버퍼 레지스터 : 메모리와 주고 받을 값을 저장하는 레지스터. CPU 가 주소 버스로 내보낼 값이 메모리 주소 레지스터를 거치고, 데이터 버스로 주고 받을 값은 메모리 버퍼 레지스터를 거친다.

위의 레지스터들이 어떻게 동작하는지 일련의 동작을 순서대로 작성해본다.

만약, CPU 가 실행할 프로그램의 데이터나 명령어가 메모리의 1000~1500 번지에 있다고 가정한다.

  1. 맨 처음 실행할 프로그램의 명령어가 존재하는 메모리 1000번지의 주소 즉, 1000이 프로그램 카운터에 저장된다.
  2. 그 다음, 그 1000번지를 메모리 주소 레지스터프로그램 카운터로부터 받는다.
  3. 제어 장치가 제어버스, 메모리 주소 레지스터주소 버스를 통해 1000번지 메모리로 접근한다.
  4. 메모리 1000번지에 저장된 값이 데이터 버스에 의해 메모리 버퍼 레지스터에 저장된다. 그리고 프로그램 카운터는 증가되어 다음 명령어가 포함된 주소를 받을 준비를 한다.
  5. 메모리 버퍼 레지스터에 저장된 값은 명령어 레지스터로 이동한다.
  6. 제어장치가 명령어 레지스터로부터 명령어를 받아 해석하고 제어 신호를 발생시킨다.

당연히 여기서 연산 코드에 의해 프로그램 카운터에 다른 메모리 주소 값이 들어갈 수 있다. JUMP 등에 의해

나머지 레지스터를 알아본다.

 

범용 레지스터 : 다양하고 일반적인 상황에서 자유롭게 쓰는 레지스터. 데이터와 주소를 모두 저장가능

플래그 레지스터 : ALU 연산 결과의 추가 정보 플래그를 저장하는 레지스터

스택 포인터 와 베이스 레지스터는 밑에서 설명

 

추가적인 주소 지정 방식

유효 주소를 찾는 방식 중 스택 주소 방식이 있다.

 

스택 주소 방식 : 스택 포인터는 스택의 꼭대기를 가리키는 레지스터이다. 즉, 스택의 마지막 저장 값의 주소를 저장하는 레지스터 이다. 이때, 스택 주소 지정 방식은 이 스택 포인터가 가리키는 주소를 유효 주소로 지정한다. 그래서 스택 포인터로 스택에 얼마나 데이터가 채워졌는지 확인 가능하다.

 

변위 주소 지정 방식

이 방식은 상대 주소 지정 방식과, 베이스 주소 지정 방식이 있다. 이때, 명령어는 연산 코드, 레스터, 오퍼랜드로 이루어진다.

 

상대 주소 지정 방식 : 이 방식은 오퍼랜드와 레지스터를 더해서 유효 주소를 찾는다. 프로그램 카운터가 가지고 있는 메모리 주소와 오퍼랜드 필드에 있는 값으로 접근한다.

가령 프로그램 카운터가 1000번지 오퍼랜드 필드가 -3 이면 CPU 가 읽기로한 명령어의 주소로부터 -3 번째 번지로 접근하고 실행한다.

 

베이스 주소 지정 방식 : 오퍼랜드와 베이스 레지스터의 값을 더해서 주소를 얻는다. 여기서 베이스 레지스터란 기준 주소를 가지고 있느 레지스터이다. 이 기준 주소와 오퍼랜드 값을 더한 메모리 번지수에 접근하여 해당 번지수의 코드르 실행한다.

 

04_3 명령어 사이클과 인터럽트

CPU 가 하나의 명령어를 처리하는 과정에는 정해진 흐름이 있다. 이러한 흐름은 반복되어 명령어들이 순차적으로 처리된다. 이러한 정해진 흐름을 명령어 사이클이라고 한다.

CPU 가 흐름에 따라 명령어를 처리하다가 이 흐름이 끊어지는 경우가 있는데 이를 인터럽트 라고한다.

명령어 사이클

프로그램 속 각각의 명령어들을 일정한 주기 별로 반복하여 실행하는데 이 주기가 명령어 사이클이다.

명령어를 실행 시킬려면 메모리의 명령어를 CPU 로 가져오는데 이 단계가 인출 사이클이다.

이 인출 사이클은 레지스터가 명령어를 받는 과정으로 04_2 레지스터에서 확인 가능하다.

CPU가 명령어 인출을하면 실행한다. 이것을 실행 사이클 이라고 한다. 제어장치가 명령어 레지스터에 담긴 값을 해석하고, 제어 신호를 발생 시키는 단계

이러한 인출, 실행 사이클을 반복하여 프로그램이 작동된다.

다만, 간접 주소 지정 방식을 이용하는 명령어 같은 경우에는 해당 명령어 내에서 한 번 더 메모리로 접근해야한다. 이 경우를 간접 사이클이라고 한다.

즉, 간접 주소 지정 방식을 이용하는 명령어는 인출 → 간접 → 실행 순이다.

인터럽트

CPU 의 작업을 방해하는 신호를 인터럽트 라고 함.

 

인터럽트는 동기, 비동기 인터럽트로 나눈다.

 

동기 인터럽트 : CPU 에 의해 발생하는 인터럽트. CPU 가 명령어 수행 중 예상치 못한 상황에 마주치면 발생하는 인터럽트. 동기 인터럽트는 예외 라고 부른다.

 

비동기 인터럽트 : 주로 입출력장치에 의해 발생하는 인터럽트. 예 - 마우스가 입력을 받아 CPU 에게 입력 알림(인터럽트) 를 보냄. 일반적으로는 비동기를 그냥 인터럽트라고 하지만 하드웨어 인터럽트라고 생각하고 다음 설명.

 

하드웨어 인터럽트 : CPU 는 입출력 작업 도중에도 효율적으로 명령어를 처리하기 위해서 하드웨어 인터럽트를 이용함.

CPU 가 입출력장치에 명령을 내려도 입출력장치는 CPU 보다 느려서 결과를 바로 줄 수 없다. 이때, CPU 는 매번 결과가 나왔는지 확인하게 되고 이러면 사이클 낭비가 심해진다. 이때, 인터럽트를 이용해서 따로 결과 확인을 하지 않고, 하드웨어 인터럽트가 발생했을 때 에만 결과 확인을 하고 그 전까지는 다른 작업을 처리한다.

  1. 입출력장치가 CPU에 인터럽트 요청 신호 보냄
  2. CPU 는 실행 사이클 끝나고 인출전 인터럽트 여부 확인
  3. CPU는 요청 확인 후 인터럽트 플래그를 통해 현재 인터럽트를 받아들일 수 있는지 여부 확인
  4. 인터럽트 받기 가능이면 CPU 가 지금까지의 작업 백업
  5. CPU 가 인터럽트 벡터 참조 후 인터럽트 서비스 루틴 실행
  6. 루틴 끝나면 백업해둔 작업을 복구하여 다시 실행 재개

인터럽트 요청 신호 : CPU 말고 다른 존재가 현재 인터럽트 가능한지 물어보는 것.

인터럽트 플래그 : 인터럽트 플래그는 하드웨어 인터럽트를 받아들일지 말지를 결정하는 플래그. 다만, 인터럽트 플래그가 모든 인터럽트를 제어하지는 못한다.

 

CPU 가 인터럽트 요청을 받으면 인터럽트 처리 프로그램을 실행하는데 이것을 인터럽트 서비스 루틴 혹은 인터럽트 핸들러 라고 한다.

 

CPU 가 인터럽트 처리를 한다 == 인터럽트 핸들러 실행 후 본래 작업으로 되돌아오겠다.

 

메모리에는 다양한 인터럽트 핸들러가 저장되어 있다. 이러한 많은 핸들러를 구분하는 것이 바로 인터럽트 벡터 이다.

인터럽트 벡터는 인터럽트 핸들러를 식별하는 정보이다. CPU 는 하드웨어 인터럽트 요청을 보낸 대상으로부터 데이터 버스를 통해 인터럽트 벡터를 받는다.

 

위에서 기존 작업들을 백업한다고 했는데 각각의 레지스터들이 인터럽트 핸들러를 위해 사용되어지면 레지스터에 있던 기존 정보들은 스택 영역에 저장된다.

 

전체 명령어 사이클

 

 

예외

  • 폴트, 트랩, 중단, 소프트웨어 인터럽트폴트 - 예외 처리한 직후 예외가 발생한 명령어부터 실행 재개트랩 - 예외 처리 직후 다음 명령어 실행 재개중단 - 심각한 오류 발생 시 프로그램 강종
  • 소프트웨어 인터럽트 - 시스템 호출이 발생 시 나타나는 예외.
  • 예) 디버깅
  • 예) 명령어 실행한 데이터가 메모리가 아니 보조기억장치에 있을 경우, 프로그램이 동작하려면 메모리에 데이터가 저장되어 있어야하니, 폴트 예외 발생 후 보조기억장치에서부터 필요한 데이터를 메모리로 가져온다. 그 이후 다시 해당 명령어 실행
  • 예외가 발생하면 CPU 는 예외 처리 부터 하는 그 이후에 본래 작업을 예외 발생한 명령어에서 할지 넘어가서 다음 명령어부터 실행할지는 폴트 트랩에 따라 다르다.
  • 동기 인터럽트의 종류 간단하게

 

 

 

 

 

 

 

 

 

 

 

 

 

'CS > 혼자 공부하는 컴퓨터구조와 운영체제' 카테고리의 다른 글

06 - 메모리와 캐시 메모리  (0) 2024.06.01
05 - CPU의 성능 향상 기법  (0) 2024.06.01
03 - 2 명령어 2  (1) 2024.02.14
03 - 1 명령어  (0) 2024.02.14
02 - 데이터  (0) 2024.02.08