Skip to main content
Summary

숫자가 명령이 되는 순간

메모리에는 숫자도 들어 있고, 글자도 들어 있고, 그림의 색 정보도 들어 있다. 그런데 메모리에는 조금 특별한 숫자도 들어 있다. 바로 명령어다.

명령어는 CPU에게 시키는 짧은 지시다. 예를 들면 이런 뜻을 가진다.

  • 이 주소에 있는 값을 가져와라.

  • 두 값을 더해라.

  • 결과를 다시 메모리에 저장해라.

  • 다음에는 이 위치의 명령어로 이동해라.

겉으로 보면 이것들도 모두 0과 1의 묶음이다. 데이터와 명령어가 생김새만으로 완전히 다른 것은 아니다. 같은 종이에 적힌 숫자라도, 가게에서는 가격이 되고, 버스에서는 노선 번호가 되고, 운동장에서는 등번호가 되는 것과 비슷하다. 중요한 것은 어떤 약속으로 읽느냐다.

CPU는 메모리에서 0과 1을 읽고, 그것을 자신이 알고 있는 약속표에 따라 해석한다. 이 약속표를 명령어 집합이라고 한다. 명령어 집합은 CPU가 알아들을 수 있는 말의 목록이다. 사람에게 한국어, 영어, 일본어가 있듯이 CPU에도 자신이 이해할 수 있는 명령어의 종류가 있다.

예를 들어 아주 작은 CPU가 다음과 같은 약속을 사용한다고 해 보자.

앞부분뜻
0001메모리에서 값을 가져오기
0010값을 더하기
0011메모리에 저장하기
0100다른 명령어 위치로 이동하기

명령어가 0001 0110이라면 앞의 0001은 "가져오기"라는 뜻이고, 뒤의 0110은 "6번 주소"라는 뜻일 수 있다. 그러면 전체 명령은 "메모리 6번 칸의 값을 가져와라"가 된다.

여기서 앞부분처럼 무엇을 할지 나타내는 부분을 연산 코드, 줄여서 opcode라고 부른다. 뒤부분처럼 어디의 값을 쓸지, 어떤 숫자를 쓸지 알려 주는 부분을 피연산자라고 한다. 어렵게 들리지만, 편지로 비유하면 opcode는 "배달하라, 보관하라, 반송하라" 같은 행동이고, 피연산자는 "어느 집으로?"에 해당하는 주소나 대상이다.

명령어를 읽는 작은 두뇌AI 생성 이미지

CPU는 천재보다 성실한 일꾼에 가깝다

CPU를 '컴퓨터의 두뇌'라고 부르지만, 사람의 두뇌처럼 스스로 상상하고 추리하는 장치라고 생각하면 오해가 생긴다. CPU는 천재라기보다 정해진 일을 엄청나게 빠르게 반복하는 성실한 일꾼에 가깝다.

CPU가 하는 기본 일은 크게 세 단계로 나눌 수 있다.

  1. 가져오기: 메모리에서 다음 명령어를 가져온다.

  2. 해석하기: 그 명령어가 무슨 뜻인지 알아낸다.

  3. 실행하기: 명령어가 시킨 일을 실제로 한다.

이 흐름을 명령어 사이클이라고 한다. 사이클은 빙글빙글 반복되는 과정이라는 뜻이다. 세탁기가 물 받기, 돌리기, 헹구기, 탈수를 순서대로 반복하듯이 CPU도 가져오기, 해석하기, 실행하기를 계속 반복한다.

이때 클록은 박자를 맞춰 준다. 앞에서 본 것처럼 클록은 회로의 메트로놈이다. CPU 안의 여러 회로는 클록 박자에 맞춰 "이번에는 명령어를 가져오자", "이번에는 해석하자", "이번에는 결과를 저장하자"처럼 움직인다. 실제 CPU에서는 명령어 하나가 한 박자에 끝나기도 하고, 여러 박자에 나뉘어 처리되기도 한다. 중요한 것은 모든 일이 제멋대로 일어나는 것이 아니라 정해진 박자와 순서에 맞춰 움직인다는 점이다.

