본문 바로가기
컴퓨터 구조

컴퓨터구조 6주차

by 몰라몰라개복치 2020. 6. 13.

MIPS 시스템

 

 

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

 

디자인 원리

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

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

- 적을수록 빠름

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

 

 

 

 

설계 원칙 1

 

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

- 일관성 있는 명령어 형태

- 같은 수의 피연산자 => 2개의 source와 1개의 destination

 

ex 1) 덧셈 Addition

 

High-level code                MIPS assembly code

     a=b+c;                             add a, b, c

 

=> b와 c를 더한 뒤 a에 저장

 

 

ex 2) 뺄셈 Subtraction

 

High-level code                MIPS assembly code

     a=b-c;                             sub a, b, c

 

=> b에서 c를 뺀 뒤 a에 저장

 

 

 

 

 

 

 

 

설계 원칙 2

 

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

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

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

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

 

 

High-level code                MIPS assembly code

 a = b + c – d;                add t, b, c   # t = b + c

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

 

 

 

 

 

 

 

설계 원칙 3

 

적을수록 빠름

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

32개의 레지스터 (323 비트 또는 64 비트)

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

 

 

MIPS 레지스터 세트

이렇게 32개의 레지스터에 각자 역할을 정해 두고 어셈블리의 형태를 짠 것이 MIPS 구조

 

 

 

ex) 레지스터를 사용한 명령어

 

High-level code                MIPS assembly code

  a = b + c;                 # $s0 = a, $s1 = b, $s2 = c

                                       add $s0, $s1, $s2

 

High-level code                MIPS assembly code

  a = b + c - d;        # $s0 = a, $s1 = b, $s2 = c, $s3=d

                                       sub $t0, $s2, $s3

                                       add $s0, $s1, $t0

 

 

 

 

 

워드 주소 메모리

 

1Word=4Byte

 

 

 

워드 주소 메모리 읽기

(1) load 명령어 (lw) 

Assembly code

lw $s3, 1($0)    # read memory word 1 into $s3

->워드 1번지에서 데이터를 가져와서 $s3 레지스터 넣어라

 

 

(2) store 명령어 (sw)

Assembly code

sw $t4, 0x3($0)       # # write the value in $t4

                          # to memory word 3

->t4 레지스터에 있던 값을 워드 3번지에 데이터 저장

 

 

즉 임시 레지스터에 저장되어 있던 값이 40F30788이었던 것!

 

 

 

 

 

 

 

 

 

 

 

바이트(byte) 주소 메모리

주소 체계가 달라짐

 

바이트 주소 메모리 읽기

(1) load 명령어 (lw) 

MIPS Assembly code

lw $s3, 4($0)       # read word at address 4 into $s3

->4번지에 있는 데이터를 가지고 와서 s3레지스터에 넣겠다 (가지고 오는 양은 1word, 바이트 단위로 다루는 것 X)

레지스터에 들어가는 값은 F2F1AC07

 

 

(2) store 명령어 (sw)

MIPS Assembly code

sw $t7, 12($0)  # write $t7 into address 12

->t 레지스터의 데이터를 12번지에 넣어라 

임시레지스터에 들어가 있던 값은 40F30788이었음

 

 

 

 

 

Big-Endian vs. Little-Endian

데이터를 읽어오는 방식에 대한 이야기

MSB: 제일 높은 비트

LSB: 제일 낮은 비트

주로 리틀 엔디안 방식으로 데이터를 읽어 옴

 

 

예제

$t0의 값이 0x23456789라고 가정. 아래의 프로그램이 Big-Endian 시스템과 Little-Endian 시스템에서 수행한 후에 $s0의 값은?

 

sw $t0, 0($0)                        Big-Endian: $s0 = 0x00000045

                                          

lb $s0, 1($0)                        Little-Endian: $s0 = 0x00000067

(**한 바이트만 읽겠다)

Big-Endian의 저장방향: →               Little-Endian의 저장방향: 

Big-Endian 방식으로 읽게 되면 MSB부터 읽게 되므로 45, Little-Endian으로 읽어 오게 되면 주소 체계가 바뀌어 LSB부터 읽게 되므로 67이 저장

(데이터를 읽어오는 방식이 다르기 때문에 각 방식으로 읽어왔을 때 $s0에 저장되는 값이 다름)

 

 

 

 

 

 

 

 

 

 

설계 원칙 4

 

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

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

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

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

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

 

기계어

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

- 32비트 명령어

 

명령어 형태

(1)R-Type

(2)I-Type

(3)J-Type

 

 

 

(1)R-Type

 

레지스터 타입

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

 - rs,rt: source 레지스터

 - rd: destination 레지스터

 

 

다른 필드

- op: operation 코드 (op 코드)

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

- funct: function

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

17번 레지스터와 18번 레지스터를 더해서 16번 레지스터에 넣어 주고 op 코드는 항상 0, 곱하기 나누기 계산이 없으므로 shamt도 0 더하는 명령어라 funct값은 32

11번 레지스터에서 13번 레지스터를 뺀 뒤 8번 레지스터에 넣어 준다 op 코드는 항상 0, 곱하기 나누기 계산이 없으므로 shamt도 0 빼는 명령어라 funct 값은 34

 

