[CS] 컴퓨터의 구조 - CPU의 작동원리

이상혁·2023년 9월 12일
0

Computer science

목록 보기
4/15
혼자 공부하는 컴퓨터 구조 + 운영체제를 읽고 공부한 내용입니다.

CPU의 구조

cpu는 제어 장치, 산술/논리연산장치인 ALU, 레지스터로 구성이 되어 있다.

ALU

ALU는 산술/논리연산장치이다.
간단하게 말해서 계산하는 장치이다.
ALU는 레지스터를 통해서 데이터를 받아 드리고 수행할 연산을 알려줄 제어신호를 받아드린다.
받아드린 데이터와 제어신호를 통해서 다양한 연산을 수행한다.

연산을 수행한 ALU는 결과를 내보는데 그 결과가 데이터가 될 수 있고 메모리 주소가 될 수 있다.
이 결과는 메모리에 저장이 되지 않고 일시적으로 레지스터에 저장이 된다.

메모리에 저장을 하지 않고 레지스터에 저장을 하는 이유는
CPU가 메모리에 접근을 하는 속도와 레지스터에 접근을 하는 속도를 비교해 보았을 때
레지스터에 접근하는 것이 훨씬 빠르다.
메모리에 자주 접근하게 되면 그 만큼 속도가 늦는다.
이는 프로그램 실행속도가 낮아지는 것이다.
그래서 메모리가 레지스터에 저장을 하는 것이다.

ALU는 결과값이 말고도 다은 하나를 더 내보는 데 이것이 플래그이다.
플래그는 ALU의 연산 결과에 대한 부가적인 정보이다.
연산의 결과가 음수인지, 양수인지, 0인지 등 결과 대한 부가 정보 뿐아니라
CPU에 관한 정보도 들어 있다.
이러게 연산결과와 CPU의 대한 부가 정보인 플래그를 저장하는 레지스터를 플래그 레지스터라고 한다.

제어장치

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

제어장치가 받아드리는 정보를 여러가지가 있다.

클럭 신호를 받아 드린다.
클럭은 컴퓨터의 모든 부품을 움직일 수 있게하는 시간 단위이다.
이 클럭 주기에 맞춰서 CPU는 작동을 한다.

해석할 명령어를 받아드린다.
명령어 레지스터에서 수행할 명령어를 받아드리고 해석한 뒤, 제어 신호를 통해 명령을 수행한다.

플래그를 받아 드린다.
플래그는 연산 결과의 부가 정보이다.
제어 신호를 보낼 때 참고해야 하는 정보이다.
이 플래그를 참고하여 제어 신호를 발생시킨다.

제어 버스를 통해 입출력 장치의 제어 신호를 받아 드린다.
CPU의 내부 뿐만 아니라 외부의 장치(입출력 장치)에서도 제어 신호를 발생시킬 수 있다.
CP는 이 제어 신호 또한 받아드린다.

제어 장치가 내보는 정보는 제어 신호이다.
이 제어 신호는 외부로 가는 것이 있고 내부로 가는 것이 있다.
내부로 보내는 신호는 레지스터나 ALU에게 보내고
외부로 보내는 신호는 입출력 장치나 메모리로 보낸다.

레지스터

레지스터는 CPU안에 있는 임시 저장 장치이다.
CPU가 많은 만큼 그에 따라 굉장히 많은 레지스터가 있고 CPU의 종류의 따라 레지스터의 종류도 다양하다.
여기서 대중화 되고 거의 많은 CPU가 공통으로 가지고 있는 레지스터를 알아보자.

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

프로그램 카운터는 메모리에서 가져올 명령어의 주소를 저장한다.
명령어 레지스터는 해석할 명령어, 메모리에서 읽어 드린 명령어를 저장한다.
메모리 주소 레지스터는 메모리 주소를 저장하는데 주소 값을 주소 버스로 보낼 때 이 레지스터를 거친다.
메모리 버퍼 레지스터는 메모리와 주고 받을 데이터를 저장하는 레지스터이다.

