[컴퓨터구조] 2. Instructions: Language of the Computer(2) - MIPS 기본 연산 및 피연산자

2025. 7. 10. 01:30·Computer Science/컴퓨터구조

 

2. Instructions: Language of the Computer(2) - MIPS 기본 연산 및 피연산자

#Computer_Architecture


Operations
MIPS ISA에서는 연산을 어떻게 처리하는지 알아보자. 우리가 코드로 작성하는 연산들이 어떻게 명령어로 바뀌는지 이해해야, 하드웨어에서 동작하는 것을 이해할 수 있다.


산술 연산(Arithmetic Operations)

  • 덧셈과 뺄셈은 3개의 피연산자를 사용합니다.
    • 두 개의 source와 하나의 destination 피연산자를 사용합니다.
    • 주의) dest 피연산자가 가장 먼저 온다.
    add a, b, c  # a(dest)는 b(source) + c(source)
    
    
  • 모든 산술 연산은 이러한 형태를 가집니다.
  • 설계 원칙 1: 간단하게 하기 위해서는 규칙적인 것이 좋다.
    • 규칙성은 구현을 단순화합니다.
    • 단순함은 더 낮은 비용으로 더 높은 성능을 가능하게 합니다.

예시: Arithmetic

  • C 코드:
    f = (g + h) - (i + j);
    
  • MIPS 코드:
    add t0, g, h    // t0 = g + h
    add t1, i, j    // t1 = i + j
    sub f, t0, t1   // f = t0 - t1
    
    • 여기서 t0, t1은 임시 변수에 해당한다. temporary라서 t를 쓰는듯

레지스터 피연산자(Register Operands)

  • 산술 명령어는 레지스터 피연산자를 사용합니다.
    • 산술 연산에서 레지스터에 올라와있는 값만 사용할 수 있다는 말인듯
  • MIPS는 32 × 32비트 레지스터 파일을 가지고 있습니다.
    • 32비트 짜리 레지스터가 32개 있다고 생각하면 됨.
    • 자주 접근하는 데이터는 레지스터에 저장합니다
    • 레지스터는 0부터 31까지 번호가 매겨져 있습니다.
      • 5bit로 32개의 위치를 표현할 수 있음
      • cf) 메모리의 각 칸은 바이트 단위로 조회할 수 있음
        • ex) 0x12 34 56 78(리틀 엔디안 or 빅 엔디안)
  • 32비트 데이터는 "워드"라고 합니다. (한 번에 옮길 수 있는 크기)
    • 4바이트
    • 앞으로 크기에 대해서 별 말이 없으면 32비트(워드)라고 생각하면 된다.
  • 어셈블리어 명칭:
    • $t0, $t1, ... $t9: 임시 값 저장(temporary values)
    • $s0, $s1, ... $s7: 저장된 변수(saved variables)
    • 레지스터 앞에는 $를 붙여주는 네이밍 규칙이 있다
  • 설계 원칙 2: 더 작은 것이 더 빠릅니다.
    • 주 메모리와 비교하면 수백만 개의 위치를 가집니다.(레지스터는 32개)

예시: 레지스터 피연산자

  • C 코드:
    f = (g + h) - (i + j);
    
    • f, g, h, i, j는 $s0, $s1, $s2, $s3, $s4에 저장됩니다.
      • 연산을 하기 위해 saved register에 값을 저정하는 것
  • MIPS 코드:
    add $t0, $s1, $s2   // t0 = g + h
    add $t1, $s3, $s4   // t1 = i + j
    sub $s0, $t0, $t1   // f = t0 - t1
    
    • 최종 연산 결과는 temporary register가 아니라 saved register에 저장된다

메모리 피연산자