이것을 기계어 코드로 바꾸면,

 

 

 

 

(2)I-Type

 

- 즉시값(Immediate) 타입

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

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

   imm: 16비트 즉시값(immediate)

 

 

 

 

다른 필드

  op: operation 코드 (op 코드)

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

 

17번 레지스터와 5를 더해서 16번 레지스터에 넣는다 더하는 명령어라 op 코드는 8

19번 레지스터에서 12라는 함수값을 빼서 8번 레지스터에 넣는다

32를 10번 레지스터에 넣어라

4를 17번 레지스터에 저장해라

 

이를 기계어로 바꾸면

 

 

 

 

 

(3)J-Type

- Jump 타입

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

   addr: 주소 피연산자

- 다른 필드

   op: operation 코드 (op 코드)

 

 

저장된 프로그램

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

- 프로그램 실행

   프로그램을 메모리에 저장

   메모리에 있는 명령어들을 순차적으로 읽어서 실행

   프로그램 카운터 (PC)를 이용해서 다음에 수행할 명령어 파악

 

 

 

 

 

 

 

기계어 코드 해석

 

(1) opcode 분석

(2) opcode가 0이면, 

  R-type 명령어

  func 비트를 통해서 명령어 기능 분석

(3) opcode가 0이 아니면,

  I-type 또는 J-type 명령어

 

어셈블리 코드를 Field Values로 바꾸고 Field Vlaues를 Machine Code로 바꾸고 그것을 16진수로 바꾸는 과정

 

 

 

 

 

논리 명령어

- and, or, xor, nor

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

  or: 두 레지스터의 비트를 결합시키는데 유용

  nor: 비트들을 역전시키는데 유용

- andi, ori, xori

  16비트 즉시값(immediate)이 and, or, xor의 피연산자로 포함

  16비트 즉시값은 32비트로 변환될때, 제로 확장(패딩)

  

 

 

 

 

 

 

조건부 분기(beq)

 

beq: 두 레지스터의 값이 동일할 경우 분기

 

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

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

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

(sll은 비트연산임. 첫 번째 비트 연산을 했을 떄는 0010, 2가 됨 두 번째 비트연산을 하면 0100, 4가 됨.)

beq $s0, $s1, target      # branch is taken

($s0, $s1이 같으면 target으로 분기해라. 이때 두 레지스터의 값이 같기 때문에 target으로 이동)

addi $s1, $s1, 1            # not executed

(분기했으므로 실행하지 않음)

sub $s1, $s1, $s0          # not executed

(분기했으므로 실행하지 않음)

target:

add $s1, $s1, $s0

 

 

 

 

 

조건부 분기(bne)

 

bne: 두 레지스터의 값이 동일하지 않을 경우 분기

 

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, $s1이 다르면 target으로 분기해라. 두 레지스터의 값이 같기 때문에 분기 X)

addi $s1, $s1, 1                 # $s1 = 4 + 1 = 5

(실행됨)

sub $s1, $s1, $s0               # $s1 = 5 – 4 = 1

(실행됨)

target:

add $s1, $s1, $s0 # $s1 = 1 + 4 = 5

 

 

 

 

 

무조건 분기 (j)

 

j: 무조건 분기

 

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

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

j target                        # jump to target

(무조건 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

 

 

 

 

무조건 분기(jr)

 

jr: 주소로 무조건 분기 레지스터가 가진 값을 주소로 판단하고 그 주소로 이동

 

0x00002000          addi $s0, $0, 0x2010

0x00002004          jr $s0

0x00002008         addi $s1, $0, 1

0x0000200C         sra $s1, $s1, 2

0x00002010         lw $s3, 44($s1)

 

 

 

 

 

 

if 문

어셈블리어에선 같지 않으면 분기하고 같으면 분기하지 않는다. 바로 다음 명령어 수행

 

 

 

if/else 문

s3과 s4 레지스터가 같지 않으면 L1 분기 / 같으면 분기하지 않고 그 다음 명령어

j done 무조건 분기를 써서 if와 else식 구분

 

 

while문

pow가 128이 되면 while문을 빠져나오는 코드

=> $s0와 $t0가 같으면 done으로 분기. 이때 $s0는 pow고 $t0는 128이라고 선언된 상태. 즉, $s0가 128일 때 분기.

 

 

 

 

for 루프

j for 무조건 분기를 사용하여 for문 반복

 

 

 

Less Than 비교

뒤에 있는 두 레지스터의 값을 비교하여 만약 앞에 있는 레지스터가 더 작다면 맨 첫 번째 오퍼랜드에 있는 레지스터의 값을 1로 세팅

 

 

 

 

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

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

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

 

 

문제

더보기

Q1. MIPS 시스템 디자인 원리로 틀린 것은?  (       ) 

ㄱ. 규칙적인 것이 간단성을 위해 좋다

ㄴ. 많이 발생되는 사항을 빨리 처리한다

ㄷ. 적을수록 느리다

ㄹ. 좋은 설계는 좋은 절충안을 요구한다

 

 

 

Q2~Q3. 다음은 워드 주소 메모리를 읽는 것에 관한 설명이다 맞으면 O, 틀리면 X를 선택하시오

 

 

 

 

 

 

 

 

 

 

Q2) lw $s3, 1($0)라는 어셈블리 코드는 워드 1번지에서 데이터를 가지고 와서 $s3 레지스터에 값을 넣으라는 뜻이다 (      )

