※"컴퓨터 구조 및 설계 6판 MIPS EDITION" 책을 간단하게 정리한 내용의 글입니다.※
3.1 서론
아래의 질문에 답할 수 있는 내용을 배울 예정이다.
소수나 실수를 어떻게 표현하는지?
컴퓨터로 표현할 수 있는 것보다 더 큰 수가 계산의 결과로 나오면 어떻게 되는지?
하드웨어가 실제로 어떻게 곱셈, 나눗셈을 수행하는지?
3.2 덧셈과 뺄셈
컴퓨터는 덧셈을 할 때 사람이 하는 것처럼 가장 아랫 자리부터 더하고, 올림수는 그 위의 자리에 더한다. 뺄셈은 수의 부호를 바꿔서 더한다.
덧셈 시에 오버플로가 발생할 수 있다. 서로 다른 부호의 수를 더할 때는 오버플로가 발생하지 않는다. 뺄셈 시에는 부호가 같을 경우에 오버플로가 발생하지 않는다.
(덧셈과 뺄셈은 산술논리연상장치(arithmetic logic uni, ALU)에서 수행한다.
- 오버플로 탐지
- 덧셈 시: 두 양수를 더했을 때 결과가 음수라면 오버플로가 발생한 것이다. 두 음수를 더했는데 결과가 양수이면 오버플로가 발생한 것이다.
- 뺄셈 시: 양수(또는 0)에서 음수를 뺏을 때 결과가 음수이면 오버플로가 발생한 것이다. 음수에서 양수(또는 0)를 뺏을 때 결과가 양수이면 오버플로가 발생한 것이다.
< MIPS의 명령어에 따른 오버플로 처리 >
- add(add), add immediate(addi), subtract(sub) 명령어들은 오버플로가 발생하면 예외(exception)를 발생시킨다.
- add unsigned(addu), add immediate unsigned(addiu), subtract unsigned(subu) 명령어들은 오버플로가 발생해도 예외(exception)을 발생시키지 않는다.
< 언어로 인한 차이 >
- C언어
C언어는 오버플로를 무시한다. 그래서 MIPS C 컴파일러는 변수형에 관계없이 항상 부호없는 addu, addiu, subu 명령어를 사용한다. - Fortran
과학 및 공학 계산에서 주로 사용되는 Fortran은 오버플로를 무시하지 않는다. 그래서 MIPS Fortran 컴파일러는 피연산자의 데이터 형에 따라 적절한 산술 명령어를 생성한다.
3.3 곱셈
3.3 절에서는 하드웨어가 곱을 어떻게 연산하는지 본다.
피승수(multiplicand) x 승수(multiplier) = 곱(product)
이진수의 곱셈에서 승수가 0이면 0을 해당 위치에 복사하고, 승수가 1이면 피승수를 해당위치에 복사하고 더하는 작업을 한다.
< 곱셈 알고리즘과 하드웨어 순차적 버전 >
32비트 체제에서 수는 32비트로 표현된다. 32비트의 수와 32비트의 수가 곱셈을 하면 64비트의 수가 된다.
위의 이미지에서 피승수(Multiplicand)는 64비트로 이루어져 있고, 오른쪽 32비트는 피승수로, 왼쪽 32비트는 0으로 초기화된다.
그리고 사람이 곱셈을 하듯이 각 자리수를 더하고 왼쪽으로 1비트씩 자리이동 된다.
승수(multiplier)의 오른쪽 1비트를 검사해서 피승수를 더할지, 0을 더할지 결정한다. 그리고 승수(multiplier)는 오른쪽으로 1비트 자리이동 된다.
최종 결과를 얻기 위해서는 이 단계를 32번 반복해야 한다.
< 곱셈 하드웨어 수정된 버전 >
이전 버전의 경우 피승수가 더해지는 위치를 조정하기 위해 피승수는 왼쪽으로 1비트씩 자리이동 했다. 그리고 0인지 1인지 하나씩 검사하기 위해 승수는 오른쪽으로 1비트씩 자리이동 했다.
위의 수정된 버전은 자리이동을 한번만 해서 성능을 개선한 버전이다.
Product의 오른쪽 32비트를 승수로 초기화한다. 그리고 다음을 반복한다.
- 가장 오른쪽 값을 읽어서 Product의 왼쪽 32비트에 0 혹은 승수를 더한다.
- Product를 오른쪽으로 1비트 자리이동 한다.
< 부호있는 곱셈 >
원래 수의 부호를 기억한다. 그리고 두 수를 양수로 변환해서 곱셈하고 원래 수의 부호가 달랐을 경우에만 음수로 바꾼다.
< 더 빠른 곱셈 >
곱셈을 시작할 때 승수의 32개 비트를 한번에 조사해서 1인 것으르 먼저 알아내고, 1인 것만 더하기 위해 덧셈기를 여러개 할당하고 덧셈을 병렬로 처리할 수 있다. 이렇게 하면 곱셈이 훨씬 빨라진다.
< MIPS에서의 곱셈 >
MIPS에서는 64비트 곱을 저장할 수 있는 한 쌍의 32비트 레지스터를 제공한다.
그리고 mult(multiply)와 multu(multiply unsigned) 2개의 곱셈 명령을 제공한다.
3.4 나눗셈
3.4 절에서는 하드웨어가 나눗셈을 어떻게 연산하는지 본다.
피제수(dividend) = 몫(quotient) * 제수(divisor) + 나머지(remainder)
이진수의 나눗셈도 사람이 나눗셈을 하듯이 피제수의 앞쪽 자리부터 제수가 들어갈 수 있는지 보고, 들어갈 수 있으면 1, 못들어가면 0을 입력하면 된다.
< 나눗셈 알고리즘과 하드웨어 >
위의 제수(divisor)는 연산을 반복할 때마다 한칸씩 오른쪽으로 오면서 피제수(dividend)에서 뺄 수 있는지 판단한다.
뺄 수 있으면 빼고 몫(quotient)을 왼쪽으로 자리이동하고 오른쪽 1비트에 1을 입력한다. 뺄 수 없으면 빼지 않고 몫(quotient)을 왼쪽으로 자리이동한다.
< 부호있는 나눗셈 >
부호있는 곱셈과 마찬가지로 두 수의 부호를 저장하고, 두 수를 양수로 변환해서 나눗셈을 연산한다. 그리고 저장한 두 부호가 다를 경우 음수로 변환한다.
< 나눗셈 하드웨어의 개선된 버전 >
Remainder 64비트 중 왼쪽 32비트에 피제수(divident)를 넣는다. 그리고 Divisor를 왼쪽 32비트에 대해서 뺄 수 있으면 빼고 Remainder 전체를 왼쪽으로 1비트 이동하면서 오른쪽에 1을 쓴다. 빼지 못하면 0을 쓴다. 이 과정을 반복하면 결과로 64비트의 왼쪽 32비트는 나머지가 되고, 오른쪽 32비트는 몫이 된다.
< MIPS에서의 나눗셈 >
위에서 봤듯이 곱셈과 나눗셈을 하기위해서는 64비트의 레지스터가 필요하다. MIPS에서 곱셈과 나눗셈을 할 때는 Hi와 Lo 레지스터 쌍을 64비트 레지스터로 사용한다.
또한 MIPS에는 부호 있는 정수를 위한 div(divide)와 부호 없는 정수를 위한 divu(divide unsigned) 명령어가 있다.
'CS > 컴퓨터구조' 카테고리의 다른 글
[컴퓨터구조] 4 프로세서 (4.1 서론, 4.2 논리 설계 관례) (0) | 2024.11.11 |
---|---|
[컴퓨터구조] 3 컴퓨터 연산 (3.5 부동 소수점 ~) (0) | 2024.11.05 |
[컴퓨터구조] 2 명령어: 컴퓨터 언어 2.11 ~ (0) | 2024.10.15 |
[컴퓨터구조] 2 명령어: 컴퓨터 언어 2.6~ (1) | 2024.10.08 |
[컴퓨터구조] 2 명령어: 컴퓨터 언어 2.1~2.5 (0) | 2024.10.01 |