안 쓰던 블로그

컴퓨터 구조-MIPS, MIPS 구조 본문

컴퓨터 구조

컴퓨터 구조-MIPS, MIPS 구조

proqk 2020. 6. 8. 22:52
반응형

MIPS 구조

1980년대 스탠포드대학에서 John Hennessy와 그의 동료들에 의해 개발됨 

Silicon Graphics, Nintendo, Cisco의 제품에서 사용되고 있음

 

디자인 원리 

1. 규칙적인 것이 간단성을 위해 좋음 (일관성있는 명령어 형태)

2. 많이 발생되는 사항을 빨리 처리함 (복잡한 명령어를 여러개 단순한 명령어로)

3. 적을수록 빠름 (32개의 레지스터가 1000개보다 빠름)

4. 좋은 설계는 좋은 절충안을 요구함 (융통성 제공, 적은 수의 명령어 유지)


설계원칙1: 규칙적인 것이 간단성을 위해 좋음 

일관성있는 명령어 형태

같은 수의 피연산자 (두 개의 source와 한 개의 destination)

하드웨어로 구현하기 쉬움

 

명령어

addtion(더하기)

subtraction(빼기)

고급 레벨 코드 MIPS 어셈블리 코드 의미
a=b+c; add a,b,c a에 b+c를 저장
a=b-c; sub a,b,c a에 b-c를 저장

 

설계원칙2: 많이 발생되는 사항을 빨리 처리함

 

MIPS: 단순하고 많이 사용하는 명령어를 포함함

명령어를 해석하고 실행하는 하드웨어는 단순하고 빠름

복잡한 명령어는 여러 개의 단순한 명령어로 수행됨

고급 레벨 코드 MIPS 어셈블리 코드 의미
a=b+c-d; add t,b,c t에 b+c를 저장
(임시 변수 t에 저장)
sub a,t,d a에 t-d를 저장

 

설계원칙3: 적을수록 빠름

MIPS: 적은 수의 레지스터를 포함

적은 수: 32개의 레지스터 (32 비트 또는 64 비트)

 

32개의 레지스터로부터 데이터를 획득하는 것이

1000개의 레지스터 또는 메모리로부터 데이터를 획득하는 것 보다 빠름

 

32개의 MIPS 레지스터 세트 종류

고급 레벨 코드 MIPS 어셈블리 코드 의미
a=b+c; add $s0, $s1, $s2 $s0=a
$s1=b
$s2=c 저장
$s0에 $s1+$s2를 저장
a=b+c-d; sub $t0, $s2, $s3
add $s0, $s1, $t0
$s0=a
$s1=b
$s2=c
$s3=d 저장
$t0에 $s2-$s3를 저장(임시 변수 t)

$s0에 $s1+$t0을 저장

 

설계원칙4: 좋은 설계는 좋은 절충안을 요구함

 

-다중 명령어 형태는 융통성 제공

(1) add, sub: 3개의 레지스터 피연산자 사용

(2) lw, sw: 2개의 레지스터 피연산자와 상수 사용

-적은 수의 명령어 형태를 유지함


워드 주소 메모리 읽기

1워드=4바이트

주소 단위가 워드 기준

1. load 명령어(lw)

load 목적지, 주소

어셈블리 코드 의미
lw $s3, 1($0) $s3레지스터에 워드1번지(1+0=1)에서 가져온 데이터를 저장

워드1번지값이 0000 0001이므로 위에 사진 같은 경우 F2F2AC07이 $3에 저장

 

 

2. store 명령어(sw)

store 소스, 목적지

어셈블리 코드 의미
sw $t4, 0x3($0) $s4레지스터 값을 워드3번지(16진수 3+0=1)에 저장

위에 사진 같은 경우 워드3번지는 0000 0003이므로 40F30788 있는 곳에 $s4값이 저장된다

 

바이트 주소 메모리 읽기

주소 단위가 바이트 기준

 

 

1. load 명령어(lw)

load 목적지, 주소

어셈블리 코드 의미
lw $s3, 4($0) $s3레지스터에 4번지(4+0=1)에서 가져온 데이터를 저장 

왜 워드 주소 메모리랑 명령어가 같냐면, 워드 기준이든 바이트 기준이든

데이터를 가져올 때 단위는 워드로 통일이기 때문임

 

위에 사진에서 4번지는 0000 0004고 데이터는 F2F1AC07 이므로 $s3에 저 데이터가 저장됨

