04-3 명령어 사이클과 인터럽트 CPU가 메모리의 명령어를 실행하는 데는 정해진 패턴, 흐름이 있다. 이 흐름 또는 주기를 명령어 사이클이라고 한다. 근데 간혹 이 정해진 흐름을 끊기도 하는데, 이 흐름을 끊는 신호를 인터럽트라고 함.
명령어사이클: 인출>실행>인출>실행>인출..반복 1. 인출 사이클: 가장 먼저 메모리에 있는 값을 CPU로 가져와야한다. 이를 인출이라 함 2. 실행 사이클: CPU에 가져온 값을 실행함 근데 인출 이후 메모리 접근이 더 필요한 경우가 있다(오퍼랜드는 주소필드라고도 불린다는 점!) → 1.5 간접사이클
1. 인출 사이클
1.5 간접 사이클
2. 실행 사이클
인터럽트: CPU가 꼭 주목 또는 먼저 처리해야할 다른 일이 생겼을 때 - 인터럽트 종류: 동기 인터럽트(예외), 비동기 인터럽트(하드웨어 인터럽트)
동기인터럽트(exception) - CPU가 예기치 못한 상황을 접했을 때 발생 - 예) 메모리 갔더만 원하는 데이터가 없거나 실행할 수 있는 명령어가 없거나 디버깅..등
비동기 인터럽트: 주로 입출력장치에 의해 발생 - 알림 같은 거임 ㄴ 예1) 프린터가 CPU에게 "나 프린트 다했어!" ㄴ 예2) 키보드가 CPU에게 "타이핑 발생했어!" - 왜 있는거임?? 일반적으로 입출력 장치의 입출력 작업은 CPU에 비해 느림 → (인터럽트 없다면)cpu가 입출력 작업 완료 여부 확인을 주기적으로 해줘야함...그래서 인터럽트 둬서 CPU가 굳이 계속 확인할 필요 없도록 하기 위해 인터럽트 사용
인터럽트 처리 순서 (=인터럽트 서비스루틴을 실행하고 본래 수행하던 작업으로 다시 돌아오는 과정+그리고 인터럽트 시작 주소는 인터럽트 벡터를 통해 알 수 있다) 1. 입출력장치 > CPU 인터럽트 요청 신호 발송: 입출력장치가 cpu에게 말한다 "지금 끼어들어도 됨?" 2. CPU가 실행 사이클 끝내고 명령어 인출 전 항상 인터럽트 여부 확인. 3. CPU가 인터럽트 요청 확인 후 인터럽트 플래그를 통해 현재 인터럽트를 받을 수 있는지 확인 ㄴ플래그 레지스터에서 인터럽트 받아들일 수 있는지 확인하는 값. 이걸로 CPU가 이렇게 얘기할 수 있는거임 "지금은 안되요~장사 안해요~" ㄴ 근데 모든 인터럽트를 인터럽트 플래그로 막을 수 있는 건 아님. 긴급한 건이라면 이 플래그값 상관없이 인터럽트 들어가기도 함(Non Maskable Interupt) 4. 인터럽트 받아들일 수 있다면 CPU는 지금까지 작업 백업 5. CPU는 인터럽트 벡터(인터럽트를 구분하기 위한 정보) 참조해 인터럽트 서비스 루틴 실행 ㄴ 인터럽트 서비스 루틴마다 메모리에서 차지하는 주소가 달라..그니깐 인터럽트 벡터 값을 통해 CPU가 인터럽트 서비스루틴을 메모리의 어디서부터 시작하면 되는지 알 수 있음 6. 인터럽트 서비스 루틴(메모리 안에서 실행되는 프로그램) 끝나면 (4)에서 백업해 둔 작업 복구 후 실행 재개 ㄴ 인터럽트 서비스 루틴은 인터럽트가 발생했을 때 어떻게 처리하면 좋을지 적혀있는 프로그램이라 생각하면 됨(like "키보드 타이핑에는 이렇게 행동하세요") ㄴ 근데 어떻게 복구함? 기존에 레지스터에 있던 값들을 어디 보관? → 지금까지 작업내용은 stack(메모리 내 스택 영역)에 백업해놓음.
데이터? - 정적인 정보 - 컴퓨터가 주고 받는 정보, 내부에 저장된 정보를 얘기하기도 함
명령어? - 컴퓨터는 결국 명령어 처리 기계 - 명령어는 컴퓨터를 실질적으로 움직이는 정보 *데이터는 명령어를 위한 재료 - 명령어 예) 1과2를 더하라(1과2는 데이터)
컴퓨터 4가지 핵심 부품(컴퓨터 종류를 막론하고 거의 동일) - CPU, 메모리, 보조기억장치, 입출력장치 *메모리는 주기억장치의 줄임말. 주기억장치는 원래 2종류(RAM, ROM) 근데 이 학습과정에선 RAM을 지칭한다고 보면 됨
핵심부품이 모이는 판(부착하는 판): 마더보드, 메인보드 메인보드에 부착된 부품 간 정보를 주고 받을 수 있는 통로: 버스 버스 중에서 제일 중요한 버스(like 척추): 시스템 버스
메모리? - 현재 실행되는 프로그램(프로세스)의 명령어와 데이터를 저장하는 부품 (=프로그램을 실행하려면 데이터와 명령어가 메모리에 있어야한다) *페이징기법을 사용하면 꼭 메모리에 있어야 하는 건 아닐 수도 있음* - 메모리의 주요 개념: 주소 ▶️ 접근 또는 필요로하는 데이터나 명령어가 메모리 내 어디에 위치해있는지 알 수 있는 정보
CPU? - 컴퓨터의 두뇌와 같은 부품☆☆☆ - 메모리에 저장된 명령어를 읽어 들이고 해석하고 실행하는 장치 - CPU 핵심 부품 3가지: ALU(산술논리연산장치), 제어장치(control unit), 레지스터
- ALU? 그냥 계산기임 - 레지스터? CPU 내부에 있은 작은 저장 장치(임시 저장 장치). 보통 CPU 내 여러 개 있음 - 제어장치? 제어신호(컴퓨터의 부품을 관리하고작동시키기 위한 전기신호로 여러 종류가 있다)라는 일종의 전기신호를 내보내고 명령어를 해석하는 장치
제어신호 종류: 메모리 읽기신호, 메모리 쓰기신호 - CPU가 메모리 값 읽고 싶을 때? 읽기 신호 ㄴ CPU가 메모리에 읽기 신호(1번지 읽어)를 보냈다면? 메모리가 명령어를 레지스터에 갖다둠. 그럼 제어장치가 레지스터에 있는 명령어를 해석함 -> 이를 기반으로 다음 처리 수행 - CPU가 메모리에 값을 쓰고 싶을 때? 쓰기 신호
보조기억장치 - 왜 필요해? 메모리(RAM)은 비쌈. 그리고 메모리는 전원 꺼지면 정보를 읽어버림(휘발성 저장장치) ▶️ 전원이 꺼져도 정보를 보관할 수 있는 장치 필요 - 실행되지 않는 프로그램 보관하는 장소 *메모리에는 실행할 정보를 저장하고, 보조기억장치에는 보관할 정보를 저장한다.
메인보드? - 컴퓨터의 4가지 핵심 부품을 부착하는 판 - 버스를 통해서 부품 간 정보를 주고 받음
버스? - 메인보드에 있는 핵심부품들 간에 정보를 주고 받을 수 있는 통로(다양한 종류가 있음) - 제일 중요한 통로를 시스템 버스라고 함
시스템버스? - 주소 버스(주소 통로) / 데이터버스(데이터 통로) / 제어 버스(제어신호 통로)로 구성
02-1 0과1로 숫자를 표현하는 방법 컴퓨터의 정보단위. 비트 - 비트(bit): 0과 1로 표현하는 가장 작은 정보 단위 - 프로그램은 수많은 비트로 이뤄져 있음 - 다만 일상적으로 비트라는 단위를 쓰진 않음(바이트, 메가바이트, 킬로바이트, 메가바이트, 기가바이트, 테라바이르..등을 사용) - 8bit=1byte - 1,000byte=1kB - 1,000kB=1MB... - 1,000MB=1GB - 1,000GB=1TB
워드(word) - CPU가 한번에 처리할 수 있는 정보의 크기 단위 - 예1) aCPU가 한번에 32bit씩 처리할 수 있다면 해당 CPU의 1워드=32bit - 예2) bCPU가 한번에 64bit씩 처리할 수 있다면 해당 CPU의 1워드=64bit - half word: 워드의 절반 크기 - full word: 워드 크기 - double word: 워드의 2배 크기
0과1로 숫자 표현 방법. 이진법(binary) - 숫자가 1을 넘어가는 시점에 자리 올림 - 십진법(decimal)은 9 넘어가는 시점에 자리올림 - 이진수로 음수 표현: 2의 보수 ㄴ 어떤 수를 그보다 큰 2^n에서 뺀 값 ㄴ 모든 0과 1을 뒤집고 1을 더하면 됨 ㄴ CPU가 음수와 양수를 구분하는 법: CPU 내부에 플래그 레지스터라는 게 있음. 거기에 양수인지 음수인지 표시되어 있음. 근데 이진법만 쓰면 데이터 길이가 너무 길어짐. 그래서 십육진법 쓰는 경우도 있음 - 0~9까지는 십진법과 동일. - 10(십진법)은 a, 11(십진법)은 b...15(십진법)는 f. 16(십진법)에 자리 올림되어서 10 - 코드상 십육진법 표기 시, 0x15라고 표기할 수 있음 - 십육진법 왜 써? 이진수<->십육진수 변환이 쉬움
02-2 0과 1로 문자를 표현하는 법 - 문자집합(character set): 컴퓨터가 이해할 수 있는 문자 모음 - 인코딩(encoding) ㄴ 코드화 과정 ㄴ 문자를 0과 1의 문자코드로 변환하는 과정 - 디커딩(decoding) ㄴ 코드 해석 과정 0과1의 문자코드를 문자로 변환하는 과정
아스키코드(대중적인 문자집합) - 초창기 문자집합 - 7비트로 하나의 문자 표현(8비트 중 1비트는 오류 검출을 위해 사용되는 패리티 비트(parity bit) - 한글을 포함한 다른 언어 문자 표현 불가 >언어별 인코딩 방식의 등장
한글 인코딩: 완성형 VS 조합형 - 한글 특징: 초성 중성 종성 조합으로 단어가 이루어짐(영어와 다름) - EUC-KR ㄴ완성형 인코딩 방식 ㄴ글자 하나에 2바이트(16비트) 크기의 코드 부여함=한 글자를 표현하는데 16진수 4자리가 필요 ㄴ문제점: 지원하지 않는 글자도 있음(뷁, 괗 등) ㄴ문데점: 다국어 지운 프로그램 개발 시에는 언어벌로 인코딩 방식을 모두 이해해야함 >통일된 문자집합에 대한 니즈 > 유니코드문자집합과 utf 인코딩 방식 탄생
유니코드 - 통일된 문자집합 - 한글 영어부터 이모티콘 특수문자까지 가능 - 현재 문자 표현에 있어 매우 중요 - 인코딩 방식에 따라, 글자를 비트로 변환하는 방식에 따라 utf-8, utf-16...등으로 나뉨
03-1 소스코드와 명령어 - 개발자가 사용하는 언어: python, JAVA..등 고급 언어=개발자가 읽고 쓰기 편하게 만들어진 언어 - 컴퓨터가 이해하고 실행하는 언어: 저급 언어
저급 언어의 종류: 기계어, 어셈블리어 - 명령어로 이루어진 언어: 기계어: 2진수 또는 16진수로 표현됨 - 사람들이 그나마 좀 읽기 편하게 변환된 언어: 어셈블리어 - 어셈블리어는 기계어와 다르게 소스코드에 직접 입력하기도 함
고급언어는 저급언어로 변환되어 컴퓨터가 명령어를 처리함 - 고급>저급언어변환 방식의 종류: 컴파일 방식, 인터프리트 방식 ㄴ 고급언어 중 컴파일 언어 -> 컴파일 방식 ㄴ 고급언어 중 인터프리트 언어 -> 인터프리트 방식
컴파일언어 - 고급언어>저급언어 변환과정을 컴파일이라고 함 - 컴파일러에 의해 고급언어(소스코드)가 저급언어로 변환됨 - 컴파일에 의해 변환된 저급언어는 목적코드라고 함 - 컴파일러가 소스코드 전체를 검토(오류 여부, 미사용 변수 유무, 최적화 가능 여부 등) > 이후 소스코드 전체를 목적코드로 통째로 컴파일 진행 -> 오류가 하나라도 있으면 변환을 진행하지 않음
인터프리트 언어 - 인터프리터라는 특수한 프로그램에 의해 소스코드를 한줄씩 실행됨(저급언어로 변환됨) - 소스코드 전체가 저급언어로 변환되기까지 기다릴 필요가 없음 - 에러 발생 코드 전까지 다 저급언어로 변환
*cpu종류와 컴파일러 종류에 따라 저급언어가 달리질 수 있음
*컴파일언어, 인터프리터언어가 정확하게 양분되는 건 아님(흑백논리X)
03-2 명령어의 구조 명령어 =컴퓨터가 수행할 연산+연산에 사용될 데이터가 저장된 위치 =연산코드+오퍼랜드
어셈블리어도 명령어다 =어셈블리어도 연산코드와 오퍼랜드로 이뤄져있다.
오퍼랜드? - 연산에 사용될 데이터 or 연산에 사용될 데이터가 저장된 위치(오프랜드가 들어가는 공간에는 얘를 훠어어얼씬 더 자주 들어감) -> 그래서 오퍼랜드를 주소필드라고 부르기도 함 - 하나의 명령어에 오퍼랜드는 없을 때(0주소 명령어)도 1개(1주소 명령어)일 수도, 2개(2주소 명령어)일 수도..여러 개일 수도 있음.
연산코드 - 컴퓨터가 수행할 연산 - CPU마다 갖고 있는 연산코드 종류는 다양한데 그래도 공통적으로 데이터 전송, 산술/논리 연산, 제어 흐름 변경, 입출력 제어가 있음
연산코드의 종류1) 데이터 전송 - 데이터 이동, CPU로 이동, 저장, 스택에 저장, 가져오기 등 *STACK: LAST IN FIRST OUT 구조(한 쪽이 막힌 듯한 구조) *OUE: FIRST IN FIRST OUT 구조(선입선출 구조)
연산코드 종류3) 제어 흐름 변경 - 특정 메모리 주소로 실행의 순서를 옮기는 연산 - 조건 부합하면 딴 데부터 수행해라, 실행 순서 바꿔라, 실행을 멈춰라
연산코드 종류4) 입출력 제어
주소필드를 쓰는 이유 - 크기가 제한되어 있음 -> 들어갈 수 있는 데이터 크기가 제한됨
유효주소: 연산에 사용될 데이터가 저장된 위치
명령어 주소 지정 방식 - 연산에 사용할 데이터가 저장된 위치를 찾는 방법 - 유효 주소를 찾는 방법 - 다양한 명령어 주소 지정 방식들 - 종류1) 즉시 주소 지정 방식 ㄴ 연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시 -> 오퍼랜드 크기가 제한되기에 사용가능한 데이터가 한정됨. 근데 데이터를 찾아다니지 않아도 되서 간단하고 빠름 - 종류2) 직접 주소 지정 방식 ㄴ 오퍼랜드 필드에 유효 주소를 직접 명시 ㄴ 유효 주소를 표현할 수 있는 크기가 연산코드만큼 줄어듦. - 종류3) 간접 주소 지정 방식 ㄴ 유효주소의 주소를 명시하는 방식 -> 느림 - 레지스터 주소 지정 방식 ㄴ 연산에 사용될 데이터가 저장된 레지스터 명시 ㄴ CPU가 메모리보단 레지스터에 접근하는 게 훨 빠름(레지스터는 CPU 안에 있음. 메모리는 CPU 밖에 있음) - 종류4) 레지스터 간접 주소 지정 방식 ㄴ 연산에 사용할 데이터를 메모리에 저장하고 이 주소를 저장한 레지스터를 오퍼랜드 필드에 명시
03 추가: c언어의 컴파일 과정 컴파일과정: 전처리기>컴파일러>어셈블러>링커
04-1 ALU와 제어장치 CPU를 구성하는 부품 ALU는 계산해는 장치 제어장치는 제어 신호를 발생시키고 명령어를 해석하는 장치
ALU가 받아들이는 정보 - 레지스터한테서 피연산자를 받아들임 - 제어장치로부터 제어신호(수행할 연산)를 받아들임 >ALU는 위 정보를 바탕으로 계산 수행. 그리고 이 결과값을 레지스터로 내보냄 ?왜 메모리가 아닌 레지스터에 저장? CPU가 메모리에 접근하는 것보다 레지스터에 접근하는 게 훨 빠름. 추가로 플래그라는 것도 내보냄. 플래그란? 연산정보에 대한 부가정보. 이건 플래그 레지스터라는 곳으로 내보냄 *연산결과가 음수이먄 음수라는 플래그값이, 0이면 0이라는 플래그값이 플래그 레지스터에 담김. 오버플로우여부(연산결과가 연산결과를 담을 수 있는 레지스터보다 큰 경우)도 플래그에 명시됨
플래그 레지스터는 0과 1로 표현됨. 예를 들어 제로플래그가 1이면 연산결과가 0이라는 걸 표현한 거임.
제어장치가 받아들이는 정보: 클럭, 해석할 명령어, 플래그 - 클럭? 제어장치가 받아들이는 신호. 컴퓨터의 모든 부품을 일사분란하게 움직일 수 있게 하는 단위. 시계처럼 일정 주기로 발생하는 신호. 클러규신호 단위에 맞춰 명령어가 수행됨. - 해석할 명령어? 명령어 레지스터라는 특수한 레지스터에 저장됨. 이걸 받아들이고 이를 해석하여 제어신호를 내보냄. - 플래그? Cpu가 받아들이는 부가정보. 근데 명령어 해석과정에서도 필수적인 정보임. - 제어신호? 제어신호는 사실 제어장치만 발생시캘 수 있는게 아니라서 받아들임
04-2 레지스터 레지스터: CPU 내부에 있는 작은 임시 저장장치 - 프로그램 속 명령어와 데이터는 실행 전후로 레지스터에 저장 > 이거 프로그래머가 관찰할 수도 있음 - LOWLEVEL개발자는 이 레지스터 까보는 경우도 많음. 레지스터 종류는 다양(CPU마다 종류도 다름)하고 역할도 다 다름.
종류1) 프로그램카운터 - 메모리에서 가져올 명령어의 주소 저장 종류2) 명령어 레지스터 - 해석할 명령어를 저장함(메모리에서 갓(방금) 읽어 들인 명령어) 종류3) 메모리 주소 레지스터 - 메모리의 주소를 저장함 - cpu가 주소버스로 정보 내보낼 때 거치는 레지스터 종류4) 메모리 버퍼 레지스터 - 메모리와 주고받을 값(데이터, 명령어)을 저장 - 데이터버스로 주고받을 때 거치는 레지스터 종류5) 플래그 레지스터 - 연산결과 또는 cpu상태에 대한 부가적인 정보 종류6) 범용 레지스터 - 다양하고 일반적인 상황에서 자유롭게 쓸 수 있음(주소도, 데이터도 담을 수 있고 그리고 얘는 여러 개가 있음) 종류7) 스택 포인터 > 주소 지정에 사용 - 스택 주소 지정 방식에 사용. - 스택의 꼭대기, 즉 스택이 어디까지 차있는지를 알려주는 레지스터 *스택은 메모리 안에 있음(스택 영역) 종류8) 베이스 레지스터 > 주소 지정에 사용 - 변위 주소 지정 방식에 사용되는 레지스터 - 오퍼랜드 필드 값을 변위로 보고 특정 레지스터 값을 더하여 유효 주소를 얻음(오퍼랜드 필드 + 레지스터값) ㄴ 방식1)오퍼랜드 필드 값+프로그램카운터(상대 주소 지정 방식) ㄴ 방식2) 오퍼랜드 필드 값+베이스 레지스터