최종 수정 : 2025.04.21
컴퓨터가 이애하는 정보
CPU는 기본적으로 0과 1만을 이해할 수 있다. 0과 1을 나타내는 가장 작은 정보의 단위를 비트(bit)라고 하며, 1비트는 0또는 1, 2개(2^1, 2의 1제곱)의 정보를 표현할 수 있다.
N비트는 2^N개의 정보를 표현할 수 있다.
하지만 비트는 너무 작은 단위이다. 그래서 프로그램의 크기를 말할 때는 비트보다는 바이트(byte), 킬로바이트(kB), 메가바이트(MB), 기가바이트(GB), 테라바이트(TB) 등을 사용한다.
바이트(byte) : 여덟 비트를 묶은 단위
이들은 프로그램의 관점에서 본 정보 단위이다. CPU 관점에서의 정보단위로는 워드(word)가 있다.
워드는 CPU가 한 번에 처리할 수 있는 데이터의 크기를 의미한다. 만약 CPU가 한 번에 16비트를 처리할 수 있으면 워드는 16비트가 된다. 이런 식으로 32비트, 64비트로 표현된다.
■ 데이터 - 0과 1로 숫자 표현하기
CPU는 컴퓨터 내부에서 2진법(binary)을 사용해 2 이상, 0 이하의 수를 이해한다.
그러나 2진법에는 단점이 있다. 표현하는 숫자의 길이가 너무 길어진다, 그래서 2진수와 더불어 16진수도 함께 사용한다. 2진수와 16진수는 서로 변환하기 쉽기 때문이다.
0이하의 수, 즉 소수를 표현할 때는 오차가 존재할 수 있다. 컴퓨터 내부에서는 소수점을 나타내기 위해 부동 소수점(floating point) 표현 방식을 이용하는데, 이 방식은 정밀도에 한계가 있기 때문이다.
부동 소수점
- 소수점이 고정되어 있지 않은 소수 표현 방식
- 필요에 따라 소수점의 위치가 이동할 수 있고 유동적(floating)
ex) 123.123 -> 1.23123 * 10^2 or 123.23 * 10^(-1)
지수(exponent) : 제곱으로 표현된 2와 -1
가수(significand) : 1.23123과 1231.23
부동소수점의 저장방식 : IEEE754
부호 1비트 | 지수 8비트 | 가수(소수 부분) 23비트 |
부호 1비트 | 지수 11비트 | 가수(소수 부분) 52비트 |
부호(sign) 비트가 0이면 양수, 1이면 음수를 의미한다.
컴퓨터가 지수를 저장할 때는 바이어스(bias)값이 더해져서 저장된다.
- 8비트 : 2^7 - 1 => 127
- 11비트 : 2^11 -1 => 1,023
10진수 0.1은 m * 10^n 꼴로 표현할 수 있지만 같은 수를 1.m * 2^n의 꼴로 표현하려면 무한하게 많은 소수점이 필하다. 따라서, 딱 맞아떨어지지 않는 수가 존재할 수 있다. 컴퓨터의 저장공간은 한정적이기 때문에 무한히 많은 소수점을 저장할 수 없다. 그렇기에 일부 소수점을 생략하여 저장하게 되는데, 이로 인해 오차가 발생한다.
■ 데이터 - 0과 1로 문자 표현하기
컴퓨터가 이해할 수 있는 문자들의 집합을 문자 집합(character set)이라고 한다. 이 문자 집합에 속한 문자를 컴퓨터가 이해하는 0과 1로 이루어진 문자 코드로 변환하는 과정을 문자 인코딩(charater encoding)이라고 하며, 반대로 문자로 변환하는 과정을 문자 디코딩(charater decoding)이라고 한다.
아스키(ASCII, American Standard Code for Information Interchange)
가장 기본적인 문자 집합. 초창기 컴퓨터에서 사용하던 문자 집합 중 하나로, 영어의 알파벳과 아라비아 숫자, 일부 특수 문자를 포함한다.
하나의 아스크 문자를 표현하기 위해서는 8비트를 사용하며, 그 중 1비트는 패리티 비트(parity bit)라 불린다. 패리티 비트는 오류 검출을 위해 사용되는 비트이므로, 실질적으로 문자 표현을 위해 사용되는 비트는 7비트이다. 즉, 총 128개의 문자를 표현할 수 있다. 아스키 문자들은 0부터 127까지의 숫자 중 하나의 고유한 수에 대응되는데, 이 대응된 고유한 수를 '아스키 코드'라고 한다.
10진수 66 : A
10진수 97 : a
이처럼 문자 인코딩에서 '글자에 부여된 고유한 값'을 코드 포인트(code point)라고 한다.
EUC-KR
다만, 아스키 코드는 한글을 표기할 수 없다. 그래서 등장한 한글 인코딩 방식 중 하나가 EUC-KR이다. KS X 1001, KS X 1003이라는 문자 집합 기반의 인코딩 방식으로, 아스키 문자를 표현할 때는 1바이트, 하나의 한글 글자를 표현할 때는 2바이트 크기의 코드를 부여한다. 이를 통해 총 2,350개 정도의 한글 단어를 표현할 수 있다. 그러나 아직도 모든 한글 조합을 표현할 수는 없다.
유니코드(unicode)
그래서 등장한 것이 유니코드 문자 집합이다. 한글을 포함해 EUC-KR에 비해 훨씬 많은 언어, 특수문자, 화살표, 이모티콘까지 코드로 표현할 수 있는 통일된 문자 집합이다.
글자에 부여된 값 자체를 인코딩된 값으로 삼지 않고, 이 값을 다양한 방법으로 인코딩한다. 가변 길이 인코딩 방식을 사용하는데, 이는 인코딩된 결과의 길이가 일정하지 않을 수 있다는 의미이다.
- UTF-8
- UTF-16
- UTF-32
base64 인코딩
문자뿐만 아니라, 이진 데이터까지 변환할 수 있는 인코딩 방식이다. 문자보다는 이진 데이터를 인코딩하는 데에 더 많이 사용된다. 이미지 등 단순 문자 이외의 데이터까지 모두 아스키 문자 형태로 표현할 수 있다. 사진 파일 등을 전송하거나 이메일 원문을 확인해 보면, base64로 인코딩되어 있는 것을 확인할 수 있다.
base64는 사실 64진법을 의미한다. 64개의 문자가 사용되는 것이다. 즉, 2^6의 지수인 6비트가 필요하다. 따라서 변환할 데이터를 6비트씩 나누어 하나의 문자로 변환하게 되며, 기본적으로 4개씩(24비트씩) 한 번에 변환된다.
■ 명령어
명령어는 수행할 동작과 수행할 대상으로 이루어져 있다. 수행할 대상은 수행할 동작에 사용될 데이터 자체가 될 수도 있고, 동작에 사용될 데이터가 저장된 위치가 될 수도 있다.
- 연산 코드(opcode) : 명령어가 수행할 동작
- 오퍼랜드(operand) : 동작에 사용될 데이터 혹은 (메모리나 레지스터의 주소와 같이) 동작에 사용될 데이터가 저장된 위치
연산 코드는 연산자, 오퍼랜드는 피연산자라고도 부른다.
즉, 하나의 명령어는 연산 코드와 0개 이상의 오퍼랜드로 구성되어 있으며, 명령어에서 연산 코드가 담기는 영역은 연산 코드 필드, 오퍼랜드가 담기는 영역은 오퍼랜드 필드라고 한다.
오퍼랜드 필드에는 숫자나 문자와 같이 연산 코드에 사용될 데이터가 직접 명시되기보다는 많은 경우 연산 코드에 사용될 데이터가 저장된 위치, 즉 메모리 주소나 레지스터의 이름이 명시된다. 그래서 주소 필드(address field)라고 부른다.
연산 코드는 매우 다양하다. 하지만 대부분의 CPU가 공통적으로 이해하는 대표적인 연산 코드의 유형에는 데이터 전송, 산술/논리 연산, 제어 흐름 변경, 입출력 제어가 있다.
유형 | 연산 코드 | 설명 |
데이터 전송 | MOVE | 데이터를 옮겨라 |
STORE | 메모리에 저장해라 | |
LOAD(FETCH) | 데이터를 메모리에서 CPU로 가져와라 | |
PUSH | 데이터를 스택에 저장해라 | |
POP | 스택의 최상단 데이터를 가져와라 | |
산술 / 논리 연산 | ADD / SUBTRACT / MULTIPLY / DIVIDE | 덧셈 / 뺄셈 / 곱셈 / 나눗셈을 수행하라 |
INCREMENT DECREMENT |
오퍼랜드에 1을 더해라 오퍼랜드에서 1을 빼라 |
|
AND / OR / NOT | AND / OR / NOT 연산을 수행하라 | |
COMPARE | 두 개의 숫자, 혹은 TRUE / FALSE 값을 비교해라 | |
제어 흐름 변경 | JUMP | 특정 주소로 실행 순서를 옮겨라 |
CONDITIONAL JUMP | 조건에 부합할 경우 특정 주소로 실행 순서를 옮겨라 | |
HALT | 프로그램의 실행을 멈춰라 | |
CALL | 되돌아올 주소를 저장한 채 특정 주소로 실행 순서를 옮겨라 | |
RETURN | CALL을 호출할 때 저장했던 주소로 돌아가라 | |
입출력 제어 | READ (INPUT) | 특정 입출력장치로부터 데이터를 읽어라 |
WRITE (OUTPUT) | 특정 입출력장치로 데이터를 써라 | |
START IO | 입출력장치를 시작해라 | |
TEST IO | 입출력장치의 현재 상태를 확인해라 |
기계어와 어셈블리어
CPU가 이해할 수 있도록 0과 1로 표현된 정보를 있는 그대로 표현한 언어를 기계어(machine code)라고 한다. 하지만 기계어만 봐서는 이것이 어떤 프로그램인지, 어떻게 동작하는지 짐작하기 어렵다. 그래서 등장한 언어가 어셈블리어(assembly language)이다. 0과 1로 표현된 기계어를 읽기 펴한 형태로 단순 번역한 언어이다.
어셈블리어는 명령어의 종류와 생김새가 다르면 기계어도 달라지고, 이를 번역한 어셈블리어도 달라진다. 또한, 같은 프로그램일지라도 CPU마다 이해하는 명령어가 다르면 실행이 불가할 수도 있다. 그렇기에 여러 플랫폼에서 실행되는 프로그램을 개발할 때는 특정 CPU에만 의존적인 코드로 만들지 않아야 한다.
명령어 사이클
메모리 안에는 프로그램이 저장되어 있고, 이 프로그램은 여러 명령어로 구성되어 있다. 그리고 CPU는 이 메모리에서 명령어를 인출하고 실행하기를 반복하며 전체 프로그램을 실행해 나간다. CPU가 명령어를 처리하는 과정에서 프로그램 속 각각의 명령어들을 일정한 주기를 반복하며 실행하는데, 이 주기를 명령어 사이클(instruction cycle)이라고 한다.
- 인출 사이클(fetch cycle) : 메모리에 있는 명령어를 CPU로 가져오는 단계
- 실행 사이클(execution cycle) : CPU로 가져온 명령어를 실행하는 단계
CPU는 메모리 속 명령어를 가져와 실행하고, 가져와 실행하기를 반복하며 프로그램을 실행하기 때문에 두 과정을 반복한다. 하지만 모든 명령어가 이렇게 실행되는 것은 아니다. 간접 사이클과 인터럽트 사이클도 존재한다.
- 간접 사이클(indirect cycle) : 명령어를 실행하기 위해 한 번 더 메모리에 접근하는 단계
- 인터럽트 사이클 : 인터럽트를 처리하는 사이클
참고 도서
이것이 컴퓨터 과학이다.
'CS 공부 > 컴퓨터 구조' 카테고리의 다른 글
CPU (0) | 2025.04.21 |
---|---|
컴퓨터 구조의 큰 그림 (0) | 2025.04.17 |
클러스터 컴퓨터 (0) | 2025.01.10 |
컴퓨터 성능평가 (0) | 2025.01.10 |
DMA를 이용한 입출력 (0) | 2025.01.10 |
댓글