HyeM

[컴퓨터구조]6주차_MIPS구조 본문

Study/Computer Architecture

[컴퓨터구조]6주차_MIPS구조

Hailey_HyeM207 2020. 6. 9. 03:42

MIPS 시스템

MIPS(Microprocessor without Interlocked Pipeline Stages) : 밉스 테크놀로지에서 개발한 RISC ISA(명령어 집합구조)이다.



디자인 설계 원리 

  1. 규칙적인 것이 간단성을 위해 좋음

  2.  많이 발생되는 사항을 빨리 처리함

  3.  적을 수록 빠름

  4.  좋은 설계는 좋은 절충안을 요구함

각 설계 원칙을 하나씩 자세히 살펴보자.

 

 

 

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

" 일관성 있는 명령어 형태

같은 수의 피연산자 _ source 2개, destination 1개 "

하드웨어로 구현 쉬움

 

명령어

addition(+)과 subtraction(-)

ex ) add a, b, c          ; b와 c를 더하여 a에 저장

첫번째 오퍼랜드(a) : destination

두번째 오퍼랜드(b) : source operand1

세번째 오퍼랜드(c) : source operand2

 

High-level code

MIPS asssembly code

덧셈(Addition)

 a = b + c

add a, b, c   ; b와c를 더하여, a에 저장

뺄셈(Subtraction)

 a = b - c 

sub a, b, c

 

 

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

" MIPS는 단순하고 많이 사용하는 명령어를 포함한다. " 

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

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

High-level code

MIPS asssembly code

a  = b + c - d;

add t, b, c   # t = b +c

sub a, t, d   # a = t - d

사칙연산 같은 복잡한 코드를 여러개의 MIPS 명령어로 나누어 처리한다.

 

 

 

설계원칙#3. 적을수록 빠름

" MIPS는 적은 수의 레지스터를 포함한다. (32개 레지스터) "

레지스터의 개수가 적으면 데이터를 획득하는 속도 빠름

 

각 레지스터마다 역할이 있고, assembly 하고 연결된다. 

 

표. 32개의 MIPS 레지스터 세트

레지스터 이름 

레지스터 번호 

사용법

$0

0

상수값 0

$at

1

어셈블러 임시용

$v0 - $ v1

2-3

프로시저 리턴값 (함수 결과값)

$a0 - $a3

4-7

프로시저 인자

$t0 - $t7

8-15

임시변수

$s0 - $s7

16-23

저장변수

$t8 -$t9

24-25

임시변수

$k0 - $k1

26-27

운영체제 임시용

$gp

28

전역 포인터

$sp

29

스택 포인터

$fp

30

프레임 포인터

$ra

31

프로시저 반환(return)주소

 

레지스터를 사용한 명령어 

High-level code

MIPS asssembly code

a = b + c;

# $s0 = a, $s1 = b, $s2 = c 가저장됨. 

add $s0, $s1, $s2     ;s1과 s2의 데이터를 더해, s0에 저장

a = b + c - d;

# $s0=a , $s1=b, $s2=c, $s3=d 가 저장됨

sub $t0, $s2, $s3   #t=c-d

add  $s0, $s1, $t0  #a = b+t

 

▶ 워드(word)주소 메모리 읽기 & 바이트(byte) 주소 메모리--------------------------------------------------------------------------------

01. 워드(word)주소 메모리 읽기

1word=4Byte

말그대로, 메모리주소가 word 단위로 표시됨.

(워드 주소라, 0000 0000, 0000 0001, 0000 0002 이렇게 표시되었다.)

 

01.01_load 명령어 (lw)

lw (destination) (source)

lw $s3, 1($0)       # word1번지(1+0=1)에서 데이터를 가져와 $3레지스터에 저장해라.

                                # F2F2AC07값이 $3에 저장됨

                                # word1번지 : 0000 0001

01.02_store 명령어 (sw)

store (source) (destination)

sw $t4, 0x3($0)    # t4레지스터 값을 word3번지((16진수)3+0 )에 저장

                                  # word 3번지 는 0000 00003

 

 

02. 바이트(Byte)주소 메모리

말그대로, 주소 단위가 바이트 단위로 됨.

(바이트 주소라, 0000 0000, 0000 0004, 0000 0008, 0000 0000C 이렇게 표시되었다.)

 

01.01_load 명령어 (lw)