위 4개의 레지스터를 좀 더 확실하게 이해를 하기 위해 프로그램을 실행하는 과정을 보자

먼저, 프로그램이 실행이 되면 메모리의 저장이 된 프로그램의 명령어의 첫 주소가 프로그램 카운터에 저장이 된다.

이제 메모리 주소의 있는 명령어를 읽어 드리기 위해서 주소 버스를 이용할 수 있는 메모리 주소 레지스터로 메모리 주소를 옮긴다.
그리고 주소 버스로 받은 메모리 주소에서 명령어를 읽어와 메모리 버퍼 레지스터에 저장한다.
이 때, 프로그램 카운터는 메모리 주소를 카운팅해서 다음 명령어를 읽어드릴 준비를 한다.

저장이 된 명령어를 명령어 리지스터로 옮기고 제어 장치가 명령어를 해석해서 제어 신호를 발생시킨다.

범용 레지스터는 다양하고 일반적인 상황에서 사용을 한다.
메모리 주소 레지스터는 메모리 주소만 메모리 버퍼 레지스터는 데이터만 값을 저장하고 주고 받을 수 있다.
하지만 범용 레지스터느 데이터와 주소 모두를 저장할 수 있다.

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

스택 포인터베이스 레지스터는 레제스터를 이용한 주소 지정 방식을 통해서 이해하는 것이 편하다.

스택 주소 지정 방식스택스택 포인터를 이용한 주소 지정 방식이다.
스택은 한 쪽만 입구가 있는 저장 공간이다.
이 때, 스택에서 저장된 값들 중에 가장 상단에 저장된 값의 위치를 저장한 레지스터가 스택 포인터이다.

예를 들어
1번지부터 10번지 까지의 주소가 있는 스택에 1,2,3번지 까지 데이터가 저장이 되어 있다면
스택 포인터는 3번을 가르키고 있을 것이다.
만약 3번이 pop 되고 2번이 최상단이라면 스택포인터는 2번을 가르키고 있을 것이다.

베이스 레지스터를 알기 위해선 변위 주소 지정 방식을 알아야 한다.
변위 주소 지정 방식이란 오퍼랜드 필드 값에 특정 레지스터의 값을 더해서 유효 주소를 알아내는 방식이다.
변위 주소 지정 방식에는 2가지가 있는데 상대 주소 지정 방식베이스 레지스터 지정 방식이 있다.

상대 주소 지정 방식은 오퍼랜드와 프로그램 카운터의 값을 더해서 유효 주소를 구한다.
만약 프로그램 카운터가 1000이고 오퍼랜드의 값이 +3이라면 1003번지의 명령어를 가져온다.

베이스 레지스터 지정 방식은 오퍼랜드 값과 베이스 레지스터의 값을 더해서 값을 구한다.
베이스 레지스터가 기준 값을 제공해 주는 것이다.
베이스 레지스터의 값이 2000이고 오퍼랜드가 50라면 2000에서 50 떨어진 2050의 데이터를 가지고 온다.

명령어 사이클과 인터럽트

명령어를 처리하는 흐름이 명령어 사이클이다.
즉, 명령어 사이클은 명령어들이 일정한 주기로 실행이 되는 것을 말한다.
명령어 사이클은 인출 사이클실행 사이클로 구성되어 있다.

인출 사이클은 메모리에서 명령어를 CPU로 가지고 오는 과정을 말한다.
위에 프로그램 카운터부터 메모리 버퍼 레지스터의 과정까지를 말한다.

실행 사이클은은 제어 장치가 명령어를 해석하고 실행시키는 과정이다.

