[C]기계어, 비트에 대한 이해

JH Bang·2022년 3월 12일
0

C/C++

목록 보기
4/8
post-thumbnail

C는 어셈블리어와 일대일 대응된다고 볼 수 있는데, 어셈블리어는 또 기계어와 일대일로 대응된다. 특히 C언어에 등장하는 비트 시프트(<< / >>)나 int, float, double, unsigned char 등의 자료형을 이해하기 위해선 기계어를 구성하는 비트에 대한 이해가 필수적이다.

2진법의 의미

2진법은 숫자 체계 중 하나다. 우리가 흔히 사용하는 10진법은 0부터 9까지를 '한자리 수'로 본다. 시간은 60진법을 사용한다. 60분은 1시간이고 0부터 59까지는 시간 체계에서 '한자리 수'가 된다.

마찬가지로 2진법에서는 0과 1이 '한자리 수'다. 2진법 1101은 2의 3제곱 자리에 하나, 2의 제곱 자리에 하나, 2의 자리에 0개, 1의 자리에 1개라는 뜻이다. 10진수 13과 동일한 숫자다.

기계의 2진법

기계어는 하드웨어 시스템을 컨트롤하기 위해 미리 만들어진 규칙이라고 할 수 있다. 하드웨어를 직접 컨트롤하는 방법이자 이를 추상화 시키면 프로그래밍 언어가 되기 때문에 기계어는 소프트웨어와 하드웨어의 접점이다.

그럼 기계는 무조건 2진법만을 써야할까? 아니다. 기계도 10진법을 사용할 수 있다. 8진법도, 16진법도, 60진법도, 설계에 따라 얼마든지 가능하다.

그런데 왜 기계는 인간이 이해하기 쉬운 10진법을 놔두고 2진법을 사용할까? 2진법을 안 쓰는 기계는 폐기처분이라도 하는 것일까?

그렇다. 2진법 이외의 진법을 쓰는 기계는 효율이 나지 않기 때문에 쓰지 않는다. 8진법과 2진법을 예로 들어보자. 전류의 세기로 구간을 나눠 숫자를 표현해야 한다고 할 때 8진법은 표현해야 하는 문턱값 구간이 많다. 어느 숫자를 표현하기 위해서 전류의 세밀한 컨트롤이 필요하다.

반면 2진법은 on과 off 두가지만 존재하므로 표현이 상당히 쉽다. 설계 및 생산 비용이 8진법 기계보다 2진법 기계가 훨씬 저렴하다는 뜻이다.

인간의 16진법

프로그래밍에서 16진법은 10진법과 더불어 흔하게 볼 수 있는 진법 체계다. 특히 컴퓨터 메모리의 주소값을 나타낼 때 16진법을 사용하게 된다. 16진법을 사용하는 이유는 단순히 보기 쉽기 때문이다.

예전에는 손으로 일일이 계산해야하는 문제가 있었기 때문에 가독성과 계산의 효율성을 고려해 8진법을 많이 사용했다. 1바이트가 8비트인 8진법 체계라는 부분도 한 몫 했다.

하지만 8진법 체계는 2진법 체계와 잘 맞지 않는다는 문제가 있다. 2진법으로 16자리 수가 있다고 하자.

1010011110001110

16자리이므로 2바이트다. 이를 8진법 체계로 나타낼 때 2의 3제곱이 8이므로 3자리 씩 끊으면 가독성이 올라간다.

1 010 011 110 001 110

가장 높은 자리수에서 1개로 끊기는 문제가 발생했다. 또 8비트는 1바이트라는 부분도 8진법 체계와 사실 잘 맞지 않는다. 8비트는 2진법 자리수가 8개라는 뜻인데, 8을 3으로 나누면 나머지가 2가 된다. 16은 나머지가 1이다. 3개 씩 끊어 읽으려면 3바이트 씩 끊어 읽어야 한다.

그러나 16진법이면 얘기가 달라진다. 16진법은 2비트 4개로 표현될 수 있는데, 위의 2바이트 예시는 4개 씩 16진법으로 깔끔하게 끊어 읽을 수 있게 된다.

1010 0111 1000 1110

16진법으로 이를 표현하면 a78d 가 된다.

2진수로 의미 전달

2진수로 문자, 숫자, 이미지, 소리를 표현하는 것이 가능하다.

문자는 각 문자에 번호를 매겨서 그 번호를 2진수로 표현하면 된다. 가령 A는 65, B는 66으로 표현해보자

A = 65 = 0100 0001
B = 66 = 0100 0010

숫자는 특정 10진수를 바로 2진수로 바꿔 나타내면 되지만, 음의 정수나 소수점일 때 다소 까다로워진다. 이 때 사용하는 것이 2의 보수 표기법과 부동소수점 표기법이다.

이미지와 소리를 표현하는 방법은 좀 더 복잡하다.

이미지는 pixel(picture element)이라는 단위로 해석하는데, 픽셀은 그림의 한 점과 같은 의미로 컴퓨터는 이미지를 점묘화처럼 나타낸다.

빛의 3원색은 빨갼색(red), 초록색(green), 파란색(blue)이고, 이를 적절히 섞으면 모든 색을 표현하게 된다. 추가적으로 색의 불투명도까지 수치화해 표현할 수 있다.

소리 표현은 소리가 진동이라는 사실에서 출발한다. 진동은 사인 함수(정확하게는 푸리에 변환으로 나타낸 진동 함수)로 나타낼 수 있다. 특정 지점에서의 입력값은 진폭을 결과값으로 갖게 된다.

따라서 어떤 범위의 입력값을 충분히 잘게 쪼개면 각각에 대응하는 진폭값을 사인 함수로부터 얻을 수 있다. 이 값을 다시 물리적 진동으로 변환하면 소리를 표현하게 된다.

정리

기계어는 하드웨어 시스템이 어떤 상황에서 어떻게 작동할지를 미리 정한 약속으로 2진수로 나타낸다. 하지만 하드웨어 제조사가 모두 다르므로 하드웨어 마다 기계어가 각각 다르다.

일반적인 프로그래머는 기계어를 짤 일이 평생 없다고 해도 과언이 아니다. 보통 프로그래밍을 공부해도 어셈블리어 수준까지만 공부하게 된다. 어셈블리어는 기계어와 일대일 대응되는 명령어의 집합이다.

그럼에도 기계어는 소프트웨어와 하드웨어의 접점이기 때문에 기계어의 개념을 이해하는 것은 중요하다. 기계어는 하드웨어를 제어하기 위해 설계됐다고 볼 수 있지만, 반대로 하드웨어는 인간이 입력한 명령어를 기계어로 해석하고 실행하기 위해 설계됐다고 볼 수 있다. 기계어에서 추상화 단계를 높이면 어셈블리어를 거쳐 우리가 아는 C언어, JAVA, 파이썬 등의 고수준 프로그래밍 언어가 만들어 진다.

profile
의지와 행동

0개의 댓글