위와 같이 연산을 하기 위해서 메모리에서 레지스터로 값을 가져오는 과정이 필요한데, 이 과정을 살펴보자.

  • 복합 데이터(composite data)는 메인 메모리에 저장됩니다.
    • 배열, 구조체, 동적 데이터 등
  • 산술 연산을 적용하려면 메모리에서 레지스터로 값을 불러와야 합니다.
    • 또한 연산 결과를 메모리로 저장하려면 레지스터에서 메모리로 값을 저장해야 합니다.
  • 메모리는 바이트 단위로 주소 지정됩니다.
    • 각 주소는 8비트 바이트를 식별합니다.
      • 0x 12 34 56 78 —> 8비트(바이트) 4개
      • 1바이트 공간 4개를 차지하고 있어서 1바이트(8비트) 단위로 식별한다고 보면 된다.
  • 워드는 메모리에 정렬되어 있어야 합니다.
    • 주소는 4의 배수여야 합니다.
      • 워드는 4바이트니까 워드 하나 하나 접근하려면 주소가 4의 배수여야 하겠죠?
  • MIPS는 빅 엔디안 방식입니다.
    • 워드의 가장 큰 바이트가 가장 작은 주소에 저장됩니다.
      • 0x12345678이면 12부터 저장
    • 리틀 엔디안 방식과 비교하면 반대입니다.
      • 리틀 엔디안 : 0x12345678에서 78부터 저장
      • x86이 리틀 엔디안 방식이었던걸로 기억.

메모리 피연산자 예시 1
C 코드:

g = h + A[8];
  • g는 $s1, h는 $s2, 배열 A의 기본 주소는 $s3에 저장됩니다.
  • 배열에 있는 특정 원소를 가져올 때 바로 값을 가져오는게 아니라, 배열의 주소를 먼저 saved register에 저장한다는 것에 유의하자.

MIPS 코드:

lw $t0, 32($s3)   // 배열 A[8]의 값을 로드
add $s1, $s2, $t0 // g = h + A[8]

A[8]의 값이 아니라 A의 주소값을 $s3에 저장했기 때문에, A[8]의 값을 가져와야 한다.


이 때 word 단위로 8번째 원소이므로, A의 주소값 $s3에 오프셋 8 * 4만큼 더해준 값이 A[8]이 된다.
이 주소에서 값을 가져와(lw 명령어) 임시변수 $t0에 저장해준다.


여기서 기억해야할 건, 배열의 원소값을 가져올 때 먼저 배열의 첫 번째 주소를 레지스터에 저장한 다음, 주소의 값을 계산하고, 해당 주소에서 값을 가져오는데, 임시변수에 저장해서 사용한다는 것이다.

  • lw = load word : 메모리에서 로드한다. ( 방향으로 로드)
    • 반대로 sw = store word (메모리에 저장. 방향으로 저장)
  • $s3 레지스터에 들어있는 주솟값에다가 오프셋(32)만큼 더해준 다음 타겟 레지스터에다가 로드해준다.

메모리 피연산자 예시 2
예시 하나를 풀어봤으니, 요거는 스스로 풀어볼 수 있음!
C 코드:

A[12] = h + A[8];
  • h는 $s2, 배열 A의 기본 주소는 $s3에 저장됩니다. (미리 주어짐)

MIPS 코드:

lw $t0, 32($s3)   // 배열 A[8]의 값을 로드
add $t0, $s2, $t0 // h + A[8]
sw $t0, 48($s3)   // A[12]에 저장

주의! 연산결과를 saved register가 아니라, A[8]값을 저장해놨던 temporary register에 저장한다.


레지스터 vs 메모리

  • 레지스터는 메모리보다 액세스 속도가 빠릅니다. (CPU랑 가까우니까)
  • 메모리 데이터를 사용하려면 로드와 저장 명령어가 필요합니다. (lw, sw)
    • 더 많은 명령어가 실행되어야 합니다.
  • 컴파일러는 가능한 한 변수들을 레지스터에 저장해야 합니다.
    • 덜 자주 사용되는 변수만 메모리로 넘깁니다.
    • 자주쓰는 것들만 레지스터에 오랫동안 가지고 있어야 하고, 잘 안쓰는 것들은 메모리로 넘겨서 비워줘야 한다.
    • 레지스터 최적화가 중요합니다.

Immediate Operands(즉시 피연산자라고 번역되긴 하는데, 상수인듯)

Arithmetic Operands에서는 모든 값을 레지스터에 올리고 연산을 수행했어야 했다. 메모리에 있는 값은 무조건 레지스터에 올려야겠지만, 상수 값을 더하거나 빼는 경우 레지스터에 옮기는데 시간이 소요된다. Immediate Operands를 사용하면 메모리에 접근할 필요가 없다.


명령어 내에서 상수 데이터를 직접 지정할 수 있습니다.

