1주차 공부를 시작한다! 사실 이번주가 너무 바빠서 포기할까 고민도 했지만.. 지금 시작하지 않으면 방학동안 하나도 안 할 것 같아서 얼레벌레 시작해본다! 2주차부터는 미루지 않고 미리미리 하는게 목표다!
Chapter 01 컴퓨터 구조 시작하기
01-1 컴퓨터 구조를 알아야 하는 이유
프로그래밍 공부를 처음 시작했을 때는 컴퓨터 구조를 굳이 알아야 할까? 프로그래밍 언어만 잘 사용할 수 있으면 되는게 아닌가? 라는 생각을 했었다. 하지만 프로그래밍에 대해서 깊게 공부할 수록 컴퓨터 구조에 대해서 공부해야겠다는 생각이들어 공부를 시작하게 되었다.
1. 문제해결
컴퓨터 구조를 이해하고 있다면 문제 상황을 빠르게 진단할 수 있고, 문제 해결의 실마리를 다양하게 찾을 수 있다. 컴퓨터 내부를 거리낌 없이 들여다보며 더 좋은 해결을 고민 할 수 있다.
컴퓨터 구조 지식은 다양한 문제를 스스로 해결할 줄 아는 개발자가 될 수 있도록 만들어 준다.
2. 성능, 용량, 비용
어떤 CPU를 사용하는지, 어떤 메모리를 사용하는지에 따라 성능, 용량, 비용이 달라진다. 사용하는 프로그램을 위한 최적의 컴퓨터 환경을 스스로 판단 할 수 있어야 한다. 성능, 용량, 비용 문제는 프로그래밍 언어의 문법만 알아서는 해결하기 어렵다. 컴퓨터 구조를 이해하면 입력과 출력에만 집중하는 개발을 넘어 성능, 용량, 비용까지 고려하며 개발하는 개발자가 될 수 있다.
01-1 컴퓨터 구조의 큰 그림
우리가 알아야할 컴퓨터 구조 지식은 크게 두 가지이다. 하나는 '컴퓨터가 이해하는 정보'이고, 또 하나는 '컴퓨터의 네 가지 핵심 부품'이다,
1. 컴퓨터가 이해하는 정보
컴퓨터는 0과 1로 표현된 정보만을 이해하는데, 0과 1로 표현되는 정보에는 크게 두 가지가 있다. 데이터와 명령어이다.
- 데이터 : 컴퓨터가 이해하는 숫자, 문자, 이미지, 동영상과 같은 정적인 정보
- 명령어 : 데이터를 움직이고 컴퓨터를 작동시키는 정보
2. 컴퓨터의 4가지 핵심 부품
중앙처리장치 (CPU) |
- 메모리에 저장된 값을 읽어 들이고, 해석하고, 실행하는 장치이다. - 내부에는 ALU, 레지스터, 제어장치가 있다. - ALU는 계산하는 장치, 레지스터는 임시 저장 장치, 제어장치는 제어 신호를 발생시키고 명령어를 해석하는 장치이다. |
주기억장치 (메모리) |
- 프로그램이 실행되기 위해서는 반드시 메모리에 저장되어 있어야 한다. - 메모리는 현재 실행되는 프로그램의 명령어와 데이터를 저장한다. - 메모리에 저장된 값의 위치는 주소로 알 수 있다. |
보조기억장치 | - 메모리는 가격이 비싸 저장 용량이 적고, 전원이 꺼지면 저장된 내용을 잃는다는 단점이 있는데 이를 보조할 저장 장치가 보조기억장치이다. - 메모리보다 크기가 크고 전원이 꺼져도 저장된 내용을 잃지 않는다. - eg., 하드디스크, SSD, USB 메모리, DVD, CD-ROM |
입출력장치 | - 마이크, 스피커, 프린터, 마우스, 키보드처럼 컴퓨터 외부에 연결되어 컴퓨터 내부와 정보를 교환하는 장치 |
- 메인보드와 시스템 버스
위의 컴퓨터의 핵심 부품들은 메인보드라는 판에 연결이 된다. 메인보드는 마더보드라고도 부른다.
메인보드에 연결된 부품들은 서로 정보를 주고받을 수 있는데, 이는 메인보드 내부에 버스라는 통로가 있기 때문이다. 컴퓨터 내부에는 다양한 종류의 통로, 즉 버스가 있다. 하지만 여러 버스 가운데 컴퓨터의 네 가지 핵심 부품을 연결하는 가장 중요한 버스는 시스템 버스이다.
시스템 버스는 주소버스, 데이터 버스, 제어 버스로 구성되어 있다.
- 주소 버스 : 주소를 주고받는 통로
- 데이터 버스 : 명령어와 데이터를 주고받는 통로
- 제어 버스 : 제어 신호를 주고받는 통로
Chapter 02 데이터
02-1 0과 1로 숫자를 표현하는 방법
컴퓨터는 0과 1만을 이해할 수 있다고 하였는데, 어떻게 3+4가 7이라는 답변은 내놓을 수 있는지?
1. 정보 단위
0과 1을 나타내는 가장 작은 정보 단위를 비트라고 한다.
2비트는 네 가지 정보를, 3비트는 여덟 가지 정보를 표현할 수 있다. 즉 n비트는 2^n가지 정보를 표현할 수 있다.
1바이트(1byte) | 8비트(8bit) |
1킬로바이트(1kB) | 1,000바이트(1,000byte) |
1메가바이트(1MB) | 1,000킬로바이트(1,000kB) |
1기가바이트(1GB) | 1,000메가바이트(1,000MB) |
1테라바이트(1TB) | 1,000기가바이트(1,000GB) |
2. 이진법
수학에서 0과 1만으로 모든 숫자를 표현하는 방법을 이진법이라고 한다. 일상적으로는 십진법을 사용한다.
십진법에서는 숫자가 9를 넘어가는 시점에서 자리 올림을 하고, 이진법에서는 숫자가 1을 넘어가는 시점에서 자리 올림을 한다.
이진법으로 표현한 수를 이진수, 십진법으로 표현한 수를 십진수라고 한다,
이진수를 표현할 때는 혼동을 방지하기 위해서 이진수 끝에 아래첨자 (2)를 붙이거나 이진수 앞에 0b를 붙인다.
- 이진수의 음수 표현
십진수에서 음수를 표현할 때는 단순이 숫자 앞에 마이너스 부호를 붙이면 된다. 하지만 이진수는 컴퓨터가 0과 1밖에 이해하지 못하기 때문에 음수 또한 0과 1만으로 표현해야 한다.
0과 1만으로 음수를 표현하는 방법 중 가장 널리 사용되는 방법은 2의 보수를 구해 이 값을 음수로 간주하는 방법이다. 2의 보수의 사전적 의미는 '어떤 수를 그보다 큰 2^n에서 뺀 값'을 의미한다.
2의 보수를 매우 쉽게 표현하자면 '모든 0과 1을 뒤집고, 거기에 1을 더한 값'으로 이해하면 된다.
<음수로서의 0101과 십진수 5를 표현하기 위한 양수로서의 0101은 똑같이 생겼는데 어떻게 구분하는가?>
컴퓨터 내부에서 어떤 수를 다룰 때는 이 수가 양수인지 음수인지를 구분하기 위해 플래그를 사용한다.
3. 십육진법
이진법을 이용하면 컴퓨터가 이해하는 숫자 정보를 직접적으로 표현할 수 있다. 하지만 이진법은 0과 1만으로 모든 숫자를 표현하다 보니 숫자의 길이가 너무 길어진다는 단점이 있다. 그래서 데이터를 표현할 때 이진법 이외에 십육진법도 자주 사용한다.
십육진법은 수가 15를 넘어가는 시점에 자리 올림을 하는 숫자 표현 방식이다. 십진수 10, 11, 12, 13, 14, 15는 십육진법 체계에서는 각각 A, B, C, D, E, F로 표기한다.
십육진수도 이진수와 마찬가지로 숫자 뒤에 아래첨자 (16)을 붙이거나 숫자 앞에 0x를 붙여 구분한다.
- 십육진수를 이진수로 변환하기
십육진수를 이진수로 변환하는 간편한 방법 중 하나는 십육진수 한 글자를 4비트의 이진수로 간주하는 것이다. 즉, 십육진수를 이루고 있는 각 글자를 따로따로 이진수로 변환하고, 그것들을 그대로 이어 붙이면 십육진수가 이진수로 변환이 된다.
1A2B 1 -> 0001 A -> 1010 2 -> 0010 B -> 1011 1A2B(16) -> 0001101000101011(2) |
- 이진수를 십육진수로 변환하기
반대로 이진수를 십육진수로 변환할 때는 이진수 숫자를 네 개씩 끊고, 끊어 준 네 개의 숫자를 하나의 십육진수로 변환한 뒤 그대로 이어붙이면 된다.
11010101 1101 -> D 0101 -> 5 11010101(2) -> D5(16) |
02-2 0과 1로 문자를 표현하는 방법
1. 문자 집합과 인코딩
문자 집합 | 컴퓨터가 인식하고 표현할 수 있는 문자의 모음 |
문자 인코딩 | 문자를 0과 1로 변환하는 과정 |
문자 디코딩 | 0과 1를 문자로 변환하는 과정 |
2. 아스키 코드
아스키는 초창기 문자 집합 중 하나로, 영어 알파벳과 아라비아 숫자, 그리고 일부 특수 문자를 포함한다. 아스키 문자 집합에 속한 문자들은 각각 7비트로 표현되는데, 총128개의 문자를 표현할 수 있다.
아스키 문자들은 0부터 127까지 총 128개의 숫자 중 하나의 고유한 수에 일대일로 대응된다. 아스키 문자에 대응된 고유한 수를 아스키 코드라고 한다.
아스키 코드는 매우 간단한게 인코딩된다는 장점이 있지만, 한글을 표현할 수 없다. 한글뿐만 아니라 아스키 문자 집합 외의 문자, 특수문자도 표현할 수 없다. 더 다양한 문자 표현을 위해 아스키 코드에서 1비트를 추가한 확장 아스키가 등장하기도 했지만, 그럼에도 표현 가능한 문자의 수는 256개로 부족했다.
3. EUC-KR
한국을 포함한 영어권 외의 나라들은 자신들의 언어를 0과 1로 표현할 수 있는 고유한 문자 집합과 인코딩 방식이 필요하다고 생각했고, 이런 이유로 등장한 한글 인코딩 방식이 EUC-KR이다.
알파벳을 쭉 이어 쓰면 단어가 되는 영어와 달리 한글을 초성, 중성, 종성의 조합으로 이루어져 있다. 그래서 한글 인코딩 방식은 완성형과 조합형이 존재한다.
완성형 인코딩 방식은 초성, 중성, 종성의 조합으로 이루어진 하나의 글자에 고유한 코드를 부여하는 방식이다.
조합형 인코딩 방식은 초성, 중성, 종성 각각에 비트열을 할당하여 그것들의 조합으로 하나의 글자 코드를 완성하는 인코딩 방식이다.
EUC-KR은 대표적인 완성형 인코딩 방식을 사용한다. 초성, 중성, 종성이 모두 결합된 한글 당어에 2바이트 크기의 코드를 부여한다.
해당 방식으로 총 2,350개 정도의 한글 단어를 표현할 수 있지만, 문자 집합에 정의되지 않은 '쀍', '믜' 같은 글자는 표현할 수 없다.
이러한 문제를 해결하기 위해 나온 것이 마이크로소프트의 CP949로 EUC-KR의 확장된 버전이지만, 이 또한 한글 전체를 표현하기에는 부족했다.
4. 유니코드와 UTF-8
유니코드는 EUC-KR보다 훨씬 더 다양한 한글을 포함하며 대부분 나라의 문자, 특수문자, 화살표나 이모티콘까지도 코드로 표현할 수 있는 통일된 문자 집합이다. 현대 문자를 표현할 때 가장 많이 사용되는 표준 문자 집합이며, 문자 인코딩 세계에서 매우 중요한 역할을 맡고 있다.
유니코드의 문자 집합에서는 아스키 코드나 EUC-KR과 같이 각 문자마다 고유한 값이 부여된다. 유니코드는 조금 앞과는 조금 다른 점이 존재하는데, 앞의 방식들은 부여된 값을 그대로 인코딩 값으로 삼았다면 유니코드에서는 글자에 부여된 값 자체를 인코딩된 값으로 삼지 않고 이 값을 다양한 방법으로 인코딩 한다.
가장 대중적인 방법인 UTF-8에 대해서 살펴볼 것이다. 해당 방법은 1바이트부터 4바이트 까지의 인코딩 결과를 만들어 낸다. 즉 인코딩의 결과가 1바이트가 될 수도 있고, 2바이트, 3바이트, 4바이트가 될 수도 있다. 유니코드 문자에 부여된 값의 범위에 따라 결정된다.
Chapter 03 명령어
03-1 소스 코드와 명령어
프로그래밍 언어가 어떻게 명령어가 되어 실행되는지?
1. 고급 언어와 저급 언어
컴퓨터는 프로그래밍 언어를 이해할 수 없다. 우리가 사용하는 프로그래밍 언어는 사람이 이해하고 작성하기 쉽게 만들어진 언어이다. '사람을 위한 언어'를 고급언어라고 한다. 대부분의 프로그래밍 언어가 이에 속한다.
반대로 컴퓨터가 직접 이해하고 실행할 수 있는 언어는 저급언어라고 한다. 저급 언어는 명령어로 이루어져 있다. 컴퓨터가 이해하고 실행할 수 있는 언어는 오직 저급 언어뿐이다. 고급언어로 작성된 소스 코드가 실행되려면 반드시 저급 언어, 즉 명령어로 변환되어야 한다. 저급언어에는 두 가지 종류가 있다. 기계어와 어셈블리어이다.
기계어 | 0과 1의 명령어 비트로 이루어진 언어로 0과 1로 이루어진 명령어 모음 이진수로 나열하면 너무 길어지기 때문에 가독성을 위해 십육진수로 표현하기도 한다. |
어셈블리어 | 0과 1로 표현된 명령어(기계어)를 읽기 편한 형태로 번역한 언어 어셈블리어 한 줄 = 명령어 |
<왜 저급 언어를 알아야 하나요?>
하드웨어와 밀접하게 맞닿아 있는 프로그램을 개발하는 임베디드 개발자, 게임 개발자, 정보 보안 분야 등의 개발자는 어셈블이어를 많이 이용한다. 어셈블리어를 읽으면 컴퓨터가 프로그램을 어떤 과정으로 실행하는지, 즉 프로그램이 어떤 절차로 작동하는지를 가장 근본적인 단계에서부터 하나하나 추적하고 관찰할 수 있다.
2. 컴파일 언어와 인터프리터 언어
고급언어를 저급언어로 변환하는 방식은 크게 두 가지가 존재한다. 컴파일 방식과 인터프리트 방식이다. 컴파일 방식으로 작동하는 프로그래밍 언어를 컴파일 언어, 인터프리트 방식으로 작동하는 프로그래밍 언어를 인터프리터 언어라고 한다.
컴파일 언어 | 컴파일 언어로 작성된 소스 코드 전체를 저급언어로 변환하는 과정을 컴파일이라고 한다. 코드를 처음부터 끝까지 저급언어로 컴파일하여 목적코드를 생성한다. 대표적인 언어로는 C가 있다. |
인터프리터 언어 | 인터프리터에 의해 소스 코드가 한 줄씩 실행되는 고급 언어이다. 소스 코드 전체가 저급 언어로 변환되는 컴파일 언어와 달리, 소스 코드를 한 줄씩 차례로 실행한다. 대표적인 언어로는 Python이 있다. |
일반적으로 인터프리터 언어는 컴파일 언어보다 느리다.
03-2 명령어의 구조
명령어를 자세히 들여다 보자!
1. 연산 코드와 오퍼 랜드
명령어는 '무엇을 대상으로, 어떤 작동을 수행하라'는 구조로 되어 있다. 명령어는 연산 코드와 오퍼랜드로 구성되어 있다.
연산 코드(연산자) | 명령어가 수행할 연산 연산 코드가 담기는 영역 => 연산 코드 필드 기본적인 연산 코드 유형은 네 가지로 데이터 전송, 산술/논리 연산, 제어 흐름 변경, 입출력 제어가 있다. |
오퍼랜드(피연산자) | 연산에 사용할 데이터 또는 연산에 사용할 데이터가 저장된 위치 오퍼랜드가 담기는 영역 => 오퍼랜드 필드(주소필드) 오퍼랜드 필드에는 숫자나 문자와 같이 연산에 사용할 데이터를 직접 명시하기보다는, 연산에 사용할 데이터가 저장된 위치, 즉 메모리 주소나 레지스터 이름이 담긴다. 오퍼랜드는 명령어 안에 하나도 없을 수도 있고, 한 개만 있을 수도 있고, 두 개 또는 세 개 등 여러개가 있을 수도 있다(0-주소 명령어, 1-주소 명령어 ... ) |
2. 주소 지정 방식
연산 코드에 사용할 데이터가 저장된 위치, 즉 연산의 대상이 되는 데이터가 저장된 위치를 유효주소라고 한다.
연산에 사용할 데이터 위치를 찾는 방법을 주소 지정 방식이라고 한다. 즉, 주소 지정 방식은 유효 주소를 찾는 방법이다.
즉시 주소 지정 방식 | 연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시하는 방식 데이터의 크기가 작아진다는 단점이 있지만 빠르다. |
직접 주소 지정 방식 | 오퍼랜드 필드에 유효 주소를 직접적으로 명시하는 방식 표현할 수 있는 유효 주소에 제한이 생길 수 있다. |
간접 주소 지정 방식 | 유효 주소의 주소를 오퍼랜드 필드에 명시하는 방식 두 번의 메모리 접근이 필요해 일반적으로 느리다. |
레지스터 주소 지정 방식 | 연산에 사용할 데이터를 저장한 레지스터를 오퍼랜드 필드에 직접 명시하는 방식 직접 주소 지정 방식보다 빠르게 데이터에 접근할 수 있지만 레지스터 크기에 제한이 생길 수 있다. |
레지스터 간접 주소 지정 방식 | 연산에 사용할 데이터를 메모리에 저장하고, 그 주소(유효주소)를 저장한 레지스터를 오퍼랜드 필드에 명시하는 방법 메모리에 접근하는 횟수가 한번으로 줄어들고 간접 주소 지정 방식보다 빠르다. |
숙제
51p. 확인문제 3번
프로그램이 실행되려면 반드시 메모리에 저장되어 있어야 합니다.
65p. 확인문제 3번
1101(2)을 음수로 표현한 값은 0011(2) 입니다.
추가숙제
스택과 큐
스택 stack | 한쪽 끝이 막혀 있는 통과 같은 저장 공간이다. 나중에 저장한 데이터를 가장 먼저 빼내는 데이터 관리 방식(후입선출)로 LIFO(Last In First Out) 자료 구조라고도 부른다. 새로운 데이터를 저장하는 명령어가 PUSH, 저장된 데이터를 꺼내는 명령어가 POP이다. |
큐 queue | 스택과 달리 양쪽이 뚫려 있는 통과 같은 저장 공간이다. 한쪽으로는 데이터를 저장하고, 다른 한쪽으로는 먼저 저장한 순서대로 데이터를 빼낸다. 가장 먼저 저장된 데이터부터 빼내는 데이터 관리 방식(선입선출)로 FIFO(First In First Out) 자료 구조라고도 부른다. |
'[혼공학습단 12기] 혼자 공부하는 컴퓨터구조+운영체제' 카테고리의 다른 글
[혼공컴운] 6주차 (0) | 2024.08.21 |
---|---|
[혼공컴운] 5주차 (0) | 2024.08.14 |
[혼공컴운] 4주차 (0) | 2024.07.30 |
[혼공컴운] 3주차 / 더 열심히..! (0) | 2024.07.21 |
[혼공컴운] 2주차 / 화이팅 >ㅁ< (0) | 2024.07.13 |