CPU가 빠른 이유는 이 과정을 믿기 어려울 만큼 짧은 시간 안에 반복하기 때문이다. 하지만 원리는 단순하다. 다음 할 일을 읽고, 뜻을 확인하고, 그대로 수행한다. 그리고 또 다음 할 일을 읽는다.

프로그램 카운터는 손가락 책갈피다

CPU가 명령어를 실행하려면 먼저 알아야 할 것이 있다. "다음 명령어는 어디에 있지?"

이 질문에 답하는 작은 저장 공간이 프로그램 카운터다. 프로그램 카운터는 CPU 안의 특별한 레지스터다. 레지스터는 CPU가 바로 사용할 값을 잠시 담는 아주 빠른 기억 칸이라고 했다. 프로그램 카운터는 그중에서도 다음에 읽을 명령어의 주소를 담는다.

책을 읽을 때 손가락으로 현재 줄을 짚는 모습을 떠올려 보자. 한 줄을 읽고 나면 손가락은 다음 줄로 내려간다. 프로그램 카운터도 비슷하다. CPU가 한 명령어를 가져오면, 보통 프로그램 카운터는 다음 명령어 주소로 바뀐다.

간단한 예를 보자.

메모리 주소저장된 내용
06번 주소의 값을 가져와라
17번 주소의 값을 더해라
28번 주소에 저장하라
63
74
8비어 있음

처음에 프로그램 카운터가 0을 가리킨다고 하자. CPU는 0번 주소에서 명령어를 가져온다. 뜻은 "6번 주소의 값을 가져와라"다. CPU는 메모리 6번 칸에 있는 3을 가져와 자기 안의 작은 저장 칸에 둔다.

그다음 프로그램 카운터는 1을 가리킨다. CPU는 1번 주소의 명령어를 가져온다. 뜻은 "7번 주소의 값을 더해라"다. CPU는 7번 칸에 있는 4를 가져와 앞의 3과 더한다. 결과는 7이다.

그다음 프로그램 카운터는 2를 가리킨다. CPU는 2번 주소의 명령어를 가져온다. 뜻은 "8번 주소에 저장하라"다. CPU는 결과 7을 메모리 8번 칸에 저장한다.

이것만 보면 CPU가 무언가 똑똑하게 판단한 것처럼 보일 수 있다. 하지만 CPU는 "3 더하기 4를 해서 8번 칸에 넣어야겠다"라고 스스로 계획한 것이 아니다. 메모리에 적힌 명령어를 순서대로 읽고 실행했을 뿐이다.

가져오기, 해석하기, 실행하기

명령어 사이클을 조금 더 자세히 따라가 보자.

먼저 가져오기 단계다. CPU는 프로그램 카운터에 적힌 주소를 메모리로 보낸다. 메모리는 그 주소에 들어 있는 0과 1의 묶음을 CPU에게 돌려준다. CPU는 가져온 명령어를 잠시 담아 둔다. 이 명령어를 담는 칸을 명령어 레지스터라고 부르기도 한다.

다음은 해석하기 단계다. CPU는 명령어의 앞부분을 보고 어떤 행동인지 알아낸다. 가져오기인지, 더하기인지, 저장하기인지, 이동하기인지 확인한다. 그리고 뒤부분을 보고 어느 주소의 값을 써야 하는지, 어떤 숫자를 사용해야 하는지 알아낸다.

마지막은 실행하기 단계다. 명령어의 뜻에 따라 실제 일이 벌어진다. 값을 메모리에서 가져올 수도 있고, 덧셈 회로를 사용해 계산할 수도 있고, 결과를 레지스터나 메모리에 저장할 수도 있다. 어떤 명령어는 프로그램 카운터를 바꿔서 다음에 읽을 위치를 점프시키기도 한다.

이 세 단계는 식당 주방의 주문 처리와 닮았다.

  • 주문서를 가져온다.

  • "라면 하나, 김밥 하나"처럼 내용을 읽는다.

  • 실제로 음식을 만든다.

주방장이 주문서에 없는 음식을 마음대로 만들지 않듯이, CPU도 명령어에 없는 일을 마음대로 하지 않는다. CPU의 힘은 자유로운 상상이 아니라 정확한 반복에서 나온다.

순서대로 읽기만 하면 할 수 있는 일이 제한된다

