컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (15)

나빌레라의 이미지

#15. 사칙연산을 해 봅시다.

지난 번에 2의 보수를 이용해 음수를 표시하는 방법에 대해 이야기했다. 음수를 표시할 수 있으므로 음수를 더하면 그것이 뺄셈이 된다. 그러므로 우리가 만든 회로에서 가산기에 들어가는 입력으로 2의 보수를 줄 수 있으면 뺄셈이 가능해 진다.

그렇다면 2의 보수를 이용한 뺄셈 수식이 다시 어떻게 덧셈으로 변하는지 되새겨 보자.

이진수A – 이진수B

위 식은 2의 보수를 통해 덧셈으로 바뀐다. 식을 연달아 풀어보겠다.

이진수A + 이진수B의 2의 보수 = 이진수A + (이진수B의 1의 보수 + 1)

덧셈은 결합법칙이 성립하기 때문에 아래처럼 수식은 정리될 수 있다.

(이진수A + 이진수B의 1의 보수) + 1

이진수에서 1의 보수 표현은 간단히 이진수의 각 비트를 반전하면 된다. 비트 반전은 인버터를 사용하는 방법과 XOR 논리 게이트를 사용하는 방법이 있다.

전체 회로는 너무 커서 레지스터 A, B와 가산기 부분만 그렸다. SUB/ADD 선택 핀은 0이 입력되면 덧셈을 하고 1이 입력되면 뺄셈을 수행하도록 했다. 레지스터 B로부터 내려오는 입력에 XOR 게이트를 붙여서 SUB/ADD 선택 핀에 1이 들어오면 XOR를 통해 레지스터 B에서 받는 입력은 비트 반전이 된다. XOR 게이트는 두 입력 중 한 개가 1이면 출력은 다른 입력의 반대 값이 나온다. 또한 두 입력중 하나가 0이면 출력은 다른 입력 값이 그대로 나온다. 그래서 XOR 게이트를 사용하면 비트 반전을 선택적으로 할 수 있다. 위 회로에서는 SUB/ADD 선택 핀의 값을 XOR 게이트에 한 쪽 입력으로 넣어서 1이 입력될 경우 비트 반전을 하도록 했다. 0이 입력되면 비트 반전이 일어나지 않는다.

그리고 눈여겨 볼 곳은 지금까지 비어있던 Cin 입력에 SUB/ADD 선택 핀의 입력이 같이 들어오는 부분이다. 그러면 XOR 게이트를 통해서 레지스터 B의 입력이 비트 반전되어 1의 보수가 되고, 동시에 Cin으로 추가적인 1이 더해지므로 마지막 +1의 효과가 생겨 2의 보수를 더하는 결과가 된다.

더하기와 빼기가 되므로 이제부터 줄곧 가산기라고 부르던 저 네모를 앞으로는 ALU(Arithmetic Logic Unit)이라고 부르겠다. ARM이나 x86 등 모든 CPU에는 그 중심에 ALU가 있다. 실질적으로 계산을 수행하는 주체는 ALU기 때문이다. 이 이야기에서 조금씩 만들어가는 우리의 CPU도 드디어 덧셈과 뺄셈이 가능한 ALU를 갖추게 되었다.

사실 감산기(subtractor)를 구성하는 방법은 내가 설명한것처럼 가산기 외부에서 XOR를 이용해 2의 보수를 입력으로 넣지 않고 가산기 회로에 인버터를 붙여서 바로 만들어 낼 수도 있다. 그리고 그게 더 빠르다. 하지만 그런식으로 구현 가능한 모든 경우를 이 책에서 설명하는 것은 책의 목적을 벗어나므로 나는 최대한 여러분들이 이해하기 쉬운 방법으로 구현하기 위해 위의 내용처럼 2의 보수를 만들어내는 회로를 가산기를 이용해 만들었다. 마찬가지로 그 전에 설명한 가산기도 내가 이야기한 방법보다 훨씬 빠른 방법이 있다. 앞으로 이야기할 곱셈기 회로나 나눗셈기 회로 역시 내가 이야기한 방법 말고도 더 효율적이고 빠른 방법이 아주 많이 있다. 하지만 나는 내가 알고 있는 한도 내에서 내가 이해할 수 있는 범위의 내용을 다루려 한다. 중요한 것은 이런식으로 돌아간다는 것을 이해하는 것이고, 나중에 가면 그것들을 모두 묶어 하나로 인식해 버리게 되므로 컴퓨터의 사칙연산이 결국엔 로직회로의 연속으로 이뤄져 있다는 것을 이해 시키는 것이 나의 목적임을 알아주기 바란다.