4번지는 워드1번지값 0000 0001 과 같은 데이터인데, 4바이트=1워드이기 때문임

 

 

2. store 명령어(sw)

store 소스, 목적지

어셈블리 코드 의미
sw $t7, 12($0) $s7레지스터 값을 12번지에 저장

위에 사진에서 12번지는 0000 000C이므로 40F30788 있는 곳에 $s7값이 저장된다

 


데이터를 읽는 방식: 빅 엔디안vs리틀 엔디안

빅 엔디안: 높은 비트에서 낮은 비트 순으로 데이터를 읽음

리틀 엔디안: 낮은 비트에서 높은 비트 순으로 데이터를 읽음

 

하드웨어에서는 보통 리틀 엔디안을 사용함

 

예제

$t0의 값이 0x23456789라고 가정한다

아래의 프로그램이 Big-Endian 시스템과 Little-Endian 시스템에서 수행한 후에 $s0의 값은?

sw $t0, 0($0)

lb $s0, 1($0)

 

sw $t0, 0($s0)은 $t0레지스터 값을 $s0레지스터에 store

lb $s0, 1($s0)은 $s0레지스터 1번 인덱스의 1바이트를 $s0에 load

 

빅 엔디안인 경우 답: $s0=00000045

리틀 엔디안인 경우 답:  $s0 = 0x00000067

왜?

빅엔디안이면 높은 비트MSB부터 낮은 비트 LSB로 레지스터에 데이터를 저장하기 때문에

23 45 67 89로 짤려서 들어가게 되고, 1번 인덱스를 가져오면 45를 꺼낸다

 

리틀엔디안이면 낮은 비트SLB->높은 비트 MSB로 저장하기 때문에 89 67 45 23 순서로 들어가고,

1번 인덱스를 가져오면 67이 나온다


기계어

명령어들의 이진 표현 (0 또는 1)

32비트 명령어

 

명령어 형태

R-Type (레지스터 타입)

I-Type (즉시값 타입)

J-Type (점프 타입)

 

1. R-Type

레지스터 타입

rs, rt : source 레지스터

rd : destination 레지스터

op : operation 코드 (op코드. 모든 R-Type명령어의 op코드값은 0이다)

funct : function

shamt : shift 명령어에서 사용되는 shift 양

 

rs, rt, rd : 3개의 레지스터 피연산자(오퍼랜드)

op, funct, shamt : 그 외

 

예) 다음과 같은 명령어가 있을 때

add $0, $s1, $s2 (=add rd, rs, rt)

sub $t0, $t3, $t5 (=sub rd, rs, rt)

 

필드값은 아래처럼 들어간다

 

R-Type명령어 op코드는 0이고

rd가 목적지, re, rt가 소스니까 한 칸씩 들어가고(레지스터 번호 17번 18번 16번)

shamt는 add연산이라 시프트0번이니까 0

funct는 add를 funct로 표기하면 32, sub를 funct로 표기하면 34

머신 코드로 바꾸면 이렇다

 

2. I-Type

즉시값(Immediate) 타입

3개의 피연산자(오퍼랜드)

rs,rt: 레지스터 피연산자

imm: 16비트 즉시값(immediate)

다른 필드

op: operation 코드 (op 코드)

각각의 I-type 명령어는 개별적인 op 코드값을 갖음

 

어셈블리 코드가 아래같이 있다면

addi $s0, $s1, 5

addi $t0, $s3, -12

lw $t2, 32($0) //load

sw $s1, 4($t1) //store

 

필드값은 이렇다

참고로 add와 addi는 다름

즉시값 immediate라서 뒤에 i가 붙었다

add rd,rs,rt 형태였다면 addi는 addi rt,rs,imm 형태

 

op 8은 addi 의미

rs, rt는 레지스터 번호

imm은 상수값

 

 

머신 코드로 하면 아래처럼

 

3. J-Type

Jump 타입

1개의 피연산자(오퍼랜드)

addr: 주소 피연산자

다른 필드

op: operation 코드 (op 코드)

 

분기할 때 썼던 jump명령어랑 비슷함

 


저장된 프로그램

32비트 명령어와 데이터는 메모리에 저장됨

 

프로그램 실행 과정

1) 프로그램을 메모리에 저장

2) 메모리에 있는 명령어 순차적으로 읽고 실행

