2장 - 불 연산 목표
2장에서는 숫자를 표현하고 산술 연산을 진행한다.
우리는 1장에서 배운 논리 게이트를 활용하여 ALU(arithmetic logical unit, 산술 논리 연산 장치)를 완성하는 것으로 2장을 마무리한다.
2진 코드, 불 산술 연산, 부호 정수 표시와 덧셈을 살펴보고,
CPU의 핵심 계산 부품들을 확인하는 것으로 마무리한다.
이진수 표현, 2의 보수법
산술 연산
범용 컴퓨터 시스템은 부호 있는 정수에 대해 최소한 다음의 산술 연산을 수행할 수 있어야 한다.
- 덧셈
- 부호 변환
- 뺄셈
- 비교
- 곱셈
- 나눗셈
2진수의 덧셈을 통해서 다른 모든 연산을 표현할 수도 있다.
2진수 덧셈이 하드웨어의 기본 연산을 이해하는 데 핵심이다.
2진수
우리는 평소에 10진수를 사용한다. 1000이라는 숫자를 예로 들면, 110^3 + 010^2 + 010^1 + 010^0으로 나타낼 수 있다.
이 때, 10을 밑 수 혹은 base number라고 한다.
2진수도 10진수와 마찬가지다. 각 자리는 2의 제곱수를 나타내는 밑이 2인 숫자의 나열, 코드로 나타낼 수 있다.
예를 들어, 19라는 숫자를 2진법으로 나타내면 10011이 된다. 1*2^4 + 0*2^3 + 0*2^2 + 1*2^1 + 1*2^0
우리가 19라는 숫자를 입력하기 위해 1,9,enter를 차례로 클릭하면 컴퓨터 메모리에는 최종적으로 10011이라는 2진 코드가 저장된다.
OS는 이 정수 값을 1과 9라는 두 개의 문자로 변환하고 글꼴을 조회해서 화면에 랜더링 하기 위한 두 개의 비트맵 이미지를 만든다.
그 후에 OS는 스크린 드라이버(모니터 드라이버)를 통해서 픽셀을 끄거나 켜고 화면에 19가 출력된다.
이 모든 과정은 몇 백분의 1초도 안 걸리는 시간 내에 동작한다.
고정 단어 크기
정수의 범위는 제한할 수 없이 무한하다.
그러나 하드웨어는 명백히 한계가 존재한다.
그래서 하드웨어는 고정 단어 크기를 사용해야 한다.
단어 크기란 일반적인 하드웨어 용어로 컴퓨터가 기본 정보단위(지금은 정수)를 표현하는데 사용하는 비트 수를 의미한다.
보통 정수를 표현하기 위해서 8, 16, 32, 64 비트가 사용되며 고수준 프로그래밍 언어의 byte, short, int, long에 해당한다.
short는 하드웨어 수준(기계어)으로 가면 16비트 레지스터로 처리된다.
그리고 16비트 산술 연산이 64비트 산술 연산보다 크기가 1/4인 만큼 속도도 4배 빠르다.
그래서 간결한 데이터 타입을 사용하면 좋다.
정수를 표현하기 위해 n비트를 사용하면 숫자는 0부터 2^n - 1 만큼 표현할 수 있다.
예를 들어, 8비트는 0부터 2^8 - 1인 255까지 표현할 수 있다.
그렇다면 음수인 숫자는 어떻게 표현할까?
혹은 만약 255를 넘어서서 256, 512, 1024 같은 숫자는 어떻게 표현할까?
음수에 대해서는 바로 다음 단계에서 배우는 2의 보수법을 사용할 수 있다. 자세한 건 뒤에서 확인하자.
255를 넘어서는, n비트의 한계를 넘어서는 (너무 큰 숫자나 작은 수) 수에 대해서 모든 고수준 프로그래밍 언어에서는 추상화 기법을 지원하여 처리한다.
n비트 레지스터를 논리적으로 묶어서 사용한다.
이런 여러 단어(multi-word)로 구성된 숫자의 논리, 산술 연산은 느린 작업임을 생각하자.
예를 들어보면 javascript의 BigInt나 Java의 Big Integer가 있겠다. (실제로 이 녀석들은 연산이 매우 느리다. Long의 범위를 넘어서는 연산이 필요할 때만 사용한다.)
2진 덧셈
두 개의 2진수는 우리가 초등학교에서 덧셈을 처음 배울 때와 똑같이, 오른쪽에서부터 1개씩 차례로 더한다.
가장 오른쪽 숫자 둘을 LSB(least significant bit), 최하위 비트라고 부른다.
1 + 1을 연산하게 되어 자리 올림이 발생하면 자리 올림 비트(carry bit)를 다음 순서의 덧셈에 같이 더해준다.
이런 덧셈 과정을 MSB(most siginifacnt bit), 최상위 비트까지 반복한다.
덧셈 예시를 작성하면 다음과 같다.
overflow가 발생하지 않는 경우
overflow가 발생하는 경우
이 책에서는 오버플로우를 무시한다.
실제 컴퓨터에서는 오버플로우 플래그를 두고 오버플로우가 발생하는지 항상 확인하며 에러 처리를 하는 등 뭔가 처리가 되어 있지만 그건 결정에 따른 문제이다.
부호가 있는 2진수
n비트 2진법은 2^n 개의 코드를 표현할 수 있다.
만약 2진 코드로 부호가 있는 숫자를 나타낸다면 음수와 0이상의 정수, 2가지의 집합으로 나누어 표현하는 것이 자연스럽다.
그리고 하드웨어의 구현이 덜 복잡하도록 하는 것이 좋다.
이런 상황을 고려하여 여러 체계가 개발되었고, 오늘날까지 보편적으로 사용되는 방식은 2의 보수법(two’s complement) 혹은 기수 보수법(radix complement)라고 불리는 방법이다.
2의 보수법에서 n비트 2진법의 숫자 x의 음수를 표현하는 방법은 2^n - x
를 나타내는 코드가 된다.
예를 들어, 4비트 2진법 체계에서 -7은 2^4 - 7 = 9와 관련된 1001로 표현된다.
+7과 -7의 코드를 더하면 0111 + 1001 = 0000 (오버플로우가 발생하여 10000이지만 이 책에서는 오버플로우를 무시)가 된다.
2의 보수법에 대한 특징을 나열해보면 다음과 같다.
- -2^(n-1) ~ (2^(n-1) - 1)까지 숫자를 표기할 수 있다.
- 음수가 아니면 0으로 시작하고 음수는 1로 시작한다. (2의 보수법에서는 MSB가 sign bit(부호 비트)로 사용된다.)
- x에서 -x를 구하려면 2^n - x 를 연산해도 되지만 다른 방법도 존재한다.
x 코드의 모든 숫자를 반전시키고 ( 0 → 1, 1 → 0)
1을 1의 자리에 더해주면 된다.
2의 보수법이 좋은 이유는 뺄셈을 위한 하드웨어를 구현할 필요없이, 덧셈의 특별한 경우라고 취급해버리면 되기 때문이다.
2 - 5 라는 연산을 2 + (-5) 라고 나타낼 수 있는 것이라 생각하면 된다.
그래서 음수가 아닌 숫자들을 덧셈하는 데 사용하던 하드웨어를 그대로 재활용할 수 있다.
게다가 곱셈, 나눗셈, 제곱근 등 모든 산술 연산은 2진수 덧셈으로 구현될 수 있다. 그래서 하드웨어가 따로 필요없이 2진 덧셈만을 위한 하드웨어로 모든 연산을 할 수 있다는 것이 정말 특별하다.(현대적인 컴퓨터 구조와는 조금 다를 수 있다.)
단어 정리
- 단어 크기
- 일반적인 하드웨어 용어
- 컴퓨터가 기본 정보단위를 표현하는데 사용하는 비트 수를 의미
'개발 > 개발 공부' 카테고리의 다른 글
[밑바닥부터] 6일차 - 2장 불 연산: 반가산기, 전가산기 구현 (0) | 2025.04.13 |
---|---|
[밑바닥부터] 5일차 - 2장 불 연산: 가산기 아키텍처, ALU 설계 (0) | 2025.04.10 |
[밑바닥부터] 3일차 - 1장 불 논리: 프로젝트 (0) | 2025.04.07 |
[밑바닥부터] 2일차 - 1장 불 논리: 논리 게이트와 HDL 소개 (1) | 2025.04.07 |
[밑바닥부터] 1일차 - 1장 불 논리: 불 함수 개념 이해 (0) | 2025.04.04 |