CS/컴퓨터구조

[컴퓨터구조] 2의 보수 표현법(two's complement)

하루아아한잔 2022. 9. 28. 14:00

*컴퓨터 구조 및 설계 5th Edition (저자 David A. Patterson 과 John L. Hennessy)를 기반으로 작성되었습니다.

*MIPS 어셈블리언어 기반으로 작성되었습니다.

 

컴퓨터 내에서는 일련의 높고 낮은 전기 신호의 형태로 숫자를 저장하므로, 결국 기수 2인 수로 볼 수 있습니다. 모든 정보는 이진 자리 수(binary digit), 즉 비트(bit)로 구성되므로 비트가 계산의 기본 단위가 됩니다. 어떤 기수(Base)의 숫자에서 $i$번째 숫자 $d$의 값은 다음과 같습니다.

$$d*Base^i$$

예를 들어, $11_{ten}$은 $1011_{two}$와 같이 나타낼 수 있습니다. 그리고 워드는 수평으로뿐만 아니라 수직으로도 그릴 수 있기 때문에, 가장 오른쪽 혹은 가장 왼쪽 비트라고 말하면 애매할 수 있습니다. 그렇기에, 가장 오른쪽 비트를 LSB(Least significant bit) 가장 왼쪽 비트를 MSB(Most significant bit)라고 합니다. 이러한 이진 비트 패턴을 연산하는 하드웨어를 설계 할 수 있는데, 연산의 결과가 하드웨어 구현된 비트들만으로 표현이 불가능하면 오버플로우(overflow)가 발생했다고 말합니다. 

*다만, 오버플로우가 발생했을시 어떻게 해야 할지는 프로그래밍 언어와 운영체제 및 프로그램의 몫입니다.

 

컴퓨터 프로그램은 양수와 음수를 모두 계산합니다. 가장 확실한 방법은 별도의 부호를 한 비트로 표현하여 덧붙이는 방법입니다.

*이 방법의 이름은 부호와 크기(sign and magnitude)표현법 입니다.

 

그러나 부호와 크기 표현법에는 몇 가지 단점이 있었습니다.

  • 첫째로 부호가 붙는 위치가 명확하지 않습니다.
  • 두번째로 부호와 크기 표현법의 덧셈기는 부호를 결정하기 위해 한 단계가 더 필요합니다. 왜냐하면 최종 부호가 무엇이 될지를 미리 알 수 없기 때문입니다.
  • 마지막으로, 비트가 따로 붙기 때문에 양의 0과 음의 0을 갖는다는 점입니다. 

이러한 단점으로 인하여 2의 보수(two's complement)표현법을 사용하게 되었습니다. 2의 보수 표현에서 모든 음수는 MSB가 1이라는 장점이 있습니다. 따라서, 하드웨어가 양수인지 음수인지 알아보려면 MSB만 검사하며 됩니다.

*MSB를 부호 비트(sign bit)라고 부릅니다. 

 

다만 부호없는 수의 연산결과가 오버플로우를 발생시킬 수 있는 것처럼 2의 보수 연산에서도 MSB가 부호에 맞지 않는 경우 오버플로우가 발생할 수 있습니다. 

 

*부호있는 수와 부호 없는 수는 산술 연산뿐만 아니라 적재 명령어와도 상관이 있습니다. 

부호 있는 적재의 경우, 레지스터의 남는 곳을 채우기 위해 부호를  반복하여 복사하는 부호 확장(sign extension)을 하게 됩니다.

 

 

2의 보수(two's complement) 연산 계산법

 

2의 보수 연산에서 사용할 수 있는 계산법은 두 가지가 있습니다.

 

첫번째로, 모든 0을 1로, 1은 0으로 바꾸고 그 수에 1을 더하는 방법이 있습니다.

이 방식은 원래 수와 모든 비트를 역전시킨 수의 합은 $111...111_{two}$가 -1이라는 것에 기초하고 있습니다.

 

예를 들어, $2_{ten}$을 역부호화 해보겠습니다.

$$2_{ten} = 0000\,0000\,0000\,0000\,0000\,0000\,0000\,0010_{two}$$

여기서 0은 1로, 1은 0으로 변환하면 다음과 같습니다.

$$1111\,1111\,1111\,1111\,1111\,1111\,1111\,1101_{two}$$

그런 다음, 1을 더해주면 다음과 같습니다.

$$-2_{ten} = 1111\,1111\,1111\,1111\,1111\,1111\,1111\,1110_{two}$$ 

 

 

두번째로, n비트로 표현된 이진수를 n비트보다 큰 수로 바꾸는 방법입니다. load, store, branch, add 그리고 set on less than 명령어의 수치 필드에는 2의 보수 16비트 이진수가 들어갑니다. 빠른 방법은 16비트의 이진수의 최상위 비트(부호 비트)를 취해서 비어있는 왼쪽 부분에 채우고, 원래의 16비트 값은 32 비트 수의 오른쪽 부분에 그대로 복사하는 것입니다. 

*이러한 방법은 부호확장(sign extension)이라고 합니다.

$$0000\,0000\,0000\,0010_{two} = 2_{ten}$$

최상위 비트(0)를 취해서 왼쪽 부분에 16번 복사하고, 워드의 오른쪽 부분에는 원래의 값을 그대로 복사하여 32비트 이진수를 만들 수 있습니다.

$$0000\,0000\,0000\,0000\,0000\,0000\,0000\,0010_{two} = 2_{ten}$$