그래, 솔직히 내가 아는 것만 이야기하겠다.

덧셈과 뺄셈이 가능하면 곱셉과 나눗셈과 나머지도 구할 수 있다. 곱셈은 같은 수를 연속해서 더하면 되고, 나눗셈은 같은 수를 연속해서 빼다가 남아 있는 수가 빼는 수 보다 작아졌을 때 뺄셈을 수행한 횟수가 몫. 남아 있는 수가 나머지가 된다. 그래서 하드웨어적으로 덧셈과 뺄셈만 가능하게 만들어 놓으면 소프트웨어 적으로 곱셈, 나눗셈, 나머지를 모두 다 구현할 수 있다. 하지만 곱셈, 나눗셈처럼 자주 사용하는 연산을 소프트웨어 구현으로만 만들면 하드웨어로 구성할 때보다 속도가 너무 느리다는 문제가 생긴다. 그래서 곱셈과 나눗셈 역시 회로로 구성한다. 다만 곱셈과 나눗셈 회로는 덧셈과 뺄셈 회로와는 달리 좀 복잡하다. 실제 계산도 곱셈, 나눗셈이 덧셈, 뺄셈보다 어렵지 않은가!

십진수 곱셈과 동일하게 이진수 곱셈도 피곱셈수 각 자리수의 값을 곱셈수에 한 자리씩 밀면서 곱하면 된다. 4비트 곱셈의 경우 아래 수식이 성립된다.

여러가지 자리수로 변경해 가면서 각자 곱셈기 회로를 그려보면 알겠지만 이진수 곱셈의 결과는 곱셈수, 피곱셈수의 비트수를 더한 수 만큼이다. 그래서 4비트 * 4비트의 곱셈 결과는 8비트고, 4비트 * 3비트의 결과는 7비트다.

기본적인 곱셈 법칙은 십진수의 곱셈과 같다. 다만 이진수기 때문에 중간 단계에서 각 비트끼리 곱셈은 간단하게 AND 게이트로 구현이 가능하다. 예를 들어 B3A2의 경우에는 B 입력의 네 번째 신호선과 A 입력의 세 번째 신호선을 AND 게이트로 보낸다. 두 값이 모두 1일때는 곱셈의 결과도 1이고 둘 중 하나라도 0이면 결과도 0이다. 모두가 잘 알다 시피 AND는 곱셈이고 OR는 덧셈이다.

위 수식을 잘 보면 피곱셈수(B) 비트의 가산기가 곱셈수(A) 비트 - 1 개만큼 필요하다. 4비트끼리 곱셈의 경우 4비트 가산기가 3개 필요하다. 그래서 4비트 * 3비트의 경우 4비트 가산기 2개가 필요하다. 마찬가지로 8비트 * 8비트의 경우 8비트 가산기 7개가 필요하다. 즉 수식에서 행하는 덧셈의 줄 수 만큼 필요한 것이다. 위 수식을 보면 덧셈을 총 세 번한다.

우리가 만들고 있는 CPU는 계속 8비트 가산기를 사용했다. 그래서 8비트 * 8비트 곱셈기를 만들어야 함이 맞지만, 너무 반복되는 그림이 많으니 4비트 * 4비트 가산기만 그림으로 표현해 보겠다.