3) 프로그램 카운터PC로 다음에 수행할 명령어 파악

 


기계어 코드 해석

opcode를 분석하는데

opcode가 0이면 R-type명령어. funct비트로 명령어 기능 분석

opcode가 0이 아니면 I-type이나 J-type 명령어


논리 명령어

and, or, xor, nor

and: 원치 않는 비트를 0으로 만드는 비트 마스킹에 쓰임

or: 두 레지스터의 비트를 결합

nor: 비트들을 역전

 

andi, ori, xori

and, or, xor에 16비트 즉시값(immediate)의 i가 붙어서, 16비트 즉시값이 피연산자로 포함됨

16비트 즉시값은 32비트로 변환될때, 제로 확장(zero-extended)됨

 

 

이동 명령어(시프트 비트연산)

sll: shift left logical

srl: shift right logical

sra: shift right arithmetic

sllv: shift left logical variable

srlv: shift right logical variable

srav: shift right arithmetic variable

 

조건부 분기-beq

beq A, B, C: A와 B가 같으면 C로 분기한다

s0에 4넣고 s1에 1넣고, sll로 쉬프트 연산해서 s1을 4로 만들고

그 다음에 beq가 나오는데 s0과 s1의 값이 4로 같기 때문에 target으로 분기한다

그 뒤에 addi, sub는 실행되지 않는다

 

 

조건부 분기-bne

bne A, B, C: A와 B가 다르면 C로 분기한다

아까랑 같이 s0은 4 s1은 4인 상태

bne를 만났는데 다르지 않으므로 분기하지 않고 계속 진행

addi와 sub명령어까지 실행한다

 

 

무조건 분기-j

j A: 무조건 A로 분기한다

j A는 무조건 분기하므로 target으로 바로 감

 

 

무조건 분기-jr

jr A: A로 분기한다(A는 주소값)

j와 달리 jr은 레지스터 $s0의 주소값을 바로 분기점으로 잡아주었다

jr을 만나면 0x2010번지인 lw로 분기한다


if문

고급 레벨 코드 MIPS 어셈블리 코드

if (i == j)  f = g + h;

f = f – i;

# $s0 = f, $s1 = g, $s2 = h
# $s3 = i, $s4 = j 저장

    bne $s3, $s4, L1

      add $s0, $s1, $s2   

L1: sub $s0, $s0, $s3

bne=만약 s3과 s4가 같지 않다면 L1으로 분기한다

만약 분기했다면 add명령어는 실행x

 

if/else문

고급 레벨 코드 MIPS 어셈블리 코드

if (i ==j) f = g + h;
else f = f – i;

# $s0 = f, $s1 = g, $s2 = h
# $s3 = i, $s4 = j 저장

    bne $s3, $s4, L1

      add $s0, $s1, $s2   
j done

L1: sub $s0, $s0, $s3
done:

bne=만약 s3과 s4가 같지 않다면 L1으로 분기하고, 분기했다면 add명령어 실행 안 함

 

if문에 걸려서 f=g+h;를 실행시키고 나면 else문은 실행하면 안 됨

그 else문 처리를 무조건 분기 j로 처리해 줌

 

 

while 반복

고급 레벨 코드 MIPS 어셈블리 코드

// determines the power
// of x such that 2x = 128

int pow = 1;
int x = 0;
while (pow != 128) {
    pow = pow * 2;
    x = x + 1;
}

# $s0 = pow, $s1 = x 

       addi $s0, $0, 1 

       add  $s1, $0, $0 

       addi $t0, $0, 128  # t0은 128

while:  beq $s0, $t0, done

       sll  $s0, $s0, 1

       addi $s1, $s1, 1

       j  while 

done:

while: beq s0 t0 done

beq는 같으면 분기하는 명령어

즉, s0과 t0이 같으면 done으로 분기하며 반복문 안의 명령어를 패스한다 

 

for 반복

고급 레벨 코드 MIPS 어셈블리 코드

//add the numbers
// from 0 to 9

int sum = 0;
int i;

for (i=0; i!=10; i = i+1) {
    sum = sum + i;
}

# $s0 = i, $s1 = sum
addi $s1, $0, 0 #sum(s1) 0
add  $s0, $0, $0 #i(s2) 0
addi $t0, $0, 10 #t0=10

for:   beq $s0, $t0, done
   add  $s1, $s1, $s0
   addi $s0, $s0, 1
   j    for