!!주의할점 :lw의 약자는 Load Word로, 데이터를 가져오는 양으로 word단위로 정해져 있다. 그러므로, 바이트 주소 메모리 읽기라고 해서, 바이트 단위로 데이터를 다루면 안됨. word단위로 다루기!!

lw (destination) (source)

lw $s3, 4($0)       # 4번지(4+0=4)에서 데이터를 가져와 $3레지스터에 저장해라.

                                # 0000 0004번지 데이터 : F2F1AC07

                                # 4byte는 1word 이므로, 워드 주소로 메모리 읽기에서 lw $s3, 1($0) 와 같은 위치의 메모리 위치를 가르킨다.

01.02_store 명령어 (sw)

store (source) (destination)

sw $t7, 12($0)   # t7레지스터의 값을 12번지에 데이터 저장

                                # 12번지 는 0000 000C 

 

 

-------------------------------------------------------------------------------------------------------------------------------------------------------

 

빅 엔디안 VS 리틀 엔디안   (데이터를 읽어오는 방식)--------------------------------------------------------------------------------

 

빅엔디안과 리틀엔디안은 데이터를 읽어오는 방식으로,대부분의 하드웨어는 리틀엔디안 사용하여 데이터 저장함. ( 이유 : 효율성 좋음)

(예제)

$t0의 값이 0x23456789이라 가정할 때, 아래의 프로그램을 Big-Endian 시스템 과Little-Endian시스템에서 수행한 후에 $s0값을 비교해본다.

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

lb  $s0, 1($s0)     # s0레지스터에서 1인덱스를 한 바이트만 읽어 S0에 load

 

(예제_ 답)

> Big-Endian인 경우 

 $s0 = 0x00000045

> Little-Endian인 경우

 $s0 = 0x00000067

+ 만약 lb $s0, 2($s0) 였다면, 0x00000045이다.

 

(예제_ 해설)

sw $t0, 0($s0)  :

   빅엔디안인 경우 $to의 23456789를 가장 높은 비트(MSB)부터 가장 낮은 비트(LSB)로 S0레지스터에 저장하기 때문에, 아래의 그림처럼 저장이 된다.

   반대로, 리틀엔디안인 경우 LSB에서 MSB 방향으로 저장되어, 빅엔디안과 다르게 저장된다.    

   (빅엔디안의 0인덱스는 23, 리틀엔디안의 0인덱스엔 89가 저장됨)

lb  $s0, 1($s0):

   위에서 저장한 s0의 레지스터에서 1 인덱스의 값을 읽어온다.

   빅엔디안의 경우 MSB에서 LSB방향의 1의 인덱스의 45를 읽어오고, 리틀엔디안은 LSB에서 MSB방향의 1인덱스의 67을 읽어온다.

   (결과적으로, 빅엔디안과 리틀엔디안 시스템에서 수행값은 다름)

 

-----------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

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

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

       add, sub 연산자는 3개의 레지스터 피연산자 사용

       lw, sw 연산자는 2개의 레지스터 피연산자상수를 사용

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

 

 

 

 

명령어 형태

+ 기계어 : 명령어들의 이진표현 (0,1) , 32bit 명령어

명령어 형태 

  • R-Type (레지스터 타입)

  • I-Type (즉시값 타입)

  • J-Type (Jump 타입)

 

R-Type (레지스터 타입)

-3개의 레지스터 피연산자(오퍼랜드)

     rs,rt 는 source 레지스터, rd는 destination 레지스터

 

표. R-Type 구성  _ 행(오퍼랜드, 설명)

OP (6 bits)

rs (5 bits)

rt (5 bits)

rd (5 bits)

shamt (5 bits)

funct (6 bits)

operation코드(op코드;연산코드)

모든 R-Type명령어의 op 코드값은 0

source 레지스터

source 레지스터

destination 레지스터

shift 명령어에서 사용되는 shift양(곱셈할때, shift연산함)

function

+R-Type 명령어의 op코드는 다 0이기 때문에, 명령어 기능은 funct비트를 통해 분석한다. 

 

 

(예시)

Assembly Code

add  rd, rs, rt    #add (destination), (source), (source)   ; 덧셈

Sub  rd, rs, rt    #sub (destination), (source),  (source)     ; 뺄셈

 

add $s0, $s1, $s2

sub $t0, $t3, $t5

 

Field values

