3-1) Arithmetic

서진·2023년 4월 17일
0

컴퓨터구조

목록 보기
7/8

Addition and Subtraction

overflow : 표현할 수 있는 범위를 벗어나면 발생한다
(ex. 양수 + 양수를 했는데 sign 비트가 바뀌어서 음수가 나오는 경우)

둘의 부호가 같고, 더 큰 값에서 작은 값을 빼는 경우에는 overflow가 발생하지 않는다.

-> MIPS에서는 overflow를 무시하거나, exception을 발생시켜 해결한다

덧셈

뺄셈

뺄셈 연산은 따로 없다.
1. 빼려는 값의 2의 보수를 구해서 원래 수와 더한다.
2. 더한 결과에서 자릿수를 초과하는 비트는 버린다.
3. 더한 결과가 양수면 그대로 답. (제일 앞 비트가 0인 경우)
4. 더한 결과가 음수면 (제일 앞 비트가 1인 경우)결과의 2의 보수를 구한값이 답.

❓ 2의 보수란?
어떤 수에 대해 해당 수의 모든 비트를 반전시킨 후 1을 더한다


🚨 Multiplication

ALU (Arithmetic Logic Unit) : 더하기, 빼기, 논리연산자 AND, OR등을 처리하는 하드웨어

Multiplicand(피승수 m-bit) X Multiplier(승수 n-bit) = product (결과 m+n bit)

  1. iteration이 0일 때, 승수와 피승수를 4bit로 초기화, 나머지는 0으로 초기화
    : 피승수는 원래 4bit이지만 product와 같은 크기인 8bit로 초기화해둔다. (0000 multiplicand)

  2. 승수의 bit수 만큼 iteration을 반복
    : multiplier의 가장 오른쪽 비트가 1 -> product + multiplicand
    0 -> 아무것도 안함
    : multiplicand(피승수) shift left , multiplier(승수) shift right

✅ multiplicand는 shift left, multiplier는 shift right하는 이유

shift left - 자릿수별로 계산을 수행하기 위함. 각 자릿수의 위치를 정확히 맞춤
shift right - LSB를 계속해서 빼주기 위함!!! multiplier의 가장 오른쪽 비트를 확인하기 위함.


Optimized Multiplier

product에 더하는 과정과 shift하는 과정을 병렬적으로 수행한다. (여기서 32bit는 4bit로 줄여서 말함)

  1. product를 앞 4비트(32비트)와 뒤 4비트(32비트)로 나눈다.
    HI : 앞 32비트로 multiplicand + product의 값이 들어감
    LO : 뒤 32비트로 초기에는 multiplier로 채워짐
  2. 연산이 끝나면 오른쪽으로 shift하고 값이 1이라면 HI에 multiplicand 더해주기 (위에랑 같음)

해당 iteration 반복하기 (32번의 shift)


Signed Multiplication

multiplier와 multiplicand를 모두 양수로 바꾸고, 계산한 후 기존 부호 붙여주기


Faster Multiplication


MIPS Multiplication

product는 64bit까지 값을 가질 수 있다. 하지만 MIPS register는 기본적으로 32bit의 크기를 가진다. 따라서 special register 2개를 써서 결과값 저장한다.

-> HI : 가장 상단의 32bit
-> LO : 가장 하단의 32bit

  • 명령어들
    mult rs, rt / multu rs,rt
    rs와 rt의 값을 곱한 64bit 결과값을 HI와 LO에 저장. signed multiplication을 수행

    mfhi rd / mflo rd
    HI, LO값을 rd로 옮긴다. 오버플로우가 발생했는지 확인하기 위해 HI의 사인비트를 확인해볼 수 있음.

    mul rd,rs,rt
    rs x rt를 rd에 넣는데, 32bit 결과값을 저장. LO만 rd에 넣는다.


🚨 Division

dividend = quotient X divisor + remainder
제수가 피제수에 들어가면 1, 들어가지 않으면 0 -> 이것을 알기 위해 일단 무조건 빼기를 수행 (dividend 가 divisor보다 큰지 확인하기 위함)

피제수 - 제수 > 0 (나눠지는 수가 나누는 수보다 크면)
: 몫에 1을 준다

피제수 - 제수 < 0 (나눠지는 수가 나누는 수보다 작으면)
: 몫에 0을 주고, 제수를 다시 더해서 값을 복귀시킨다.

  1. divisor 초기에는 상위 32bit에 들어가있고, 하위 32bit는 0으로 세팅됨.
  2. remainder에는 초기에 dividend가 들어가 있음.
    dividend - divisor > 0이면 quotient를 shift left해서 최하위 비트를 1
    dividend - divisor < 0이면 divisor register + remainder register을 해서 빼기 전 값으로 복귀시키고 quotient를 shift left해서 최하위 비트 0으로
  3. divisor를 shift right한다

Optimized Division

product를 앞 32bit (remainder)와 뒤 32bit (dividend)로 나눈다

HI (앞 32비트 - remainder)
초기에는 0으로 채워져 있음
dividend - divisor < 0 이면 최하위 비트 0으로 바꾸고 divisor 다시 더해줌
연산이 끝난 후 이곳에 채워진 값이 나머지

LO (뒤 32비트 - dividend)
초기에는 dividend로 채워져 있음
왼쪽으로 shift를 수행하고, HI 연산 결과에 따라 오른쪽부터 1 또는 0이 채워짐
연산이 끝난 후 이곳에 채워진 값이


MIPS Division

HI 나머지 저장
LO 몫 저장

  • 명령어
    div rs, rt / divu rs, rt
    HI : 나머지 연산 (%)
    LO : 몫 연산 (/)

    cf) 0으로 나누는 것을 확인하거나 오버플로우를 따로 확인하지 않음. 소프트웨어가 확인해줘야 함

    mfhi / mflo
    move from hi, move from lo


profile
🫧 ☁️ 🌙 👩🏻•💻 🌿 🐱 🖱 🍟 🚀 ⭐️ 🧸 🍀 💗

0개의 댓글