본문 바로가기
CS/컴퓨터 구조

[Chapter 2.4 컴퓨터 구조 및 설계] MIPS 조건 명령어와 PC 주소 지정 방식 PC 레지스터

by 베어 그릴스 2022. 7. 8.
본 정리는 CS422-컴퓨터 구조 및 설계  : 하드웨어/소프트웨어 인터페이스. David A. Patterson,존 헤네시 책을 바탕으로 하고 있음을 미리 알립니다.

 

조건 명령어(Conditional Operations)


프로그래밍할 때 if 문 같은 조건문을 사용할 때가 있다.

 

이는 MIPS 명령어로 다음과 같다.

 beq rs, rt, L1 # if (rs == rt) branch to instruction labeled L1;
 bne rs, rt, L1 # if (rs != rt) branch to instruction labeled L1;
j L1 #unconditional jump to instruction labeled L1

beq bne의 두명령어를 조건부 분기(conditional branch)라고 부른다.

 

bne beq등은 I format을 따른다.

I format

J는 새로운 J format을 따른다.

J format

J format에 대한 자세한 설명은 더 뒤에서 다루도록 하자.

 

 

예를 들어 다음과 같은 코드가 있다고 가정해보자.

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

이를 MIPS 어셈블리어로 컴파일하면,

bne $s3, $s4, Else
add $s0, $s1, $s2
j Exit
Else: sub $s0, $s1, $s2
Exit: …

이렇게 될 것이다.

 

if문이 아닌 반복문은 어떨까?

while (save[i] == k) i += 1;

이를 MIPS 어셈블리어로 컴파일하면,

Loop: sll $t1, $s3, 2
add $t1, $t1, $s6
lw $t0, 0($t1)
bne $t0, $s5, Exit
addi $s3, $s3, 1
j Loop
Exit: …

이런 식으로 될 것이다.

 

즉 $s3를 shift left 2 해서 4를 곱한 값을 $t1에 넣는다 이 코드가 의미하는 바는 $s3는 i값을 저장하고 있는데, word address이므로 이에 4를 곱해서 t1에 offset 값을 저장해준 것이다.

 

$t1 레지스터에 미리 배열의 시작 주소값($s6)을 더하고, 그것을 lw 하여 배열의 값을 빼오고 bne을 사용해 만약 같다면 쭉 루프를 돌고 j를 사용해 다시 루프의 시작 주소로 돌아오게끔 해준다.

 

 

 

기본 블록?

 

  • 분기 명령어로 끝나는 명령어 시퀀스
  • 분기명령을 포함하지 않는다(맨 마지막에는 있을 수도 있다)
  • 분기 목적지나 분기 레이블이 없다 (시작 지점에는 있을 수도 있다)

즉 간단하게는 조건 분기가 없는 코드 집합이라고 생각하면 된다. 컴파일의 초기 단계 작업 중 하나는 프로그램을 기본 블록으로 나누는 일이다.

 

 

그렇다면 이제 그래서 다음 라벨 혹은 분기점으로 어떻게 가는 것인지 의아해질 것이다.

 

PC (Program Counter) register

 

PC 레지스터는 명령어의 주소를 담고 있는 레지스터이다.

원래는 한 사이클마다 PC 레지스터에 4를 더해서 다음 명령어를 실행한다.

 

beq 혹은 bne 이 발생하여 상수값 즉, offset 값이 들어오면, PC+4 값에 offset + 4(+4를 해주는 이유는 word address이기 때문이다.)를 sign extend 하여(PC는 32bit 값을 가지고 있는 레지스터이므로) 값을 더해준다.

 

그러면 다음 명령어의 주소는 PC+4가 아니라 PC+4에 offset + 4를 더한 값을 갖게 되므로 조건문이 원하는 명령어를 실행하게 될 것이다.

 

이렇게 명령어 내 상수의 합이 실제 주소가 되는 주소지정을 PC 상대 주소지정이라한다.

조건문에 의해 다음 명령어의 주소가 바뀌는 과정

 