add $s0, $s1, $s2 에서 rd칸에는 destination이 들어가므로, 

s0을 나타내는 16 이 저장된다.

source를 나타내는 rt와 rd칸에는 s1과 s2의 각각 17,18이 저장된다. 

(add연산이라, shift연산 0번이므로, shamt는 0이다.)

add는 funt로 표기하면 32, sub는 34이다.

 

Machine Code 

 

(위의 Field Values를 2진수와 16진수로 표기한 것이다.)

 

 

 

 

 

 

I-Type(즉시값 타입)

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

rs,rt는 레지스터 피연산자이고, imm는 16비트 즉시값이다. (상수값)

 

표. I-Type 구성  _ 행(오퍼랜드, 설명)

op(6bits)

rs(5bits)

rt(5bits)

imm(16bits_

operation(op코드)

피연산자

피연산자

즉시값

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

 

(예시)

Assembly Code

add와 addi 다름. addi의 i는 즉시값(immediate)을 가리키며, 형식은 다음과 같다.
addi (rs) (rt) (imm)  ; imm은 상수값
add는 operand가 레지스터이지만, addi는 상수값이 존재함.

 

addi rt, rs, imm    #addi (destination), (source), (source)   ; 덧셈

lw rt, imm(rs)      #lw  (destination), (source)(source)    ; load(주메모리에서 레지스터로 데이터 가져옴)

sw rt, imm(rs)      #sw (destination), (source)(source)   ; store(주메모리에 저장)

 

addi $s0, $s1, 5    #addi의 i는 상수값을 의미함. (상수값 5);  s1레지스터(16번)와 5를 더해, s0에 저장한다. 

addi $t0, $s3, -12  #s3레지스터(19번)와 -12를 더해, t0에 저장

lw   $t2, 32($0)   #32와 s0레지스터(0)을 더한 32를 t2로 가져옴

sw   $s1,  4($t1)  #4와 t1을 더하여 s1레지스터에 저장한다.
 

Field values

 

addi $s0, $s1, 5 명령어에서, 

op부분의 8은 addi를 말하고,

rs는 s1레지스터 번호17이 들어가고, rt에는 저장되는 곳인 s0의 레지스터 번호 16이 들어간다. 이때, 상수값은 imm위치에 저장된다.

(나머지도 이와 같은 원리로 저장됨)

 

 

 

Machine Code 

 

J-Type (Jump 타입)

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

  addr : 주소 피연산자

- 분기명령어 때 사용하는 명령어 형식

 

 

표. J-Type 구성  _ 행(오퍼랜드, 설명)

op(6bits)

addr(26bits)

operation 코드 (op코드)

분기(점프)할 주소값

 

 

기계어 코드 해석

단계

1. opcode 분석(operation코드)

2-1. opcode가 0이면, R-type 명령어로, 명령어 기능은 funct비트를 통해 분석한다.

2-2. opcode가 0이 아니면, I-Type 또는 J-Type 명령어이다.

 

 

위 사진은 어셈블리 코드를  field Values로 나타낸 후, 기계어로 바꾸고, 최종 16진수로 바뀐 것을 보여준다.

 

 

 

 

 

명령어 알아보기

 

논리(logical)명령어

@and, or ,xor, nor

and $s3, $s1, $s2  #and :비트마스킹에 유용

or  $s4, $s1, $s2   #or : 두 레지스터 비트 결합시키는데 유용

xor $s5, $s1, $s2    

nor $s6, $s1, $s2    #nor : 비트들 역전시킴

ㄴ $s1과 $s2는 source로, 둘을 연산한 result는 각각 $s3, $s4, $s5, $s6에 저장됨.

 

@andi, ori, xori

and,or,xor에 i를 붙인 것이니까, 16비트의 즉시값이 피연산자로 포함됨.

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

 

andi $s2, $s1, 0xFA34  #3번째 오퍼랜드로 imm(상수값)확인 가능
ori  $s3, $s1, 0xFA34 

xori $s4, $s1, 0xFA34

 

 

이동(Shift) 명령어 

비트연산 

‰sll: shift left logical

‰srl: shift right logical

‰sra: shift right arithmetic

‰sllv: shift left logicalvariable

‰srlv: shift right logical variable

‰srav: shift right arithmetic variable

 

 

조건부 분기 (beq)

#MIPS 어셈블리 코드

beq (비교1) (비교2) (분기주소)     #( 비교1)과(비교2)가 같으면 (분기주소)로 분기(jump)한다.

addi $s0, $0, 4    # $s0 = 0 + 4 = 4 

addi $s1, $0, 1    # $s1 = 0 + 1 = 1 

sll  $s1, $s1, 2   # $s1 = 1 << 2 = 4    ; $s1의 값은 1인데 shift연산 2번하면 4가 되고, 이는 $s1에 저장된다. 

                              #   Sll은 비트연산을 의미한다.  예를 들어 0001(1) 를 shift연산 1번하면 0010(2)가 되고, shift연산 2번하면 0100(4)가 된다.

                              #     =>0001(1) << 0100(4)

beq $s0, $s1, target # branch is taken ; 분기 o

                                         # $s0과 $s1이 4로 값이 같기때문에,  target으로 분기한다. 그래서, 이 다음의 코드는 실행이 되지 않고, target으로 분기한다.

addi $s1, $s1, 1       # not executed ;실행 x

sub  $s1, $s1, $s0     # not executed  ;실행 x

....

target : 

  add $s1, $s1, $s0   # $s1 은 s1(4) +S0(4)하여 8이다.  ; 실행 o 

 

 

 

 

조건부 분기(bne)

#MIPS 어셈블리 코드

bne(비교1) (비교2) (분기주소)      #( 비교1)과(비교2)가  다르면,  (분기주소)로 분기(jump)한다.

addi $s0, $0, 4          # $s0 = 0 + 4 = 4 

addi $s1, $0, 1          # $s1 = 0 + 1 = 1 

sll  $s1, $s1, 2         # $s1 = 1 << 2 = 4 

bne $s0, $s1, target # branch not taken  ; s0(4)와 s1(4)는 같으므로, 분기 하지 않는다. ; 분기 x

addi $s1, $s1, 1      # $s1 = 4 + 1 = 5  ; 실행o

sub  $s1, $s1, $s0  # $s1 = 5 – 4 = 1 ; 실행o

....

target : 

  add $s1, $s1, $s0   # $s1 은 s1(4) +S0(4)하여 8이다.  ; 실행 x _(분기발생하지 않음)

 

 

 

무조건 분기(j)

#MIPS 어셈블리 코드

j (target)     # (target)으로 분기한다.

addi    $s0, $0, 4     # $s0 = 4 
a
ddi    $s1, $0, 1     # $s1 = 1 
j    target      # jump to target    j는 target으로 무조건 분기한다.
sra $s1, $s1, 2     # not executed ; 위에서 분기하여 , 실행x
addi $s1, $s1, 1      # not executed,  실행x
sub  $s1, $s1, $s0       # not executed , 실행x

....

target: add  $s1, $s1, $s0      # $s1 = 1 + 4 = 5    # 분기 하였으므로, 실행O

 

 

무조건 분기(jr)

#MIPS 어셈블리 코드

jr (target)     # (target)으로 분기한다.

레지스터가 가진값이 주소로 인식 되어 그 주소로 이동한다.

0x00002000           addi $s0, $0, 0x2010 
0x00002004            jr $s0       # jr은 j와 달리 주소를 명시해준다. s0의 주소 2010으로 분기하게된다. 
0x00002008           addi $s1, $0, 1 
0x0000200C            sra $s1, $s1, 2 
0x00002010            lw $s3, 44($s1)

 

 

if문 

#MIPS 어셈블리 코드

High-level code

MIPS assembly code

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

f = f – i;

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

      bne $s3, $s4, L1  #s3(i)와 s4(j)가 같지 않으면 L1으로 분기한다. ( 분기하게 되면 아래의 add 연산은 하지 않음. 즉 i와 j가 달라, if문 실행 x)

      add $s0, $s1, $s2   

L1: sub $s0, $s0, $s3

 

 

if / else 문

#MIPS 어셈블리 코드

High-level code

MIPS assembly code

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

else

  f= f -i ;

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

     bne $s3, $s4, L1  #s3(i)와 s4(j)가 같지 않으면, L1으로 분기한다. 분기하면 add 명령어 실행 x

     add $s0, $s1, $s2  #f = g+h; 위에서 같으면 실행하고, pc(프로그램카운터) 1증가
       done  # j로 무조건 분기 안해주면,   if문 실행하고, else문 까지 코드를 실행 하게 되는 것과 같으므로, j(무조건분기)명령어를 이용하여, done으로 분기한다. 

L1:   sub $s0, $s0, $s3 

done:

 

 

while 루프

#MIPS 어셈블리 코드

High-level code

MIPS assembly code

// 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   #s0(pow)랑 t0(128)과 같으면, done으로 분기하여, while문을 탈출한다. 그렇지 않다면, while문을 돈다. (아래 명령어 실행)

        sll  $s0, $s0, 1

        addi $s1, $s1, 1

        j    while     #무조건분기 j명령어로 while로 돌아감. 조건 만족하지 않을 때 까지 반복 

done:

for 루프

#MIPS 어셈블리 코드

High-level code

MIPS assembly code

//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  #s1(sum)은 0
           add  $s0, $0, $0  #s0(i)은 0
           addi $t0, $0, 10  #t0은 10

for:   beq $s0, $t0, done  #s0(1)과 t0(10)이 같으면, done으로 분기한다. 즉, for문의 조건식임.
           add  $s1, $s1, $s0  #s1= s1 + s0 ; sum =sum+i
           addi $s0, $s0, 1  #s0에 +=1  ; i++
           j    for  #조건을 만족할 동안 for문 계속 돌기

done:  #for문을 다 돌고 나옴.

 

Less Than 비교

#MIPS 어셈블리 코드

slt $t1, $s0, $t0        #$t1=1 if $s0 < $t0   ; s0과 t0을 비교해서, s0이 작으면, t=0이다. 그 외라면, t1은 0이다.

sll  $s0, $s0, 1           # s0은 s0 * 2의 1승      ; sll 명령어는 왼쪽으로 비트를 한칸씩 이동시켜 값을 두배 증가시키는 명령어이다.

High-level code

MIPS assembly code

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

int sum = 0;

int i;

for (i=1; i < 101; i = i*2) {

    sum = sum + i;

}

# $s0 = i, $s1 = sum

        addi $s1, $0, 0  #s1=0 ; sum=0

       addi $s0, $0, 1   #s0=1 ; i=1

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

loop:  slt $t1, $s0, $t0   #s0(i)와 t0(101)을 비교하여, i인 s0이 더 작다면, t1은 1이다. 

       beq $t1, $0, done #t1(1)과 s0(0)이 같다면, done으로 분기한다. 
     즉, 분기하기 위해선(for문 탈출), t1의 값이 0이여야 한다.
    (t1의 값은 위의 slt 명령어로 인해, s0(i)가 t0(101)보다 커야지만 0이 된다.)

       add  $s1, $s1, $s0 #s1= s1 + s0 ; sum =sum+i

        sll  $s0, $s0, 1     #s0(i)에 2를 곱한다

        j    loop   # 조건을 만족할 동안, for문 반복

done:   #for문을 다 돌고 나옴

 

 


출처 

2019 컴퓨터 구조 호준원교수님 강의노트 9

디지털논리와 컴퓨터 설계, Harris et al. (조영완 외 번역), 사이텍미디어, 2007

컴퓨터 구조와 원리 (비주얼 컴퓨터 아키텍쳐), 신종홍 저, 한빛미디어, 2011

 

 

 

문제 

1. 다음 중 옳은 것을 것을 고르시오. 

1. MIPS에서  add와 sub 명령어는 오퍼랜드가 3개로, 일관성 있는 명령어 형태이다. 
2. MIPS에선복잡한 명령어를 여러개의 단순한 명령어로 수행하여, 많이 발생되는 사항을 빨리 처리한다. 
3. MIPS는 31개의 레지스터를 포함하여, 데이터를 획득하는 속도가 빠르다.
4. lw 명령어가 데이터를 가져오는 양은 word단위이다.
5. MIPS는 령어 형태가 지정되어 있고, 적은 수의 명령어 형태를 유지한다.

 

2. t0의 값이 12345678이라 가정할때, 다음 프로그램을 Littile-Endian시스템에서 수행한 후에 $0값을 구하시오. 

sw $t0, 0($s0)

lb $0, 2($s0) 

 

3. addi $s0, $s1, 5의 명령어는 무슨 타입 명령어인가? 그리고, field values를 채우시오.

op

rs

rt

imm

4. 다음을 o,x 로 구분하시오.

 (1) add $s0, $s1, $2는 R-Type의 명령어 형태로,op에는 0이 들어가고, s0은 rd칸에 레지스터 번호 16이, s1과 s2는 rs와 rt칸에 레지스터 번호(17,18)이 저장 된다.

(2)s0의 값은1이고, s1의 값이 2라고 할때,

bne $s0, $s1, target  

addi $s1, $s1, $1

명령어 에서 addi부분의 명령어는 실행이 되지 않는다. 

 

5. 다음 빈칸에 알맞는 코드를 작성하시오

High-level code

MIPS assembly code

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

else

  f= f -i ;

# $s0 = f, $s1 = g, $s2 = h 
# $s3 = i, $s4 = 50

    (        )   $s3, $s4, (        )

     add $s0, $s1, $s2  
    (        ) done    

L1:   sub       )