addi $s3, $s3, 4  // $s3에 4를 더함
  • i += 4
  • 앞에서 봤던 add를 안쓰고 왜 Immediate Operands를 사용할까?
    • i+= 4;를 한다고 해보자. 4라는 값을 레지스터에 옮긴 뒤에 연산을 해야 하므로, 성능이 떨어진다 Immediate Operands를 사용하자

주의 | subi 연산자는 없다. 대신 음수를 더한다.


  • 즉시 피연산자를 사용하면 로드 명령어가 필요 없습니다.
  • 설계 원칙 3: 흔한 경우를 빠르게 처리하라.
    • 작은 상수는 자주 사용됩니다.
    • load instruction을 피하기 때문에 오버헤드를 줄일 수 있다.

참고 | Immediate Operands에서는 상수값의 Sign Extension이 같이 발생한다.

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

[컴퓨터구조] 2. Instructions: Language of the Computer(5) - 논리 및 제어 흐름 명령어  (0) 2025.07.10
[컴퓨터구조] 2. Instructions: Language of the Computer(4) - MIPS 명령어 형식 (Instruction Formats)  (0) 2025.07.10
[컴퓨터구조] 2. Instructions: Language of the Computer(3) - 컴퓨터 내부의 데이터 표현  (0) 2025.07.10
[컴퓨터구조] 2. Instructions: Language of the Computer(1) - ISA와 MIPS 아키텍처 소개  (0) 2025.07.10
[컴퓨터 구조] 01. Computer Abstractions and Technology  (0) 2024.10.07
'Computer Science/컴퓨터구조' 카테고리의 다른 글
  • [컴퓨터구조] 2. Instructions: Language of the Computer(4) - MIPS 명령어 형식 (Instruction Formats)
  • [컴퓨터구조] 2. Instructions: Language of the Computer(3) - 컴퓨터 내부의 데이터 표현
  • [컴퓨터구조] 2. Instructions: Language of the Computer(1) - ISA와 MIPS 아키텍처 소개
  • [컴퓨터 구조] 01. Computer Abstractions and Technology
lumana
lumana
배움을 나누는 공간 https://github.com/bebeis
  • lumana
    Brute force Study
    lumana
  • 전체
    오늘
    어제
    • 분류 전체보기 (462)
      • 개발 일지 (0)
        • Performance (0)
        • TroubleShooting (0)
        • Refactoring (0)
        • Code Style, Convetion (0)
        • Architecture (0)
      • Software Engineering (36)
        • Test (8)
        • 이론 (18)
        • Clean Code (10)
      • Java (72)
        • Basic (5)
        • Core (21)
        • Collection (7)
        • 멀티스레드&동시성 (13)
        • IO, Network (8)
        • Reflection, Annotation (3)
        • Modern Java(8~) (13)
        • JVM (2)
      • Spring (53)
        • Framework (12)
        • MVC (23)
        • Transaction (3)
        • AOP (11)
        • Boot (0)
        • AI (0)
      • DB Access (16)
        • Jdbc (1)
        • JdbcTemplate (0)
        • JPA (14)
        • Spring Data JPA (0)
        • QueryDSL (0)
      • Computer Science (130)
        • Data Structure (27)
        • OS (14)
        • Database (10)
        • Network (21)
        • 컴퓨터구조 (6)
        • 시스템 프로그래밍 (23)
        • Algorithm (29)
      • HTTP (8)
      • Infra (1)
        • Docker (1)
      • 프로그래밍언어론 (15)
      • Programming Language(Sub) (76)
        • Kotlin (0)
        • Python (25)
        • C++ (51)
        • JavaScript (0)
      • FE (11)
        • HTML (1)
        • CSS (9)
        • React (0)
        • Application (1)
      • Unix_Linux (0)
        • Common (0)
      • PS (13)
        • BOJ (7)
        • Tip (3)
        • 프로그래머스 (0)
        • CodeForce (0)
      • Book Review (4)
      • Math (3)
        • Linear Algebra (3)
      • AI (7)
        • DL (0)
        • ML (0)
        • DA (0)
        • Concepts (7)
      • 프리코스 (4)
      • Project Review (6)
      • LegacyPosts (11)
      • 모니터 (0)
      • Diary (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
lumana
[컴퓨터구조] 2. Instructions: Language of the Computer(2) - MIPS 기본 연산 및 피연산자
상단으로

티스토리툴바