만약 CPU가 항상 주소 0, 1, 2, 3, 4처럼 순서대로만 읽는다면 어떤 일이 생길까? 간단한 계산이나 정해진 작업은 할 수 있다. 하지만 상황에 따라 다른 길을 고르거나, 같은 일을 여러 번 반복하기는 어려워진다.

프로그램에는 이런 일이 자주 필요하다.

  • 점수가 60점 이상이면 합격이라고 표시한다.

  • 비밀번호가 맞으면 문을 연다.

  • 체력이 0이 될 때까지 게임을 계속한다.

  • 파일 끝에 도착할 때까지 글자를 하나씩 읽는다.

이런 동작을 하려면 다음 명령어로 그냥 넘어가는 대신, 때로는 다른 위치로 이동해야 한다. 이때 중요한 명령이 점프다. 점프 명령은 프로그램 카운터의 값을 바꾼다.

예를 들어 "조건이 맞으면 20번 주소로 가라"라는 명령어가 있다고 하자. CPU가 이 명령을 실행하면 프로그램 카운터가 20으로 바뀐다. 그러면 다음 가져오기 단계에서는 20번 주소의 명령어를 읽는다. 책을 읽다가 "자세한 설명은 50쪽으로 가시오"라는 안내를 보고 50쪽으로 넘기는 것과 같다.

조건 점프가 있으면 프로그램은 선택을 할 수 있다. 다시 앞쪽으로 점프하면 반복도 할 수 있다. 그래서 작은 명령어 몇 개만 있어도 꽤 많은 일을 만들 수 있다.

작은 명령어로 큰 프로그램을 만드는 법

컴퓨터 명령어 하나하나는 보통 아주 작다. "가져와라", "더해라", "저장하라", "비교하라", "이동하라" 정도의 짧은 일이다. 그런데 이런 작은 명령어가 많이 모이면 커다란 프로그램이 된다.

레고 블록 하나는 단순하다. 네모난 블록 하나만으로는 성도, 자동차도 만들 수 없다. 하지만 같은 블록을 규칙 있게 많이 쌓으면 집, 다리, 우주선도 만들 수 있다. CPU 명령어도 그렇다. 명령어 하나는 작지만, 순서와 반복과 조건이 더해지면 게임, 그림판, 계산기, 웹 브라우저 같은 복잡한 프로그램이 된다.

중요한 점은 CPU가 모든 일을 한 번에 이해하지 않는다는 것이다. CPU는 긴 프로그램 전체를 한눈에 보고 "아, 이건 게임이구나"라고 생각하지 않는다. 그저 지금 프로그램 카운터가 가리키는 명령어 하나를 읽는다. 해석한다. 실행한다. 그리고 다음 명령어로 간다.

이 단순한 반복이 컴퓨터의 기본 심장박동이다.

명령어를 읽는 두뇌의 정체

이제 CPU가 조금 덜 신비롭게 보인다. CPU 안에는 값을 잠시 담는 레지스터가 있고, 다음 명령어 주소를 가리키는 프로그램 카운터가 있다. 메모리에는 명령어와 데이터가 0과 1로 저장되어 있다. CPU는 프로그램 카운터가 가리키는 곳에서 명령어를 가져오고, 그 숫자를 약속에 따라 해석하고, 필요한 회로를 움직여 실행한다.

결국 컴퓨터가 프로그램을 실행한다는 말은 이렇게 풀어 쓸 수 있다.

메모리에 저장된 명령어 숫자들을 CPU가 차례로 읽고, 뜻을 해석하고, 작은 동작으로 바꾸어 반복한다는 뜻이다.

이 반복이 충분히 빠르고 정확하면, 사람의 눈에는 마치 컴퓨터가 생각하는 것처럼 보인다. 하지만 그 안쪽에서는 아주 작은 일꾼이 성실하게 외치고 있다.

"다음 명령어는 어디지? 가져오자. 무슨 뜻이지? 해석하자. 시킨 일을 하자. 이제 다음!"

다음 장에서는 이 일꾼의 몸속을 조금 더 들여다본다. 덧셈과 비교를 맡는 ALU, 그리고 회로들에게 순서를 알려 주는 제어장치가 어떻게 함께 CPU를 이루는지 살펴볼 것이다.

책 목록

처음부터 이해하는 컴퓨터 만들기

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기