검색
회원가입로그인
AI와 함께 공부하기 : 컴퓨터 구조

MIPS 명령어 형식과 주소 지정 방식 완벽 이해: R, I, J-Type 구조와 예제

MIPS 아키텍처는 RISC(Reduced Instruction Set Computer) 원칙을 충실히 따르며, 이는 명령어 형식과 주소 지정(Addressing) 기법에서도 명확히 드러납니다. 모든 명령어가 고정된 32비트 길이를 가지며, 명령어 형식을 세 가지(R, I, J)로 단순화하고, 주소 지정 모드를 효율적으로 설계하여 파이프라인 처리를 용이하게 합니다.


1. MIPS 명령어 형식 (Instruction Formats)

MIPS는 모든 명령어가 32비트 고정 길이를 가지며, 이는 명령어 인출(Fetch) 단계의 단순성과 일관성에 기여합니다. 명령어의 종류에 따라 크게 세 가지 형식으로 나뉩니다.

1.1. R-Type (Register-Type) Format

레지스터 간의 연산을 수행하는 명령어에 사용됩니다.

  • 용도: 산술 및 논리 연산 (add, sub, and, or, sll 등), 점프 레지스터 (jr), 서브루틴 점프 레지스터 (jalr) 등.

  • 필드 구성 (32비트):

    • op (opcode): 6비트 (비트 31-26). R-type 명령어는 항상 000000 (binary) 입니다.

    • rs (source register 1): 5비트 (비트 25-21). 첫 번째 소스 레지스터 주소.

    • rt (source register 2): 5비트 (비트 20-16). 두 번째 소스 레지스터 주소. (또는 시프트 명령어의 경우 목적지 레지스터)

    • rd (destination register): 5비트 (비트 15-11). 연산 결과가 저장될 목적지 레지스터 주소.

    • shamt (shift amount): 5비트 (비트 10-6). 시프트 명령어에서 시프트할 비트 수 지정. (그 외에는 0)

    • funct (function code): 6비트 (비트 5-0). op 필드가 000000일 때, 이 필드가 실제 연산을 구별합니다.

+--------+-------+-------+-------+-------+--------+
| 6 bits | 5 bits| 5 bits| 5 bits| 5 bits| 6 bits |
|   op   |   rs  |   rt  |   rd  |  shamt|  funct |
+--------+-------+-------+-------+-------+--------+
  • 예시: add $t0, $s1, $s2 ($t0 = $s1 + $s2)

    • op: 000000

    • rs: $s1 레지스터 번호 (17)

    • rt: $s2 레지스터 번호 (18)

    • rd: $t0 레지스터 번호 (8)

    • shamt: 00000

    • funct: 100000 (add 연산)

1.2. I-Type (Immediate-Type) Format

레지스터와 즉시값(constant) 간의 연산, 메모리 로드/스토어, 조건부 분기 명령어에 사용됩니다.

  • 용도: addi (add immediate), lw (load word), sw (store word), beq (branch if equal), bne (branch if not equal), andi (and immediate) 등.

  • 필드 구성 (32비트):

    • op (opcode): 6비트 (비트 31-26). 명령어를 식별하는 주요 코드. R-type과 달리 0이 아닌 고유한 값을 가집니다.

    • rs (source register): 5비트 (비트 25-21). 첫 번째 소스 레지스터 또는 베이스 레지스터 주소.

    • rt (target register): 5비트 (비트 20-16). 두 번째 소스 레지스터, 목적지 레지스터 (로드 명령어의 경우), 또는 스토어할 데이터 소스 레지스터 (스토어 명령어의 경우).

    • immediate: 16비트 (비트 15-0). 부호 확장(Signed Extension)될 즉시값 또는 오프셋(Offset) 주소.

+--------+-------+-------+----------------+
| 6 bits | 5 bits| 5 bits|    16 bits     |
|   op   |   rs  |   rt  |   immediate    |
+--------+-------+-------+----------------+
  • 즉시값의 범위: 16비트이므로 −(215)부터 (215−1)까지의 값을 가집니다 (−32768에서 32767). 부호 확장되어 32비트 값으로 사용됩니다.

  • 주의사항: andi, ori, xori와 같은 논리 즉시값 연산은 16비트 immediate 값을 부호 확장하지 않고 **제로 확장(Zero Extension)**하여 32비트 값으로 사용합니다. 이는 논리 연산의 특성상 음수 개념이 없기 때문입니다.

  • 예시: lw $t0, 100($s1) ($t0 = Memory[$s1 + 100])

    • op: 100011 (lw)

    • rs: $s1 레지스터 번호 (17) (베이스 주소 레지스터)

    • rt: $t0 레지스터 번호 (8) (로드된 값이 저장될 레지스터)

    • immediate: 100 (offset)