일반적으로 프로그램을 이루는 명령어들은 인출과 실행 사이클 반복하면 실행이 된다.
이 때, 간접 주소 지정 방식을 사용한다면 한 번에 명령어를 실행하지 못 한다.
왜냐햐면 명령어가 아니라 명령어가 담긴 메모리 주소가 담겨 있기 때문이다.
그래서 메모리에 한 번더 접근을 해야 한다.
이 단계를 간섭 사이클이라고 한다.

인터럽트는 CPU의 작업을 방해하는 신호이다.
인터럽트가 발생을 했다는 것은 CPU가 꼭 주목을 해야할 때이거나 CPU가 처리해야 할 다른 일이 생겼다는 것을 의미한다.

인터럽트에는 동기 인터럽트비동기 인터럽트가 있다.

동기 인터럽트는 CPU가 예상치 못한 상황, 즉 예외가 발생했을 때 일어난다.
예외를 처리하고 다시 작업을 시작할 때 경우에 따라 폴트, 트랩, 중단, 소프트웨어 인터럽트가 있다.

폴트는 에외가 발생한 부분부터 다시 시작하는 것을 말한다.
트랩은 예외가 발생한 다음부분부터 다시 시작하는 것을 말한다.
중단은 CPU가 프로그램을 중단해야 하는 심각한 오류를 만났을 때 실행한다.
스프트웨어 인터럽트는 시스템 호출을 실행 했을 때 나타난다.

비동기 인터럽트는 입출력 장치에 의해 인터럽트가 발생하는 것을 말한다.
비동기 인터럽트는 입출력 장치가 일을 다 했을 때 CPU에 알리기 위해서 사용을 하기 때문에 하드웨어 인터럽트라고 하기도 한다.

하드웨어 인터럽트를 이용하면 입출력 장치가 끝날 때까지 CPU가 바라볼 필요가 없다.
하드웨어 인터럽트를 받을 때까지 CPU는 다른 작업을 할 수 있다.

하드웨어 인터럽트 처리 순서는
입출력 장치가 CPU에 인터럽트 요청 신호를 보내고
CPU는 실행 사이클이 끝나고 명령어를 인출하기 전에 항상 인터럽트를 확인한다.
인터럽트 플래그를 통해서 인터럽트를 받아 드릴 수 있는 지 여부를 확인한다.
인터럽트를 받아 드리면 CPU가 하는 일 백업을 하고 인터럽트 벡터를 참고하여 인터럽트 서비스 루틴을 실행한다.

조금 더 자세히 설명을 하면
인터럽트 요청 신호로 입출력 장치가 CPU에 요청 신호를 보내면 CPU는 인터럽트 플래그를 보고 받아 드릴지 말 지를 결정한다.
만약 불가능하다면(불가능이라고 해도 무시하고 인터럽트를 실행하는 경우가 있음) 거부하고 가능하다면 받아 드린다.
받아 드리면 인터럽트 벡터를 참고 하는데

인터럽트 벡터는 인터럽트가 발생 했을 때 어떻게 대처해야 하는 지, 어떤 입출력 장치에서는 어떤 인터럽트 서비스 루틴을 실행해야 하는 지를 식별하기 위한 정보이다.

인터럽트 벡트를 참고하여 인터럽트 서비스 루틴을 실행한다.
인터럽트 서비스 루틴은 인터럽트를 처리하기 위한 프로그램이다.
어떤 인터럽트가 발생했을 때 해당 인터럽트를 어떻게 처리하고 작동해야 할 지에 대한 정보로 이루어진 프로그램이다.

인터럽트가 발생했을 때 실행중이던 프로그램의 정보를 어딘가에 저장을 해야 하는데
바로 메모리의 스택에 저장을 한다.
그리고 인터럽트가 끝나면 다시 가지고 와서 프로그램을 실행한다.

위 사진 처럼 CPU가 명령어를 처리하는 과정은 인출, 실행, 간접, 인터럽트 사이틀들이 서로 상호작용하면 돌아간다.

profile
개발 공부 하기 위해 만든 블로그

0개의 댓글