MIPS 주소 지정 방식 요약

  • 수치(immediate) 주소 지정: 피연산자는 명령어 내에 있는 상수이다.
  • 레지스터 주소 지정: 피연산자는 레지스터에 있는 값이다.
  • 베이스 또는 변위 주소지정: 메모리 내용이 피연산자이다. 메모리 주소는 레지스터와 명령어 내의 상수를 더해서 구한다.(lw)
  • PC 상대 주소 지정: PC값과 명령어 내 상수의 합을 더해서 주소를 구한다.
  • 의사 직접 주소지정: 명령어 내의 26비트를 PC의 상위 비트들광 연접하여 점프 주소를 구한다. 

그렇다면 if a < b 같은 코드는 어떻게 구현할까?

 

바로 새로운 명령어인 slt(set less than)를 사용한다.

slt $t0, $s0, $s1 # if $s0 < $s1 then
# $t0 = 1 else 
# $t0 = 0

$s0 가 $s1보다 작으면 $t0에 1을 넣고 그렇지 않다면 0을 넣는 것이다.

이 명령어는 피연산자가 두개이기 때문에 R format을 따른다.

 

slt와 beq,bne를 사용하여 다양한 비교 조건문을 구현해 낼 수 있다.

 

1. less than (보다 작으면)

slt $at, $s1, $s2 #$at set to 1 if s1 < s2
bne $at, $zero, Label #$0이 아니면 위의 조건문이 맞다는 말이므로 s1 < $s2

2. great than or equal to(크거나 같으면) ->bge $s1, $s2, Label 

slt $at, $s1, $s2 #$at set to 0 if s1 < $s2
beq $at, $zero, Label #0과 같으면 위 조건문이 아니라는 말이므로 s1 >= $s2

3.less than or equal to (보다 작거나 같으면) -> ble $s1, $s2, Label

slt $at, $s2, $s1 #$at set to 0 if s2 < $s1
beq $at, $zero, Label #0과 같으면 위 조건문이 아니라는 말이므로 위의 반대가 된다. s2 >= $s1

4. greater than(보다 크면) -> bgt $s1, $s2, Label

slt $at, $s2, $s1 #$at set to 1 if s2 < s1
bne $at, $zero, Label #$0이 아니면 위의 조건문이 맞다는 말이므로 s2 < s1

 

코드를 보면서 조금 생각해보기 바란다.

 

bge,ble,bgt 같은 명령어를 만들지 않고 slt와 bne, beq를 통해서 만들었을까?

 

위 명령어들을 직접 만들면 너무 복잡해서 별도의 클럭 사이클이 발생하여 더 느려지게 된다.

간단한 설계를 지키기 위해 그리고 자주 생기는 일을 더 빠르게 만들기 위해 빠른 명령어 두 개를 대신 사용하는 것이다. 

 

부호가 있는 수를 비교할 때 : slt, slti

부호가 없는 수를 비교할 때 : sltu, sltiu

 

구분해야 하는 이유는 11111111111이 부호가 없을 땐 매우 큰 수이지만, 부호가 있는 수에선 -1인 것처럼 차이가 있기 때문이다.

 

 

J 명령어

 

J Format

beq bne과 마찬가지로 원하는 명령어로 주소를 바꾸고 싶을 때 사용되는 명령어이다.

 

똑같이 PC+4에 26bit의 offset +4 값이 더해져서 다음 명령어의 주소가 바뀌게 된다.

J 명령어로 인해 PC 값이 바뀌는 과정

beq $s0, $s1, L1에서 L1이 16bit로 나타낼 수 없는 수 일 때,

bne $s0, $s1, L2
j L1
L2:

이렇게 사용하여 j 명령어를 활용할 수 있다.

 

요약


PC 레지스터에는 명령어의 주소가 담겨있다.

 

bne, beq, j 명령어는 PC+4 값에 상수 offset +4를 더하여 다음 명령어 주소를 바꾼다.

 

slt와 bne, beq를 활용하여 비교 조건문을 모두 만들 수 있다.