ALU와 제어장치
CPU는 메모리에 저장된 명령어를 읽어 들이고, 해석하고, 실행하는 장치이다.
이러한 CPU는 1) 계산을 담당하는 ALU, 2) 명령어를 읽어 들이고 해석하는 제어장치, 3) 작은 임시 저장 장치인 레지스터로 구성된다.
1) ALU
ALU는 계산하는 부품이라고 했다. 1+2를 계산하기 위해서는 1과 2라는 피연산자와 더하기라는 수행할 연산이 필요하다. 이처럼 ALU도 레지스터를 통해 피연산자를 받고, 제어장치로부터 수행할 연산을 알려주는 제어신호를 받는다.
그러나! 연산을 수행한 결과는 바로 메모리에 저장되지 않고 일시적으로 레지스터에 저장된다.
왜일까? CPU가 메모리에 접근하는 속도보다 레지스터에 접근하는 속도가 훨씬 빠르기 때문이다. CPU가 계속 메모리에 접근하면 프로그램의 실행 속도도 늦어질 것이다. 그래서 레지스터에 저장하는 것이다.
위의 그림을 보면 계산 결괏값 말고도 플래그를 내보내는 것을 알 수 있다.
플래그는 앞서 십진수/이진수 변환 부분에서 부호 플래그로 봤던 적이 있는 개념이다. 플래그를 자세히 살펴보자
2) 플래그
플래그는 연산 결과에 대한 추가적인 상태 정보를 의미한다. 플래그는 부호 플래그, 제로 플래그, 캐리 플래그, 오버플로우 플래그, 인터럽트 플래그, 슈퍼바이저 플래그 등 다양하다.
부호 플래그의 경우 부호 플래그가 1일 경우 계산 결과는 음수이고, 0일 경우 계산 결과는 양수인 것이다.
제로 플래그의 경우 제로 플래그가 1일 경우 연산 결과는 0이고, 0일 경우 연산 결과는 0이 아닌 것이다.
이러한 플래그는 CPU가 프로그램을 실행하는 도중 반드시 기억해야 할 일종의 참고 정보인 것이다.
플래그는 플래그 레지스터에 저장되는데, 플래그 레지스터란 말 그대로 플래그 값을 저장하는 레지스터인 것이다.
해당 경우 부호 플래그가 1이니까 음수라는 것을 알수 있다.
3) 제어장치
제어장치는 제어 신호를 내보내고, 명령어를 해석하는 부품이다.
또한 제어신호는 컴퓨터 부품들을 관리하고 작동시키기 위한 일종의 전기신호이다.
제어장치가 받아들이는 정보부터 알아보자.
1. 제어장치는 클럭 신호를 받아들인다.
클럭이란 컴퓨터의 모든 부품을 움직일 수 있게 하는 시간 단위이다.
클럭의 똑-딱-똑-딱 주기에 맞춰 한 레지스터에서 다른 레지스터로 데이터가 이동되거나 CPU가 메모리에 저장된 명령어를 읽어 들이는 것이다.
2. 제어장치는 해석해야할 명령어를 받아들인다.
CPU가 해석해야 할 명령어는 명령어 레지스터에 저장된다.
제어장치는 이 명령어 레지스터로부터 해석할 명령어를 받아들이고 해석한 뒤, 제어 신호를 발생시켜 컴퓨터 부품들에 수행할 내용을 알려주는 것이다.
3. 제어장치는 플래그 레지스터 속 플래그 값을 받아들인다.
플래그는 ALU 연산에 대한 추가적인 정보이다. 제어장치가 제어신호를 통해 부품을 제어할 때 이러한 사항을 놓치면 안 되기에 제어장치는 플래그 값을 받아들이고 이를 참고해 제어 신호를 발생시키는 것이다.
4. 제어장치는 시스템 버스, 그중에서 제어버스로 전달된 제어 신호를 받아들인다.
제어신호는 CPU뿐만 아니라 입출력장치를 비롯한 외부 장치도 발생시킬 수 있다.
이젠, 제어장치가 내보내는 정보를 알아보려 한다.
제어장치가 내보내는 정보는 크게 CPU 외부에 전달하는 제어신호와 CPU 내부에 전달하는 제어신호가 있다. CPU 외부로 전달한다는 것은 제어버스로 제어신호를 내보낸다는 말과 같다.
메모리에 저장된 값을 읽거나 메모리에 새로운 값을 쓰고 싶다면 메모리로 제어신호를 내보낼 것이다.
입출력 장치의 값을 읽거나 입출력 장치에 새로운 값을 쓰고 싶을 때는 입출력 장치로 제어신호를 보낼 것이다. 제어장치가 CPU 내부에 전달하는 제어신호에는 크게 1) ALU에 전달하는 제어신호와 2) 레지스터에 전달하는 제어신호가 있다.
1) ALU: 수행할 연산을 지시하기 위해서 제어 신호를 보낸다.
2) 레지스터 간에 데이터를 이동시키거나 레지스터에 저장된 명령어를 해석하기 위해 제어 신호를 보낸다.
레지스터
프로그램 속 명령어와 데이터는 실행 전후로 반드시 레지스터에 저장된다.
CPU 안에는 정말 다양한 레지스터들이 있으며 각기 다른 역할을 갖는다. 반드시 알아두어야 할 레지스터들에 대해 알아보자.
1) 프로그램 카운터
프로그램 카운터는 메모리에서 읽어 들일 명령어의 주소를 저장한다.
2) 명령어 레지스터
명령어 레지스터는 해석할 명령어, 즉 방금 메모리에서 읽어들인 명령어를 저장하는 레지스터이다.
제어장치는 명령어 레지스터 속 명령어를 받아들이고 이를 해석한 뒤에 제어신호를 내보낸다.
3) 메모리 주소 레지스터
메모리 주소 레지스터는 메모리의 주소를 저장하는 레지스터이다.
CPU가 읽어들이고자 하는 주소 값을 주소 버스로 보낼 때 메모리 주소 레지스터를 거치게 된다.
*프로그램 카운터는 명령어의 주소를 저장하는 것이고, 메모리 주소 레지스터는 명령어를 갖고 있는 메모리의 주소를 저장하는 레지스터인 것이다.
4) 메모리 버퍼 레지스터
메모리 버퍼 레지스터는 메모리와 주고받을 값(데이터와 명령어)을 저장하는 레지스터이다.
메모리에 쓰고 싶은 값이나 메모리로부터 전달받은 값은 반드시 메모리 버퍼 레지스터를 거치게 된다.
5) 범용 레지스터
메모리 버퍼 레지스터는 데이터 버스로 주고 받을 값을 저장하고, 메모리 주소 레지스터는 주소 버스로 내보낼 주소값만 저장한다.
하지만 범용 레지스터는 데이터와 주소를 모두 저장할 수 있다.
6) 플래그 레지스터
플래그 레지스터는 앞서 배운 것 처럼, 연산 결과 혹은 CPU 상태에 대한 부가적인 정보를 저장하는 레지스터이다.
특정 레지스터를 이용한 주소 지정 방식
1) 스택 주소 지정 방식
스택 주소 지정 방식은 스택과 스택 포인터를 이용한 주소 지정 방식이다. 스택은 한쪽 끝이 막혀있는 구조이다. 스택 포인터는 스택의 꼭대기를 가리키는 레지스터이며, 스택 포인터는 스택에 마지막으로 저장한 값의 위치를 저장하는 레지스터이다. 스택 포인터를 통해 스택의 어디까지 데이터가 채워져 있는지 확인할 수 있다.
스택은 메모리 안에 위치하는데, 정확히는 메모리 안에 스택처럼 사용할 영역이 지정되어 있는 것이다. 이를 스택 영역이라고 부른다.
2) 변위 주소 지정 방식
앞서 공부할 때 명령어 영역에는 연산코드와 오퍼랜드로 이루어져있다고 배웠다.
오퍼랜드 필드에는 메모리의 주소가 담기는 경우도 있는데, 변위 주소 지정 방식은 오퍼랜드 필드의 값과 특정 레지스터의 값을 더해 주소를 만들어내는 방식이다.
연산 코드 | 레지스터 | 오퍼랜드 |
이때 변위 주소 지정 방식은 오퍼랜드 필드의 주소와 어떤 레지스터를 더하는지에 따라
1) 상대 주소 지정방식과 2) 베이스 레지스터 주소 지정방식으로 구분할 수 있다.
상대 주소 지정 방식
상대 주소 지정 방식은 오퍼랜드와 프로그램 카운터의 값을 더해 유효 주소를 얻는 방식이다.
그림으로 이해하는게 쉬울 것 같다.
이처럼 -3인 경우 (실행할 명령어 -3) 번지로 이동하지만, +3인 경우 (실행할 명령어 +3) 번지로 이동한다.
베이스 레지스터 주소 지정 방식
베이스 레지스터 주소 지정 방식은 오퍼랜드와 베이스 레지스터의 값을 더해 유효 주소를 얻는 방식이다.
베이스 레지스터는 말 그대로 기존 주소를 의미하고, 오퍼랜드는 기존 주소로부터 떨어진 거리를 의미한다.
즉, 기준 주소로부터 얼마나 떨어져 있는 주소에 접근할 것인지를 연산해서 유효 주소를 얻는 방식이다.
명령어 사이클과 인터럽트
CPU가 하나의 명령어를 처리하는 과정에는 정해진 흐름이 있고, 이러한 흐름을 반복하며 명령어들을 처리한다. 이렇게 하나의 명령어를 처리하는 정형화된 흐름을 명령어 사이클이라고 한다. 간혹 이러한 흐름이 끊기는 상황이 발생하는데 이를 인터럽트라고 한다.
1) 명령어 사이클
프로그램 속 각각의 명령어들은 일정한 주기가 반복되며 실행된다. 이러한 주기를 명령어 사이클이라고 한다. 메모리에 저장된 명령어를 실행하기 위해서는 2가지 과정이 필요하다.
1. 명령어를 메모리에서 CPU로 가져와야 한다.
이렇게 명령어를 CPU로 가져오는 단계를 인출 사이클이라고 한다.
2. 가져온 CPU를 실행하면 된다.
이렇게 CPU를 실행하는 단계를 실행 사이클이라고 한다.
프로그램을 이루는 수많은 명령어는 인출과 실행 사이클을 반복하며 실행된다.
그러나! 앞서 간접 주소 지정 방식은 오퍼랜드 필드에 유효 주소의 주소를 명시한다고 배웠다.
즉, 명령어를 CPU로 가져왔다한들 바로 실행 사이클에 돌입할 수는 없다. 명령어를 실행하기 위해서는 메모리에 접근을 한번 더 해야 하는데 이 단계를 간접 사이클이라고 한다.
2) 인터럽트
인터럽트는 동기 인터럽트와 비동기 인터럽트로 구분할 수 있다.
동기 인터럽트는 예외라고 부르며 프로그램 상의 오류와 같은 예외적인 상황에서 발생하는 인터럽트이다.
반면 비동기 인터럽트는 하드웨어 인터럽트라고 부르며 주로 입출력 장치에 의해 발생하는 인터럽트이다.
세탁 완료 알림, 전자레인지 조리 완료 알림과 같은 것이 비동기 인터럽트에 해당한다.
3) 하드웨어 인터럽트
하드웨어 인터럽트는 일종의 알람이다. CPU는 입출력 작업 도중에도 효율적으로 명령어를 처리하기 위해 이런 알림과 같은 하드웨어 인터럽트를 사용한다.
효율적인 명령어 처리?
이 말의 의미는 예시로 들 수 있다. 프린터 출력 명령한 경우 입출력 장치는 CPU보다 속도가 느리기 때문에 CPU는 입출력 작업 결과를 볼 수 없다. 이때 하드웨어 인터럽트를 사용하지 않는다면 CPU는 언제 끝날지 모르는 작업을 확인하기 위해 주기적으로 프린터 출력이 완료되었는지를 확인해야 한다.
하지만 하드웨어 인터럽트를 사용하면 CPU는 프린터로 부터 출력 완료 알림을 받을 때까지 다른 작업을 처리할 수 있다. 따라서 효율적으로 명령어 처리를 할 수 있다는 의미이다.
4) 하드웨어 인터럽트 처리 순서
1. 입출력 장치는 CPU에 인터럽트 요청 신호를 보낸다.
- 인터럽트 요청 신호란 CPU의 정상적인 실행을 끊는 것이기에, 끼어들어도 되나여? 물어보는 것이다.
2. CPU는 실행 사이클이 끝나고 명령어를 인출하기 전 항상 인터럽트 여부를 확인한다.
3. CPU는 인터럽트 요청을 확인하고 인터럽트 플래그를 통해 현재 인터럽트를 받아들일 수 있는지 여부를 확인한다.
- CPU가 인터럽트 요청을 수행하기 위해서는 플래그 레지스터의 인터럽트 플래그가 활성화 되어있어야 한다. 불가능인 경우 인터럽트 요청이 와도 무시한다. 반면 가능인 경우 인터럽트 요청을 받아들인다.
- 인터럽트 플래그가 불가능으로 되어있더라도 가능한 경우가 있는데, 정전이나 하드웨어 고장이 해당한다
4. 인터럽트를 받아들일 수 있다면 CPU는 지금까지의 작업을 백업한다.
5. CPU는 인터럽트 벡터를 참조하여 인터럽트 서비스 루틴을 실행한다.
- 인터럽트 서비스 루틴이란 인터럽트를 처리하기 위한 프로그램이다. 인터럽트 핸들러라고도 부른다.
- 어떤 인터럽트가 발생했을 때, 해당 인터럽트를 어떻게 처리하고 작동해야 할지에 대한 정보로 이루어져있다.
- CPU가 인터럽트를 처리한다는 말은 인터럽트 서비스 루틴을 실행하고, 본래 수행하던 작업으로 다시 되돌아온다는 말과 같다.
6. 인터럽트 서비스 루틴 실행이 끝나면 (4)에서 백업해 둔 작업을 복구하여 실행을 재개한다.
인터럽트를 처리하는 방법은 입출력 장치마다 다르므로 각기 다른 인터럽트 서비스 루틴을 갖는다.
그렇다면 CPU는 각기 다른 인터럽트 서비스 루틴을 어떻게 구분해야 할까?
이때 사용하는 게 인터럽트 벡터이다. 인터럽트 벡터란 인터럽트 서비스 루틴을 식별하기 위한 정보이다.
인터럽트 벡터를 알면 서비스 루틴의 시작 주소를 알 수 있고, CPU는 인터럽트 벡터를 통해 특정 인터럽트 서비스 루틴을 처음부터 실행할 수 있다.
인터럽트 요청을 받기 전까지 CPU가 수행하고 있던 일은 인터럽트 서비스 루틴이 끝나면 되돌아와 마저 수행해야 한다. 이때 지금까지 작업해 둔 내용들은 백업을 해두어야 하는데, 프로그램을 재개하기 위해 필요한 모든 내용을 스택에 백업한다.
'Computer Science > 컴퓨터 구조' 카테고리의 다른 글
[컴퓨터 구조] Chapter 06 메모리와 케시 메모리 (1) | 2023.12.02 |
---|---|
[컴퓨터 구조] Chapter 05 CPU 성능 향상 기법 (0) | 2023.11.18 |
[컴퓨터 구조] Chapter 03 명령어 (0) | 2023.11.11 |
[컴퓨터 구조] Chapter 02 데이터 (0) | 2023.11.07 |
[컴퓨터 구조] Chapter 01 컴퓨터 구조 시작하기 (1) | 2023.10.29 |