done:

for: beq s0 t0 done

s0과 t0이 같으면 done으로 분기한다

for문의 i!=10과 같은 의미이다

 

i=0부분은 add  $s0, $0, $0

sum=sum+i 부분은 add  $s1, $s1, $s0
i++은 addi $s0, $s0, 1

 

j for 은 조건을 만족할 때까지 for문을 돌게 한다

 

 

less than 비교

고급 레벨 코드 MIPS 어셈블리 코드

//add the powers of 2
// from 1 to 100

int sum = 0;
int i;

for (i=0; i<101; i = i*2) {
    sum = sum + i;
}

# $s0 = i, $s1 = sum

    addi $s1, $0, 0  #sum(s1) 0

    addi $s0, $0, 1   #i(s2) 0

    addi $t0, $0, 101  #t0=101

loop:  slt $t1, $s0, $t0
   
beq $t1, $0, done

    add  $s1, $s1, $s0

    sll  $s0, $s0, 1  

    j    loop 
done:   

for문의 i=0은 addi $s0, $0, 1

 

loop slt t1 s0 t0에서 slt를 먼저 보면,

slt a,b,c는 s0과 t0을 비교, s0이 더 크면 t0=0이고 아니라 더 작으면 1이다

즉, for문에서 i<101 부분의 비교 연산을 수행하고 있다

 

sll a,b,c는 b<<c 결과를 a에 저장한다는 의미다

한 마디로 왼쪽 이동으로 2배씩 한다

sll s0,s0,1을 했으니 s0<<1이므로 s0^2라는 말과 같게 된다


연습 문제

1. MIPS 구조에서 레지스터가 많을 수록 데이터를 획득하는 것 보다 빠르다 (O,X)

더보기

답: x

레지스터 수가 많으면 레지스터를 뒤지는 데에도 시간이 많이 걸리니까 비효율적이다

32개 레지스터 정도가 가장 빠르다

 

2. $t0의 값이 0x23456789라고 가정했을 때, 리틀 엔디안의 경우

sw $t0, 0($0)

lb $s0, 3($0)의 결과는?

더보기

답: 0x00000023

리틀 엔디안이면 LSB부터 89 67 45 23 순서로 레지스터에 들어가기 때문에(SW명령어)

lb를 하면 3번 인덱스인 23가 나온다 

 

3. R-Type에서 add를 funct로 표기하면 무슨 값인가?

더보기

답: 32

add를 funct로 표기하면 32, sub를 funct로 표기하면 34

 

4. 저장된 프로그램 실행 과정을 알맞게 나열한 것은?

1) 메모리에 있는 명령어 순차적으로 읽고 실행

2) 프로그램 카운터PC로 다음에 수행할 명령어 파악

3) 프로그램을 메모리에 저장

 

1. 1번-2번-3번

2. 2번-3번-1번

3. 3번-1번-2번

더보기

답: 3

1. 프로그램을 메모리에 저장

2. 메모리에 있는 명령어 순차적으로 읽고 실행

3. 프로그램 카운터PC로 다음에 수행할 명령어 파악

 

5. A와 B가 다르면 분기하는 명령어는?

1) beq

2) bne

3) j

4) jr

더보기

답: 2

beq는 같으면 분기

j랑 jr은 무조건 분기

 

6. for(int i=0;i<i!=10;i++) sum=sum+i; 를 MIPS어셈블리 코드로 하면?

단, 변수 i는 레지스터 $s0, 변수 sum은 레지스터 $s1으로 가정한다

더보기

#$s0 = i, $s1 = sum

for: beq $s0, $t0, done
           add  $s1, $s1, $s0
           addi $s0, $s0, 1
           j    for

 

7. 다음과 같은 MIPS어셈블리 코드가 있다

# $s0 = i, $s1 = sum

    addi $s1, $0, 0  #sum(s1) 0

    addi $s0, $0, 1   #i(s2) 0

    addi $t0, $0, 101  #t0=101

loop:  (                 )
    
beq $t1, $0, done

    add  $s1, $s1, $s0

    sll  $s0, $s0, 1  

    j    loop  
done:   

 

빈칸에 들어갈 명령어는?

더보기

답: slt $t1, $s0, $t0

s0<t0 이면 1, 반대면 0인 for문의 조건식이 들어가는 부분이다

 

반응형
Comments