위 그림처럼 4개의 4비트 가산기를 연달아 연결해서 곱셈기를 만들었다. 곱셈 수식과 동일하게 가산기를 한 비트씩 밀면서 연결했다. 결과는 8비트다. 회로로 만든 곱셈기도 실제 수식과 구성과 모양이 똑같다. 8비트 * 8비트 곱셈기는 위 회로를 그대로 두 배 확장한 것이다. 당연히 결과도 16비트다. 지금까지 아껴왔던 가산기를 아낌없이 세 개나 사용했다. 그만큼 곱셈이라는 연산은 실제 사람이 계산하기에도 복잡하지만 기계가 계산하기에도 만만치 않은 녀석이다. 앞에서도 이야기했지만 위에서 내가 말한 가산기를 여러개 붙여서 순차적으로 계산하는 곱셈 회로 말고도 병렬적으로 한 번에 곱셈 결과를 뱉어내는 알고리즘과 회로도 있다. 하지만 그런 모든것을 설명하는 것은 이 이야기의 컨셉에도 맞지 않고 너무 어렵다. 관심있는 분들은 각자 공부해 보시면 아주 재미있는 내용들이 많이있다.

나눗셈 회로는 곱셈 회로와는 비교할 수 없을 만큼 복잡하다. 일일이 설명하기도 어렵다. 그냥 나눗셈 회로는 이렇게 생겼다라고만 알아두기 바란다.

내가 직접 그릴수가 없어서 인터넷에서 검색해서 찾은 여러가지 나눗셈 회로중에 그나마 보기 좋은 그림을 골라서 붙였다. 곱셈보다 더 많은 가산기가 필요하다. 위 나눗셈기 회로를 해석할 필요는 없다. 단지 컴퓨터로 나눗셈이 가능하다는 사실만 알면 된다.

더하기, 빼기, 곱하기, 나누기 기능을 ALU에 통합하면 아래 그림과 같은 심볼을 사용할 수 있을 것이다.

또 흔히 많이 사용하는 ALU 심볼은 오른쪽 그림처럼 안쪽으로 파인 다각형을 많이 사용한다. 하지만 나는 계속해서 왼쪽에 있는 그냥 사각형 심볼을 사용할 것이다. 이유는 없다.

지금까지 이야기한 것 처럼 CPU의 중심에는 ALU가 있다. ALU는 CPU에서 계산을 담당하는 부분이다. 실제 ALU는 내가 이야기한 것 보다 수천배는 더 복잡하고 더 많은 기능을 가지고 있다. 이 글을 쓰고 있는 지금 내 컴퓨터의 ALU와 이 이야기를 읽고 있는 지금 여러분의 ALU는 매우 바쁘게 쉬지 않고 계속 무언가를 계산하고 있다.

File attachments: 

댓글

나빌레라의 이미지

왠지 출판은 안될것 같아요...

읽어주셔서 감사합니다~^^
----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

moonend의 이미지

지금까지 애매했던 부분들이 많이 정리가 되네요. ^^;;

ubtaptt의 이미지

컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (0) : http://kldp.org/node/109764
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (1) : http://kldp.org/node/109814
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (2) : http://kldp.org/node/109901
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (3) : http://kldp.org/node/110005
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (4) : http://kldp.org/node/110137
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (5) : http://kldp.org/node/110214
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (6) : http://kldp.org/node/110311
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (7) : http://kldp.org/node/110440
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (8) : http://kldp.org/node/110515
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (9) : http://kldp.org/node/110602
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (10) : http://kldp.org/node/110670
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (11) : http://kldp.org/node/110850
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (12) : http://kldp.org/node/111015
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (13) : http://kldp.org/node/111192
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (14) : http://kldp.org/node/111678
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (15) : http://kldp.org/node/112152
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (16) : http://kldp.org/node/112552
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (17) : http://kldp.org/node/112832
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (18) : http://kldp.org/node/113385
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (19) : http://kldp.org/node/113754
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (20) : http://kldp.org/node/113854
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (21) : http://kldp.org/node/113950
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (22) : http://kldp.org/node/114146
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (23) : http://kldp.org/node/114407
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (24) : http://kldp.org/node/114537
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (25) : http://kldp.org/node/114666
컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (26) : http://kldp.org/node/114667

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.