done:

 

6. 다음 빈칸에 알맞는 코드를 작성하고, for문을 실행하고 난 후의 sum의 값은 무엇인가?

MIPS assembly code

MIPS assembly code

 

int sum = 0;

int i;

(                                      )


  sum = sum + i;

}


# $s0 = i, $s1 = sum 

           addi $s1, $0, 0  

           addi  $s0, $0, 2  

           addi $t0, $0, 8 

for:   beq $s0, $t0, done 

           add  $s1, $s1, $s0 

           addi $s0, $s0, 2

           j    for  

done:  

 

 

7. 다음 빈칸에 알맞는 코드를 작성하시오. 

High-level code

MIPS assembly code

int sum = 0;

int i;

for (i=0; i < 50 i = i*2) {

    sum = sum + i;

}

# $s0 = i, $s1 = sum

        addi $s1, $0, 0  

                                               )

                                               )

loop:                                      ) 

                                                 )

       add  $s1, $s1, $s0

             )$s0, $s0, 1     

        j    loop   

done: 

정답은 더보기에 있음.

 

 

더보기

정답

 

1. 다음 중 옳은 것을 것을 고르시오. 

1. MIPS에서  add와 sub 명령어는 오퍼랜드가 3개로, 일관성 있는 명령어 형태이다. 
맞음. add와 sub 명령어 형태는 "명령어 (destination) (source) (source)" 로, 오퍼랜드가 3개이고, 명령어 형식이 지정되어 있다.
2. MIPS에선복잡한 명령어를 여러개의 단순한 명령어로 수행하여, 많이 발생되는 사항을 빨리 처리한다. 
맞음. 예를 들어 사칙연산 같은 복잡한 코드를 여러개의 MIPS 명령어로 나누어 처리하게 되어, 빠르다.
3. MIPS는 31개의 레지스터를 포함하여, 데이터를 획득하는 속도가 빠르다.
아니다. MIPS의 레지스터 수는 총 32개이다. $0의 0번부터 시작해서, $ra의 31번까지의 레지스터가 있다. 
4. lw 명령어가 데이터를 가져오는 양은 word단위이다. 
맞음. lw은 Load Word의 약자로, 데이터를 가져오는 양은 word이다.
5. MIPS는 명령어 형태가 지정되어 있고, 적은 수의 명령어 형태를 유지한다.
맞음. 예를 들어 add,sub연산자는 3개의 레지스터 피연산자를 사용하고, lw와 sw 연산자는2 개의 레지스터 피연산자와 상수를 사용하는 등 명령어 형태가 지정되어 있다. 

