: CPU 내부에서 계산을 담당한다.
: 레지스터를 통해 피연산자 & 제어장치로부터 수행할 연산을 알려주는 제어신호를 받는다.
: 피연산자와 제어신호를 가지고 연산을 실행
ALU는 연산을 할 경우 메모리에 저장하는 것이 아니라 일시적으로 레지스터에 저장된다.
: 연산할 때마다, 결과를 메모리에 저장한다면 CPU는 메모리에 자주 접근하게 되어 CPU의 프로그램 실행 속도를 늦출 수 있기에 레지스터에 저장
ALU는 연산 값고 함께 플래그를 내보낸다. 때때로 ALU는 연산 값 외 추가 정보를 내보내야 할 상황이 생긴다.
연산 결과에 대한 추가적인 상태 정보를 flag라고 한다.
ex)
ALU의 연산 결과가 '음수'일 경우 > '방금 계산한 결과는 음수'라는 추가 정보를 내보낸다.
연산 결과가 연산 결과를 담을 레지스터보다 클 경우 > '결과값이 너무 크다'라는 추가 정보를 내보낸다.(= 오버플로우(Overflow))
부호 플래그
: 연산 결과의 부호를 나타낸다.
ex)
부호 플래그 1 > 계산 결과 음수
부호 플래그 0 > 계산 결과 양수
제로 플래그
: 연산 결과가 0인지 나타낸다.
ex)
제로 플래그 1 > 연산 결과 0
제로 플래그 0일 경우 > 연산 결과는 0이 아님을 의미
캐리 플래그
: 연산 결과 올림수나 빌림수가 발생했는지를 나타낸다.
ex)
캐리 플래그 1 > 올림수, 빌림수가 발생
캐리 플래그 0일 경우 > 발생하지 않음
-오버플로우 플래그
: 오버플로우 발생했는지 나타낸다.
ex)
오버플로우 플래그가 1일 경우 오버플로우가 발생
오버플로우 플래그가 0일 경우 > 발생하지 않음
-인터럽트 플래그
: 인터럽트가 가능하지를 나타낸다.
ex)
인터럽트 플래그가 1일 경우 인터럽트가 가능
인터럽트 플래그가 0일 경우 > 불가능
플래그는 CPU가 프로그램을 실행하는 도중 반드시 기억해야 하는 일종의 참고 정보
- 연산 값은 > 레지스터에 저장
- flag는 > flag 레지스터에 저장
제어장치는 제어 신호를 내보내고, 명령어를 해석하는 부품
제어 신호는 컴퓨터 부품들을 관리, 작동시키기 위한 일종의 전기 신호
컴퓨터의 부품들은 클럭이라는 박자에 맞춰 작동할 뿐, 한 박자마다 작동하는 것은 아니다.
: 하나의 명령어가 여러 클럭에 걸쳐 실행될 수 있다.
제어장치는 플래그 레지스터 속 플래그 값을 받음
플래그는 ALU 연산에 대한 추가적인 상태 정보
제어장치는 플래그 값을 참고하여 제어 신호를 발생
제어장치는 시스템 버스, 그 중에서 제어 버스로 전달된 제어 신호를 받음
제어 신호는 CPU, 입출력장치를 비롯한 CPU 외부 장치도 발생시킬 수 있다. 제어장치는 제어 버스를 통해 외부로부터 전달된 제어 신호를 받는다.
1) 메모리에 저장된 값을 읽거나 새로은 값을 쓰고 싶다면 메모리로 제어 신호를 보냄
2) 입출력장치의 값을 읽거나 입출력장치에 새로운 값을 쓰고 싶을 때 입출력장치로 제어 신호를 보냄
프로그램 실행 전후로 명령어와 데이터는 레지스터에 반드시 저장됨
CPU안에는 다양한 레지스터가 있다.
레지스터 종류
1) 프로그램 카운터
2) 명령어 레지스터
3) 메모리 주소 레지스터
4) 메모리 버퍼 레지스터
5) 플래그 레지스터
6) 범용 레지스터
7) 스택 포인터
8) 베이스 레지스터
--
1) 프로그램 카운터(Program Counter) = 명령어 포인터(IP : Instruction Pointer)
: 프로그램 카운터는 메모리에서 가져올 명령어의 주소 = 메모리에서 읽어 들일 명령어의 주소를 저장한다.
2) 명령어 레지스터(IR : Instruction Register)
: 해석할 명령어 = 방금 메모리에서 읽어 들인 명령어를 저장하는 레지스터
: 제어장치는 명령어 레지스터 속 명령어를 받음> 해석 > 제어신호 내보내기
3) 메모리 주소 레지스터(MAR : Memory Address Register)
: 메모리 주소를 저장하는 레지스터
: CPU가 읽어 들이고자 하는 주소 값을 주소 버스로 보낼 때 메모리 주소 레지스터를 거친다.
4) 메모리 버퍼 레지스터(MBR : Memory Buffer Register) = 메모리 데이터 레지스터(MDR : Memory Data Register)
: 메모리와 주고받을 값(데이터와 명령어)을 저장하는 레지스터
순차적인 실행 흐름이 끊기는 경우
: 프로그램 카운터가 꾸준히 증가하며 프로그램을 차례대로 실행
but, 종종 프로그램 카운터 실행 명령어의 다음 번지 주소가 아닌 전혀 다른 값으로 업데이트 되는 경우가 있다.
- JUMP, CONDITIONAL JUMP, CALL, RET와 같이 특정 메모리 주소롤 실행의 흐름을 이동하는 명령어가 실행되었을 때 차레대로 실행되지 않고 변경된 주소가 저장된다.
5) 범용 레지스터(General Purpose Register)
범용 레지스터는 데이터와 주소 모두 저장할 수 있다.
CPU 안에는 여러 범용 레지스터가 있다.
메모리 버퍼 레지스터 = 데이터 버스로 주고받을 값만 저장
메모리 주소 레지스터 = 주소 버스로 내보낼 주소값만 저장
6) 플래그 레지스터(Flag Register)
연산 결과 또는 CPU 상태에 대한 부가적인 정보를 저장
프로그램 카운터(= 명령어 포인트 : Instruction Pointer) 에서 명령어의 주소를 저장 > 이를 가져와서 메모리 주소 레지스터가 메모리 버스를 통해 메모리의 주소를 저장 > 제어신호(메모리 읽기)를 가지고 와 메모리 주소 레지스터에 전달 > 메모리 안에 있는 데이터를 데이터 버스를 통해 메모리 버퍼 레지스터로 전달! / 프로그램 카운터는 다음 명령어를 위해 +1 > 명령어 레지스터로 저장(명령어의 주소를 저장했기 때문에 > 명령어 레지스터에 저장)
프로그램 카운터, 스택 포인터, 베이스 레지스터는 주소 지정에 사용될 수 있는 특별한 레지스터
스택 주소 지정 방식은 스택과 스택 포인터를 이용한 주소 지정 방식이다.
stack은 메모리 안에 있다.(메모리 안에 스택처럼 사용할 영역)
이를 스택 영역이라고 한다.
변위 주소 지정 방식은 오퍼랜드 필드의 값(변위)과 특정 레지스터의 값이 더하여 유효 주소를 얻어내는 방식이다.
연산코드(이런 내용을 수행해라) + 레지스터(이 레지스터 값과) + 오퍼랜드(이 주소를 더한 곳에 있는 데이터로)
변위 주소 지정 방식은 오퍼랜드 필드의 주소와 어떤 레지스터를 더하는지에 따라 2-1), 2-2)로 나뉜다.
ex)
1) 오퍼랜드가 -3 (음수) 였다면 CPU는 읽어 들이기로 한 명령어로부터 3번째 이전 번지로 접근
2) 오퍼랜드가 3(양수) 였다면 CPU는 읽어 들이기로 한 명령어로부터 3번째 이후 번지로 접근
(121P-122P 그림 참고)
베이스 레지스터 = 기준 주소
오퍼랜드 = 기준 주소로부터 떨어진 거리
즉, 베이스 레지스터 주소 지정 방식 = 베이스 레지스터 속 기준 주소로부터 얼마나 떨어져 있는 주소에 접근할 것인지를 연산하여 유효 주소를 얻어내는 방식
ex)
베이스 레지스터 = 200
오퍼랜드 = 40
기준 주소 200번지로부터 40만큼 떨엊인 240번지로 접근하라
명령어 사이클(Instruction cycle)
프로그램이 명령어를 실행할 때 각각의 명령어들은 일정한 주기가 반복되며 실행된다. 이 주기를 명령어 사이클이라고 한다.
<명렁어 사이클 과정>
1. 인출 사이클(featch cycle)
: 명령어를 Memory에서 CPU로 가져온다.
2. 실행 사이클(execution cycle)
: 명령어 실행
: 제어장치가 명령어 레지스터에 담긴 값을 해석 및 제어 신호를 발생
어떤 명령어는 인출 사이클 > 실행 사이클로 실행
어떤 명령어는 인출 사이클 > 간접 사이클 > 실행 사이클로 실행
인터럽트(interrupt)
interrupt = '방해하다, 중단시키다'를 의미
CPU 작업을 방해하는 것을 인터럽트라고 한다.
<인터럽트 종류>
1. 동기 인터럽트(Synchronous interrupts)
: CPU에 의해 발생하는 인터럽트
: CPU가 명령어들을 수행인 상황에 마주쳤을 때 발생
: 예외(Exception)이라고 부른다.
예외의 종류
1. 폴트(fault)
: 예외를 처리한 직후 예외가 발생한 명령어부터 실행을 재개
2. 트랩(trap)
: 예외를 처리한 직후 예외가 발생한 명령어의 다음 명령어부터 실행을 재개
: 주로 디버깅 시 사용
3. 중단(abort)
: CPU가 싫행 중인 프로그램을 강제로 중단시킬 수밖에 없는 심각한 오류를 발견했을 때 발생
4. 소프트웨어 인터럽트(softward interrupt)
: 시스템 호출이 발생했을 때 나타난다.
하드웨어 인터럽트
하드웨어 인터럽트는 알림과도 같다.
CPU가 입출력 장치인 프린트 완료 여부를 주기적으로 확인한다면, CPU가 다른 작업을 진행할 수 없다. 하드웨어 인터럽트가 있다면, 이러한 프린트 완료 여부를 주기적으로 확인하지 않고 CPU가 프린터로부터 프린터 완료 인터럽트를 받을 때까지 다른 작업을 처리할 수 있다.
<하드웨어 인터럽트 처리 순서>
1. 입출력장치는 CPU에 인터럽트 요청 신호를 보낸다.
2. CPU는 실행 사이클이 끝나고 명령어를 인출하기 전 항상 인터럽트 여부를 확인한다.
3. CPU는 인터럽트 요청을 확인하고 인터럽트 플래그를 통해 현재 인터럽트를 받아들일 수 있는지 여부를 확인
4. 인터럽트를 받아들일 수 있다면 CPU는 지금까지의 작업을 백업합니다.
5. CPU는 인터럽트 벡터를 참조하여 인터럽트 서비스 루틴을 실행한다.
6. 인터럽트 서비스 루틴 실행이 끝나면 4번에서 백업해 둔 작업을 복구하여 실행을 재개합니다.
인터럽트 요청 신호
: 인터럽트는 CPU의 정상적인 실행 흐름을 끊는 것이기에 다른 누군가가 인터럽트하기 전에 끼어들어도 되는지 CPU에 물어봐야 한다.
CPU가 인터럽트 요청을 수용하기 위해서 플래그 레지스터의 입터럽트 플래그(interrupt flag)가 활성화되어 있어야 한다.
: 하드웨어 인터럽트를 받아들일지, 무시할지를 결정하는 플래그
: 인터럽트 플래그 '불가능' = CPU는 전달받은 인터럽트 요청을 무시
: 인터럽트 플래그 '가능' = CPU는 인터럽트 요청 신호를 받아들이고 인터럽트를 처리
Maskable Interrupt
: 하드웨어 인터럽트에서 인터럽트 플래그로 막을 수 있는 인터럽트
Non maskable Interrupt
: 하드웨어 인터럽트에서 인터럽트 플래그로 막을 수 없는 인터럽트
: 정전 / 하드웨어 고장
인터럽트 서비스 루틴(ISR : Interrupt Service Routine)
: 인터럽트를 처리하기 위한 프로그램
: 인터럽트 핸들러(Interrupt Handler)라고 부른다.
: 어떤 인터럽트가 발생했을 때 해당 인터럽트를 어떻게 처리하고 작동해야 할지에 대한 정보로 이루어진 프로그램
: 메모리에 저장되어 있다.
인터럽트 벡터(Interrupt vector)
: 서비스 루틴을 식별하기 위한 정보
: CPU는 수많은 인터럽트 서비스 루틴을 구분하기 위해 인터럽트 백터를 이용한다.
: 인터럽트 벡터를 알면 서비스 루틴의 시작 주소를 알 수 있다.
: 인터럽트 벡터를 이용하여 서비스 루틴을 처음부터 실행할 수 있다.
CPU가 작업을 수행 도중 인터럽트가 발생한 경우
1. 인터럽트 요청 받기 전에 CPU가 수행하고 있던 일은 stack에 저장
2. 인터럽트 서비스 루틴 시작 주소가 위치한 곳(인터럽트 벡터를 참조하여 서비스 루틴 시작 주소를 알아낸다.)에 프로그램 카운터 값을 갱신 후 인터럽트 서비스 루틴을 실행
3. 인터럽트 처리 완료 후 stack에 저장해 둔 값을 둘러와 이전에 수행하던 작업을 재개
혼자 공부하는 컴퓨터구조 + 운영체제
04. CPU의 작동 원리 (104p - 139p)