Q3) sw $t4, 0x2($0)라는 어셈블리 코드는 t4 레지스터에 있던 값을 워드 2번지에 저장하란 뜻이다. 그림을 통해 t4레지스터에 저장되어 있던 값이 40F30788이었던 것을 알 수 있다.  (        )

 

 

 

Q4) 다음은 Big-EndianLittl-Endian에 관한 설명이다 다음 중 틀린 것은?

1.     데이터를 읽어 오는 방식의 차이다

2.     MSB는 제일 높은 비트를 말한다

3.     LSB는 제일 낮은 비트다

4.     빅 엔디안의 저장 방향은 MSB->LSB, 리틀 엔디안의 저장 방향은 LSB->MSB

5.     주로 빅 엔디안 방식으로 데이터를 읽어온다

 

 

 

Q5) 다음 그림은 기계어의 명령어 타입 중 하나이다. 어떠한 타입의 명령어일까?  (       )

 

 

Q6) ㄱ~ㅂ까지의 어셈블리 코드 중에서 실행되지 않는 줄을 모두 고르시오 (         )

 

 

 

Q7) 다음은 if/else 문을 MIPS assembly code로 변형한 것이다 밑줄 친 부분에 들어갈 코드는? (           )

 

 

 

정답

더보기

A1. MIPS 시스템 디자인 원리로 틀린 것은?  (       ) 

ㄱ. 규칙적인 것이 간단성을 위해 좋다

ㄴ. 많이 발생되는 사항을 빨리 처리한다

ㄷ. 적을수록 느리다

적을수록 느린 것이 아니라 빠르다

ㄹ. 좋은 설계는 좋은 절충안을 요구한다

 

 

 

Q2~Q3. 다음은 워드 주소 메모리를 읽는 것에 관한 설명이다 맞으면 O, 틀리면 X를 선택하시오

 

 

 

 

 

 

 

 

 

 

Q2) lw $s3, 1($0)라는 어셈블리 코드는 워드 1번지에서 데이터를 가지고 와서 $s3 레지스터에 값을 넣으라는 뜻이다 ( O )

Q3) sw $t4, 0x2($0)라는 어셈블리 코드는 t4 레지스터에 있던 값을 워드 2번지에 저장하란 뜻이다. 그림을 통해 t4레지스터에 저장되어 있던 값이 40F30788이었던 것을 알 수 있다.  (  X   )

sw $t4, 0x2($0)라는 어셈블리 코드는 t4 레지스터에 있던 값을 워드 2번지에 저장하란 뜻이다. 그림을 통해 t4 레지스터에 저장되어 있던 값이 01EE2842였던 것을 알 수 있다

 

 

 

Q4) 다음은 Big-Endian Littl-Endian에 관한 설명이다 다음 중 틀린 것은?

1.     데이터를 읽어 오는 방식의 차이다 (o)

2.     MSB는 제일 높은 비트를 말한다 (o)

3.     LSB는 제일 낮은 비트를 말한다 (o)

4.     빅 엔디안의 저장 방향은 MSB->LSB, 리틀 엔디안의 저장 방향은 LSB->MSB다 (o)

5.     주로 빅 엔디안 방식으로 데이터를 읽어온다 (x)

->주로 리틀 엔디안 방식으로 데이터를 읽어온다

 

 

 

Q5) 다음 그림은 기계어의 명령어 타입 중 하나이다. 어떠한 타입의 명령어일까?  (   I-Type    )

3개의 피연산자(오퍼랜드)를 가지는 즉시값(Immediate)타입이다

 

 

Q6) ㄱ~ㅂ까지의 어셈블리 코드 중에서 실행되지 않는 줄을 모두 고르시오 (  ㅁ, ㅂ   )

 

ㄹ의 코드를 해석해 보면 $s0, $s1이 같으면 target으로 분기하라는 뜻이다. 이때 두 레지스터의 값이 같이 때문에 target으로 이동하게 된다 따라서 ㅁ, ㅂ는 실행되지 않는다

 

 

Q7) 다음은 if/else 문을 MIPS assembly code로 변형한 것이다 밑줄 친 부분에 들어갈 코드는? (  j done   )

if/else문을 어셈블리 코드로 표현하면 j done 무조건 분기식을 써서 if식과 else식을 구분해야 한다.

 

'컴퓨터 구조' 카테고리의 다른 글

컴퓨터 구조 5주차  (0) 2020.06.05
컴퓨터 구조 4주차  (0) 2020.05.28
컴퓨터 구조 3주차(2)  (0) 2020.05.23
컴퓨터 구조 3주차(1)  (0) 2020.05.23
컴퓨터 구조 2주차(2)  (0) 2020.04.16