답은 3번

2. t0의 값이 12345678이라 가정할때, 다음 프로그램을 Littile-Endian시스템에서 수행한 후에 $0값을 구하시오. 

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

lb $s1, 2($s0)   # s0레지스터에서 한 바이트만 읽어 S0에 load

 

sw $t0, 0($s0)에서, s0에 12345678이 저장될때, little엔디안 방식으로 LSB에서 MSB방향으로 저장이 되므로,

[0]78 ,[1]56, [2]34, [3]12 이렇게 저장이 된다.

lb로 2번째 인덱스를 뽑아오니까, 34되므로,답은 0x00000034

 

 

3. addi $s0, $s1, 5의 명령어는 무슨 타입 명령어인가? 그리고, field values를 채우시오.

상수값 5가 들어있으므로, I-Type의 명령어 이다.

op  8  (덧셈 명령어 addi)

rs (피연산자)  s1레지스터 번호 17

rt(피연산자)  S0레지스터 번호인 16

imm(즉시값)   5

 

4. 다음을 o,x 로 구분하시오. 

(1) add $s0, $s1, $2는 R-Type의 명령어 형태로, op에는 0이 들어가고, s0은 rd칸에 레지스터 번호 16이, s1과 s2는 rs와 rt칸에 레지스터 번호(17,18)이 저장 된다.

