leehyeon-dv 님의 블로그

2.10 MIPS Addressing for 32-Bit Immediates and Addresses 본문

컴퓨터구조 및 설계/2장. language of the computer

2.10 MIPS Addressing for 32-Bit Immediates and Addresses

leehyeon-dv 2024. 11. 17. 16:10

🔑Table of Contents

  1. 32-bit Constants                        - 32비트 상수, lui사용
  2. Branch Addressing                    - 분기대상 주소계산
  3. Jump Addressing                       - 32비트의 jump주소
  4. Target Addressing Example       - MIPS계산(분기 명령어에서 오프셋사용)
  5. Branching Far Away                   - 이동할 주소가 먼경우 j사용
  6. Addressing Memory Summary   -   
  7. 궁금한점

📌32-bit Constants

  • 대부분의 상수는 작은 크기임
    • 16비트 immediate로도 충분하다
  • 가끔 32-bit 상수가 쓰임 
    • MIPS에서는 16비트상수만 한번에 로드가능해서, 32비트 상수를 다루기위해 상위/하위 16비트를 따로 로드한다
    • lui rt, constant
      • 16비트 상수를  레지스터(rt)의 상위 16비트에 복사한다
      • 하위 16비트는 모두 0으로 채워진다

※MIPS는 lui, ori 명령어를 사용해 32비트 상수를 로드한다

📝예시

lui  $s0, 61

0000 0000 0111 1101 0000 0000 0000 0000

ori $s0, $s0, 2304

0000 0000 0111 1101 0000 1001 0000 0000

 

📌Branch Addressing

  • branch instructions에 사용되는
    • opcode, 2registers, target address
  • 대부분의 branch target(분기대상, 분기 조건에 따라 이동하게 되는 곳)은 branch(지금루틴) 근처에 존재한다
    • 앞 혹은 뒤로

  • PC-relative addressing (pc가 가리키는 주소를 활용)
  • target address = PC + offset*4
  • MIPS에서 PC는 어떤 루틴에 들어가면, 다음에 실행할 명령의 주소값을 가리키게 되어있다 (즉, 이미 이번 분기에 진입할 때 4만큼 증가했었음 그러므로 타겟 주소를 계산할 때 고려해야한다)

📌Jump Addressing

  • 점프(j, jal) 대상은 어디든 가능하다 (branch 타겟과 달리 멀리로도 가는편)
  • MIPS에서 j와 jal은 j-type 명령어로 다음과 같은 구조를 가집니

 

  • (Pseudo) Direct Jump Addressing 
    • PC-relative branching과 다르게 절대 주소를 사용하는 방식
    • (Pseudo) Direct Jump Addressing = 유사 직접 주소 지정 방식(완전 절대주소를 사용하는 것은 아니지만 PC의 상위 4비트와 명령어의 주소 26비트를 결합해 절대주소처럼 동작해 이렇게 부른다)   
    • MIPS명령어가 4바이트 단위로 정렬되기 때문에 26비트를 2비트 shift(x4)해서 PC의 상위 4비트와 28비트 주소를 결합해 32비트의 절대주소를 만듭니다                         

📌Target Addressing Example

  •  2.7장의 Compiling Loop Statememts를 다시 생각해보자 (Loop의 메모리 주소는 80000이라고 가정한다)
  • C code :
while (save[i] == k) i += 1;

//i,k,save -> $s3, $s5, $s6
  • 컴파일된 MIPS code: 
Loop : sll  $t1, $s3, 2          #i 인텍스만큰의 주소(4 byte)를 위해 4곱하기 
    add  $t1, $t1, $s6        #offset(위에서 구해둔 i*4)에 시작 주소를 더하면 save[i]주소
    lw   $t0, 0($t1)
    bne  $t0, $s5, Exit
    addi $s3, $s3, 1
    j    Loop
Exit: ...

 

🔦자세한 계산과정 아래참조

