쿠버네티스란 컨테이너 오케스트레이션 도구입니다. 간단히 말해, 여러 컨테이너를 관리하는 도구입니다. 앞서 도커 컴포즈에 관한 글에서 도커 컴포즈와 쿠버네티스를 간단히 비교한 적이 있습니다. 도커 컴포즈는 여러 컨테이너 생성 및 폐기가 가능하지만, 관리 기능은 없다고 하였습니다. 반면 쿠버네티스에는 관리 기능이 있죠. 뿐만 아니라 쿠버네티스는 동일 구성의 컨테이너 여러 세트를 생성하는 것에도 적합한데, 이 부분에서 쿠버네티스의 컨테이너 관리 기능 부각되는 게 아닐까 싶습니다. 만약 여러 컨테이너를 다루는 데 관리 기능이 없다면? 그랬다면, 엔지니어가 일일이 컨테이너 상태를 모니터링하며 장애가 발생할 때마다 컨테이너를 버리고 만들어주는 일을 해줘야만 했을 겁니다. 하지만 쿠버네티스는 바로 이 컨테이너 관리를 해주는 도구인 것이죠.
그럼 여러 컨테이너를 생성하고 또 관리하는 기능은 어떻게 제공되는 걸까요? 바로 이 작동 원리를 이해하기 위해선 먼저 쿠버네티스 구조를 이해할 필요가 있습니다.
쿠버네티스 구조
쿠버네티스는 여러 컨테이너를 관리할 수 있는 오케스트레이션 도구입니다. 따라서 이를 활용해 컨테이너 그룹을 배포할 수 있는데요. 중요한 건 쿠버네티스는 컨테이너 그룹을 포함해 클러스터라는 것을 만들어낼 수 있다는 점입니다.
클러스터란 컨트롤 플레인과 데이터 플레인으로 구성된 하나의 쿠버네티스 시스템을 의미합니다.
왜 클러스터를 배포할까요? 만약 컨테이너만 배포한다면 어땠을까요?
그럼 쿠버네티스는 오케스트레이션 도구라 불릴 수 없었을 것입니다. 이점에서 쿠버네티스에는 관리를 위한 구성요소가 있어야 한다는 걸 생각해볼 수 있습니다. 이 관리를 담당하는 레이어가 컨트롤 플레인이고 컨테이너를 띄우고 서로 연결될 수 있도록, 일명 실무자와 같은 역할을 수행하는 레이어가 데이터 플레인입니다.
만약 도커 컴포즈가 없다면, 일일이 커맨드를 입력해야 하는데 이를 한번에 해결해주는 도구이죠.
도커 컴포즈 vs Docker file, Kubernetes
Dockerfile 스크립트는 이미지 만드는 용도입니다. 네트워크나 볼륨을 생성할 수 없습니다.
그러나 도커 컴포즈 파일은 컨테이너를 비롯한 네트워크나 볼륨 등 주변 환경까지 포괄합니다.
앞서 말씀드렸듯, 여러 커맨드를 입력할 필요 없이 파일 하나로 해결해낼 수 있는 것입니다.
Kubernetes는 여러 컨테이너를 관리하는 도구입니다. 따라서 생성 및 폐기를 비롯한 관리 기능이 제공됩니다.
그러나 도커 컴포즈에는 컨테이너 관리 기능이 없습니다.
도커 컴포즈 사용 및 작동 원리
도커 컴포즈는 도커 엔진과 사용법이 대동소이합니다. 그러나 엄연히 별개의 소프트웨어입니다. 따라서 별도 설치가 필요합니다. 다만 리눅스 환경에서만 설치가 필요할 뿐, 윈도우나 MAC OS에선 필요치 않습니다. 이유는 Docker Desktop 설치 시 함께 설치되기 때문입니다.
도커 컴포즈의 파일 형식은 YAML 파일 형식으로, "파일이름.yml" 양식을 따릅니다.
파일은 호스트에 위치하며 도커 컴포즈가 이를 읽고 대신 커맨드를 입력해주는 방식으로 작동합니다. 단, 파일은 폴더에 하나만 있어야 합니다. 만약 여러 YAML 파일이 있다면 폴더를 각각 분리해야 합니다.
도커 컴포즈 커맨드
YAML 파일 커맨드 주요 커맨드로는 up, down이 있습니다.
도커 컴포즈 주요 커맨드: UP
up은 YAML 파일을 읽는 명령어입니다.
docker-compose -f C:\Users\user\Desktop\study\cloud\redmine-maria\docker-compose-red-maria.yml up
up 명령어 사용 시 주의해야할 점 2가지가 있습니다. 먼저, up 명령어는 YAML 파일을 한번 읽고 나면 끝입니다. 따라서 up 실행 이후 YAML 파일을 수정하더라도 동기화되진 않습니다. 마찬가지로, YAML 파일로 생성된 컨테이너의 설정을 변경하더라도 YAML 파일에 반영되지 않습니다. 다음으로, 도커 엔진에 생성되는 컨테이너 이름은 도커 컴포즈에 명시한 service 이름과 다르다는 점입니다. 도커 엔진에 생성되는 컨테이너 이름은 "leaf 폴더명_service에 명시한 컨테이너 이름_번호"로 생성됩니다. 예를 들어, C:\Users\user\Desktop\study\cloud\wordpress-maria\docker-compose-red-maria.yml에 대해 up 커맨드를 입력한 경우 생성되는 컨테이너 이름은 "wordpress-maria-${services에 명시한 컨테이너 이름}-1" 입니다.
번호는 YAML 파일이 여러 번 실행되면, 즉 같은 구성의 컨테이너 세트가 여러 개 생성되면 넘버링 형태로 붙습니다.
docker-compose -f C:\Users\user\Desktop\study\cloud\redmine-maria\docker-compose-red-maria.yml up --scale maria_lim=2
*근데 여러 컨테이너를 만드는 도커 컴포즈에서 의존 관계와 맞지 않게 특정 컨테이너만 여러 개 생성하면, 장애가 날 가능성이 높습니다. 여러 컨테이너가 포트번호를 공유하는 것(포트 번호 중복)도 장애를 야기할 수 있습니다. 따라서 여러 세트의 컨테이너를 생성하는 경우 쿠버네티스 활용을 권장합니다.
도커 컴포즈 주요 커맨드: DOWN
down은 YAML로 실행된 컨테이너, 네트워크를 폐기하는 명령어입니다.
down 명령어에서 중요한 건 image와 volume은 삭제되지 않는다는 점입니다. 따라서 별도 폐기 작업이 필요합니다.
docker-compose -f C:\Users\user\Desktop\study\cloud\redmine-maria\docker-compose-red-maria.yml down
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(메모리 내 스택 영역)에 백업해놓음.
애플리케이션을 프레젠테이션 계층 또는 사용자 인터페이스, 데이터가 처리되는 애플리케이션 계층 그리고 애플리케이션과 관련된 데이터가 저장 및 관리되는 데이터 계층이라는 3개의 논리적이고 물리적인 컴퓨팅 계층으로 구성하는 확립된 소프트웨어 애플리케이션 아키텍처 각 계층이 자체 인프라에서 실행되기 때문에 각 계층이 별도의 개발 팀에 의해 동시에 개발될 수 있으며 다른 계층에 영향을 주지 않고 필요에 따라 업데이트되거나 확장될 수 있음
데이터? - 정적인 정보 - 컴퓨터가 주고 받는 정보, 내부에 저장된 정보를 얘기하기도 함
명령어? - 컴퓨터는 결국 명령어 처리 기계 - 명령어는 컴퓨터를 실질적으로 움직이는 정보 *데이터는 명령어를 위한 재료 - 명령어 예) 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) 오퍼랜드 필드 값+베이스 레지스터