O, R-type명령어는 3개의 레지스터 피연산자가 있는 명령어 형태로 맞다. 구성은 op와 rs, rt, rd, shamt,그리고 funct로 구성되어 있다.

op에는 R-type이라 0이 저장되고, rs과 rt에는 source레지스터인 s1과 s2의 번호가(17,18) 저장된다. destination인 rd에는 s0의 레지스터번호(16)가 저장되고, shamt칸은 add연산이라 0이 되고, funct에는 add명령어를 가리키는 32가 저장된다.  

(2)s0의 값은1이고, s1의 값이 2라고 할때,

bne $s0, $s1, target   #s0과 s1의 값이 다르면 target으로 분기함.

addi $s1, $s1, $1 #s1에 +1함.

target : add $s1, $s1, $s0

명령어 에서 addi부분의 명령어는 실행이 되지 않는다. 

O, bne는 다르면 분기하는 명령어 인데, s0은 1이고, s1은 2로 둘의 값이 달라 분기한다. 이때, addi 명령어는 실행 되지 않는다.

 

5. 다음 빈칸에 알맞는 코드를 작성하시오.

High-level code

MIPS assembly code

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

else

  f= f -i ;

# $s0 = f, $s1 = g, $s2 = h 
# $s3 = i, $s4 = 50

     bne )   $s3, $s4, ( L1 )   # s3(i)와 s4(j)를 비교해서 다르면 L1으로 분기하게 한다. (같으면, 아래의 add연산 실행)

     add $s0, $s1, $s2     # f =g+h; 위에서 같으면 실행함.
     j  ) done           #아래의 L1은 else이고, 위에는 if문의 코드이므로, if문을 만족하면, else문을 실행하지 않고, 뛰어넘어야 하기 때문에, done으로 무조건분기 (J)한다.