1.3. J-Type (Jump-Type) Format

무조건 점프 명령어에 사용됩니다.

  • 용도: j (jump), jal (jump and link).

  • 필드 구성 (32비트):

    • op (opcode): 6비트 (비트 31-26). j000010, jal000011.

    • target address: 26비트 (비트 25-0). 점프할 목적지 주소의 하위 26비트.

+--------+----------------------------+
| 6 bits |           26 bits          |
|   op   |        target address      |
+--------+----------------------------+
  • 주소 계산 방식: MIPS 명령어는 항상 4바이트(32비트) 정렬되므로, 명령어 주소의 최하위 2비트는 항상 00입니다. J-type 명령어의 26비트 target address는 사실 (target address / 4)의 값을 저장합니다. 따라서 실제 32비트 점프 주소는 다음과 같이 구성됩니다:

    • 현재 PC의 상위 4비트 (PC[31:28])

    • 26비트 target address (target[25:0])

    • 00 (binary, 상수)

    • 결과: PC[31:28] || target[25:0] || 00 (32비트)

  • 도달 가능한 주소: 이 방식은 256MB 범위 내의 주소로만 점프할 수 있게 합니다 (226×4=228 바이트). 더 넓은 범위로 점프하려면 jr (jump register) 명령어를 사용해야 합니다.

  • 예시: j Label

    • op: 000010 (j)

    • target address: Label의 28비트 주소 / 4 의 26비트 값.


2. MIPS 주소 지정 기법 (Addressing Modes)

주소 지정 기법은 CPU가 명령어의 피연산자(Operand)에 접근하는 방법을 결정합니다. MIPS는 단순하고 효율적인 몇 가지 주소 지정 모드를 지원합니다.

2.1. Register Addressing (레지스터 주소 지정)

  • 개념: 피연산자가 CPU 내부의 레지스터에 직접 저장되어 있는 경우.

  • 사용 명령어: R-type 명령어 대부분 (add, sub, and, or, sll 등).

  • 특징:

    • 가장 빠름: 메모리 접근이 필요 없어 가장 빠른 주소 지정 모드입니다.

    • 명령어 내의 5비트 레지스터 필드(rs, rt, rd, shamt)를 사용하여 32개의 범용 레지스터 중 하나를 직접 지정합니다.

  • 예시: add $t0, $s1, $s2

    • $s1, $s2, $t0 모두 레지스터에 있는 값에 직접 접근합니다.

2.2. Immediate Addressing (즉시 주소 지정)

  • 개념: 피연산자 값이 명령어 자체 내에 상수로 포함되어 있는 경우.

  • 사용 명령어: I-type 명령어 중 즉시값 연산 (addi, andi, ori, slti 등).

  • 특징:

    • 16비트 immediate 필드를 사용하며, 대부분의 경우 **부호 확장(Sign Extension)**되어 32비트 값으로 사용됩니다.

    • 명령어 fetch 시점에 즉시 값을 가져오므로, 메모리 접근이 필요 없습니다.

  • 예시: addi $t0, $s1, 100 ($t0 = $s1 + 100)

    • 100이라는 상수(즉시값)가 명령어 자체에 포함되어 있습니다.

2.3. Base/Displacement (or Register Indirect) Addressing (기본/변위 주소 지정)

  • 개념: 피연산자가 메모리에 있으며, 그 메모리 주소가 베이스 레지스터의 값과 명령어 내의 오프셋(offset)을 더하여 계산되는 경우.

  • 사용 명령어: lw (load word), sw (store word) 등의 메모리 접근 명령어.

  • 특징:

    • I-type 명령어 형식을 사용합니다.

    • rs 필드가 베이스 주소 레지스터를 지정하고, 16비트 immediate 필드가 오프셋을 지정합니다.

    • 오프셋은 16비트 부호 확장되어 32비트 베이스 주소에 더해집니다.

    • Address=Base_Register_Value+SignExt(Offset)

    • 오프셋은 −(215)에서 (215−1) 바이트까지 가능하므로, 베이스 레지스터를 기준으로 ±32KB 범위 내의 메모리에 접근할 수 있습니다.

    • 배열이나 구조체(struct) 요소 접근에 매우 유용합니다. 베이스 레지스터는 배열의 시작 주소를, 오프셋은 특정 요소의 상대 위치를 나타냅니다.

  • 예시: lw $t0, 100($s1)

    • 메모리 주소는 $s1 레지스터의 값에 100(바이트)을 더한 값입니다. 이 주소에서 4바이트(워드)를 읽어 $t0에 저장합니다.

    • MIPS는 바이트 주소 지정을 하지만, 워드 단위 접근 시에는 항상 주소가 4의 배수여야 합니다. (워드 정렬)