80000 0 19 9 4 0
80004 0 9 22 9 0 32
80008 35 9 8 0
80012 5 8 21 2
80016 8 19 19 1
80020 2 20000
80024  

 

📌 Branching Far Away

분기 대상 주소가 멀어서 16bit의 offset으로도 표현불가능하다면, 어셈블러는 코드를 다시 작성하게된다

예)

beq $s0, $s1, L1이 아닌

👇

   beq  $s0, $s1, L2
   j    L1
L2: ...

*jump addressing 방식은 PC의 상위 4비트를 유지하고 나머지 28비트를 사용해 더 먼 주소로 이동가능하

 

📌Addressing Memory Summary

 

1.  즉시 주소 지정 (상수값 더하거나 빠르게 초기화할때 사용)

 

2. 레지스터 주소 지정방식 (간단한 산술연산, 논리연산)

    - 연산은 레지스터 간에서만 수행, 메모리 접근이없다

 

3. 기준주소 지정방식

    - 기준 주소로 사용하는 레지스터와 오프셋을 더해 메모리 주소를 계산한다

 

4. PC 상대주소 지정방식

    - 현재 pc값을 기준으로 오프셋을 더해 분기할 주소를 계산한다

 

5. 유사 직접주소 지정방식

    - jump 명령어에서 사용되며, 명령어에 포함된 주소 필드를 사용해 분기할 주소를 계산한다

 

 

📍?<궁금한점>📍

🔎lui란?

Load Upper Immediate : 상위 16비트에 즉시값을 로드하고 하위비트에 0으로 채우는 명령

 

🔎lb와 lui의 차이

lb = 메모리에서 8/16비트 데이터를 읽어와서 부호 확장한다 (바이트 데이터를 메모리에서 읽어올때 사용)

lui = 즉시값(immediate Value)을 상위 16비트에 로드하고, 하위 16비트를 0으로 설정한다

 

🔎Pseudo란?

라틴어에서 유래된 단어로, "가짜의" 또는 "유사한"이라는 뜻( 즉, 실제는 아니지만 비슷하게 동작한다는 것)

 

🔎왜 주소에서 데이터를 로드해야할까?($t1으로 바로 사용할수없나)

MIPS 어셈블리에서는 레지서터와 메모리가 분리되어있다 (레지스터는 빠르고 메모리는 느림)

따라서, 데이터 사용 시 메모리에서 바로 연산할 수 없고, 반드시 메모리에서 데이터를 레지스터로 로드한 후에 연산해야한다

MIPS의 설계철학

  1. 연산은 반드시 레지스터에서 만 수행
    •  MIPS 모든 연산 명령어(add, sub, mul등)는 레지스터간의 연산만 가능하다
    • 메모리에 있는 데이터를 직접 연산할 수 없다
  2. 메모리 접근은 lw(load word)와 sw(store word)통해서만 가능
    • 메모리에서 데이터읽기 : lw
    • 메모리에 데이터 저장: sw

사용예시 :

main:
    la $t1, array        # $t1에 배열의 시작 주소 로드
    lw $t2, 0($t1)       # 배열의 첫 번째 요소 (10)를 $t2에 로드
    addi $t2, $t2, 5     # $t2 = $t2 + 5 
    sw $t2, 0($t1)

 

🔎계산 자세히

80000 0 19 9 4 0
80004 0 9 22 9 0 32
80008 35 9 8 0
80012 5 8 21 2
80016 8 19 19 1
80020 2 20000
80024  

 

rs : 첫번째 소스 레지스터. 주로 연산에 사용될 입력값이 들어있음

rt : 두번째 소스 레지스터 or 대상 레지스터. 연산에 사용되거나 값을 저장할 목적지 

rd : 결과를 저장할 레지스터. 연산의 결과값 들어있다

 

target address 계산공식 : PC + 4 + (offset * 4)

  • PC + 4 = 다음명령어의 주소 (현재 명령어 주소 + 4바이트)
  • offset = 몇 개의 명령어를 건너뛸지 나타냄