L1:   sub   $s0, $s0, $s3  )    #else부분의 코드; s0=s0-s3; 즉 f=f-i 
sub (destination) (source1) (source2)

done:

 

 

6. 다음 빈칸에 알맞는 코드를 작성하고, for문을 실행하고 난 후의 sum의 값은 무엇인가?

MIPS assembly code

MIPS assembly code

 

int sum = 0;

int i;

 for (i=2; i!=8; i = i+=2)  )


  sum = sum + i;

}


# $s0 = i, $s1 = sum 

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

           addi  $s0, $0, 2   #s0(i)는 2

           addi $t0, $0, 8  #t0은 8  (t0은 if문에서 조건식에 쓰이는 값)

for:   beq $s0, $t0, done   #s0(i)와 t0(8)이  같으면(조건 만족하지 않으면,) done으로 분기함.

           add  $s1, $s1, $s0  #s1=s1+s0; sum=sum+i;

           addi $s0, $s0, 2  #s0에 2를 더한다. , i+=2

           j    for   #조건을 만족할 동안 for문 계속돌기

done#for문 다 돌고 나옴. 

출력값은 : 2+4+6 = 12이다. 

 

7. 다음 빈칸에 알맞는 코드를 작성하시오. 

High-level code

MIPS assembly code

int sum = 0;

int i;

for (i=;0 i < 25 i = i*2) {

    sum = sum + i;

}

# $s0 = i, $s1 = sum

        addi $s1, $0, 0   #s1 =0; sum=0

                addi $s0, $s0, 0       )  #s0=0; i=0

                addi $t0, $s0, 25      ) #t0=25

loop:       slt $t1, $s0 $t0      )   #s0(i)가 t0(25)보다 작으면,t1은1이다. 그 외의 경우엔 t1은 0이다. 

                 beq $t1, $s0, done ) #t1이 0이라면 done으로 분기한다. t1이 0이 되는 경우는, 위의 코드에서, i가 25보다 커지는 경우이다.

       add  $s1, $s1, $s0 #s1=s1+s0; sum+=i

       sll  )$s0, $s0, 1      #s0(i)에 2를 곱한다.

        j    loop   #조건을 만족할 동안, for문 반복한다. 

done:  #for문을 다돌고 나온다. 

 

 

 

Comments