2.4. PC-Relative Addressing (PC 상대 주소 지정)

  • 개념: 분기(Branch) 명령어의 목적지 주소가 현재 프로그램 카운터(PC) 값에 명령어 내의 오프셋을 더하여 계산되는 경우.

  • 사용 명령어: 조건부 분기 명령어 (beq, bne).

  • 특징:

    • I-type 명령어 형식을 사용합니다.

    • immediate 필드는 16비트 부호 확장된 오프셋을 지정합니다.

    • 실제 주소 계산: Target_Address=(PC+4)+(SignExt(Offset)×4)

      • PC + 4는 현재 Fetch된 명령어의 다음 명령어 주소를 나타냅니다 (파이프라인을 고려).

      • 오프셋은 워드 단위이므로, 4를 곱하여 바이트 오프셋으로 변환합니다.

    • 장점:

      • 프로그램이 메모리 어디에 로드되든 상관없이(재배치 가능, Relocatable) 작동할 수 있습니다.

      • 16비트 오프셋으로도 ±215 워드, 즉 ±217 바이트(약 ±128KB) 범위 내의 상대적인 점프가 가능하여 대부분의 조건부 분기에 충분합니다.

  • 예시: beq $t0, $t1, Label

    • $t0$t1이 같으면, Label로 분기합니다. Label의 주소는 (현재 PC + 4) + (Label까지의 상대 워드 오프셋 * 4)로 계산됩니다.

2.5. Pseudodirect Addressing (가상 직접 주소 지정)

  • 개념: 무조건 점프(j, jal) 명령어에 사용되는 주소 지정 방식. 명령어 자체 내의 26비트 주소 필드를 사용하여 점프 목적지 주소를 계산합니다.

  • 사용 명령어: J-type 명령어 (j, jal).

  • 특징:

    • J-type 명령어 형식을 사용합니다.

    • target address 필드는 26비트입니다.

    • 실제 32비트 주소 계산:

      • Current_PC[31:28] (현재 PC의 상위 4비트)

      • Target_Address_Field[25:0] (J-type 명령어의 26비트 주소 필드)

      • 00 (상수 2비트, 워드 정렬)

      • 결과: PC[31:28] || Target_Address_Field[25:0] || 00

    • 이 방식은 현재 PC가 위치한 256MB 블록(2^28 바이트) 내에서만 점프할 수 있습니다.

    • 이름이 "Pseudodirect"인 이유는 완전히 직접 주소 지정이 아니기 때문입니다. PC의 상위 비트를 재사용하여 32비트 주소를 구성합니다.

  • 예시: j LoopLabel

    • LoopLabel의 주소는 현재 PC의 상위 4비트와 명령어의 26비트 주소 필드, 그리고 하위 00을 조합하여 결정됩니다.

2.6. Jump Register Addressing (점프 레지스터 주소 지정)

  • 개념: 점프할 목적지 주소가 레지스터에 저장되어 있는 경우.

  • 사용 명령어: jr (jump register), jalr (jump and link register).

  • 특징:

    • R-type 명령어 형식을 사용합니다.

    • jr rs 명령어는 $rs 레지스터에 저장된 32비트 값을 다음 명령어의 주소로 사용합니다.

    • 장점:

      • 서브루틴 호출 및 반환: jal로 서브루틴에 점프하고, 서브루틴 끝에서 $ra (return address 레지스터)에 저장된 주소를 jr $ra로 점프하여 호출자로 돌아올 수 있습니다.

      • 함수 포인터 구현, 동적 라이브러리 링크, 케이스/스위치 문 구현 등 예측 불가능한 점프 주소에 유용합니다.

      • Pseudodirect Addressing의 256MB 제한을 넘어서는 어떤 32비트 주소로도 점프할 수 있습니다.

  • 예시: jr $ra

    • $ra 레지스터에 저장된 32비트 주소로 무조건 점프합니다.


공유하기
카카오로 공유하기
페이스북 공유하기
트위터로 공유하기
url 복사하기