서론
- 이 장의 목표는 실수의 표현과 연산 알고리즘, 이러한 알고리즘을 수행하는 하드웨어, 그리고 이 모든 것들이 명령어 집합에 미치는 영향 등을 풀어 나가는 것이다.
덧셈과 뺄셈
- 컴퓨터는 사람들이 생각하는 그대로 덧셈을 수행한다.
- 손으로 계산할 때처럼 오른쪽에서 왼쪽으로 한 비트씩 더하고, 이때 생기는 올림수는 바로 왼쪽 자리로 보낸다. 손으로 덧셈을 할 때와 같이 바로 왼쪽 자리에 올림수를 보내준다.
- 뺄셈은 덧셈을 이용한다. 뺼 값의 부호를 바꾸어 더하기만 하면 된다.
예제) 7에 6을 이진법으로 더하고, 7에서 6을 이진법으로 빼라.
7 + 6
0000 0000 0000 0000 0000 0000 0000 0111 = 7
+ 0000 0000 0000 0000 0000 0000 0000 0110 = 6
-----------------------------------------------
= 0000 0000 0000 0000 0000 0000 0000 1101 = 13
7 – 6
0000 0000 0000 0000 0000 0000 0000 0111 = 7
- 0000 0000 0000 0000 0000 0000 0000 0110 = 6
-----------------------------------------------
= 0000 0000 0000 0000 0000 0000 0000 0001 = 1
2의 보수법을 이용하여 -6을 더하는 방식
0000 0000 0000 0000 0000 0000 0000 0111 = 7
+ 1111 1111 1111 1111 1111 1111 1111 1010 = -6
-----------------------------------------------
= 0000 0000 0000 0000 0000 0000 0000 0001 = 1
https://drive.google.com/uc?id=1nBIBSYQUuoLp3jMKIPCt8HgtgjRQiefZ
- 연산 결과를 사용 가능한 하드웨어로 표현할 수 없을 때 오버플로가 발생함을 상기하라.
- 부호가 다른 피연산자를 더할 경우에는 오버플로가 발생하지 않는다. 이유는 계산 결과가 두 피연산자 중 어느 하나보다는 커질 수 없기 때문이다.
- 뺄셈에서도 똑같이 오버플로가 발생하지 않는 경우가 있는데, 피연산자의 부호가 같은 경우에는 오버플로가 발생할 수 없다. 이는 두 번째 피연산자의 부호를 바꾸어 더하는 방식으로 뺄셈을 처리하기 때문이다. $c - a = c + (-a)$
- 덧셈이나 뺄셈에서 오버플로가 발생할 수 없는 경우에는 걱정할 것이 없지만, 실제로 오버플로가 발생했을 때는 어떻게 탐지할 수 있을까? 32비트 수 두 개를 더하거나 뺀 결과를 완벽하게 표현하기 위해서는 33비트가 필요할 경우가 있다.
- 워드 크기가 32비트이므로 33번째 비트는 표시할 수 없는데, 이렇게 되면 부호 비트가 결과의 부호가 아니라 크기를 나타내는 비트 중 최상의 비트 값으로 결정된다. 딱 한 비트가 부족하므로 틀릴 수 있는 것은 부호 비트 뿐이다.
- 따라서 두 양수를 더한 값이 음수가 되면 오버플로가 발생한다. 이것은 부호 비트가 올림수가 올라갔음을 의미한다.
- 이와 반대로 두 음수를 더했는데 합이 양수가 되는 경우에도 오버플로가 발생한다.
- 오버플로는 양수에서 음수를 뺀 결과가 음수가 되거나, 음수에서 양수를 뺀 결과가 양수가 되는 경우에도 발생할 수 있다. 이것은 부호 비트에서 빌림수(borrow)가 발생했음을 의미한다. 그림 3.2는 오버플로가 발생한 경우의 연산의 종류, 피연산자 및 그 결과를 보여준다.
https://drive.google.com/uc?id=1t6Zb0eICzrvcZA0uWIXNGfdNLubIRSCc
- 그러면 부호 없는 정수에서는 어떠한가? 부호 없는 정수는 오버플로가 무시되는 메모리 주소에 사용된다.
- 그러므로 컴퓨터 설계자는 어떤 경우에는 오버플로를 무시하고 다른 경우에는 이를 인식하는 방법을 제공해야 한다. MIPS는 이 두 가지 선택을 지원하기 위해 두 가지 산술 명령어를 제공한다.
- add(add), add immediate(addi)와 subtract(sub) 명령어들은 오버플로가 발생하면 예외(exception)을 발생시킨다.
- add unsigned(addu), add immediate unsigned(addiu), subtract unsigned(subu) 명령어들은 오버플로가 발생해도 예외를 발생시키지 않는다.