[CS] #3. MIPS(2)

<div>elop·2022년 1월 17일
0

-Instructions for making decisions

이번엔 conditional branch instruction(분기문)을 알아보자!
branch instruction은 조건을 보고, 특정 statement로 간다고 생각하면된다. 예를들어, 반복문 안에

if(a==1) {
   break;
}

이라는 조건문이 있다면, a와 1을 비교해서 같을 경우(a - 1==0 이면) 반복문 밖의 line(특정 statement)으로 가게 될것이다. 사용되는 instruction들을 알아보자.

  • beq(branch if equeal)
    -beq r1, r2, L1 에서, r1-r2==0인경우 L1으로 branch

  • bne(branch if not equal)
    -bne r1, r2, L1 에서, r1-r2!=0인 경우 L1으로 branch


아래는 분기문과 함께 자주 쓰이는 대소비교를 위한 instruction이다.

  • slt(set on less than)
    -slt $t0, $s3, $s4 에서, $s3<$s4이면 $t0은 1, 아닐경우 0.
  • slti(set on less than immediate)
    -slt $t0, $s2, 10에서, $s2<10이면 $t0은 1, 아닐경우 0.

※unsigned comparision일 경우 sltu,sltiu를 사용



이제 예제를 보며 복습해보자.

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

을 MIPS로 나타내면,
가 된다. Loop와 Exit은 MIPS에서 반복문을 표현하는 방법이고,
j는 특정 statement로 가는 jump instruction인데, R-format도 I-format도 아닌
J-format이다. 후에 다시 다룰 예정이다.



-MIPS registers, instructions for procedure

여기선 MIPS의 register들을 총정리해보고, 덧붙여 procedure를 왔다갔다 하기위한 instruction을 알아볼것이다. 지금까지 많은 종류의 register들이 나왔는데, 이번 기회에 머릿속에 잘 정리해두자!

  • $zero : ㄹㅇ그냥 0이다!
  • $a0 ~ $a3 : 함수의 파라미터(argument)로 사용되는 register
  • $v0 ~ $v1 : 함수의 return 값(value)로 사용되는 register
  • $t0 ~ $t9 : temporary register. procedure에서 값을 보존(preserve)할 필요가 없는 register.
  • $s0 ~ $s7 : saved register. procedure에서 값을 보존(preserve)해줘야 하는 register
여기서 보존해야 한다는건 뭘까...?
※nested procedure(함수내에서 또 다른 함수가 호출되는 procedure)에서, 함수안의 또 다른 함수에서 $s를 호출할지라도 그 값이 덮여쓰이지 않도록 그 값을 저장하고 복원해야함을 의미한다. 하지만 temporary register은 그럴 필요가 없다.
  • $gp : global pointer. 상수와 같은 static data의 access를 위해 사용된다.
  • $sp : stack pointer. stack의 현재 pointer를 가리키는 register. 아래에서 stack을 설명할때 다시 언급할테니 일단 기억만 해두자!
  • $fp : frame pointer. stack의 맨 첫번째 item을 가리키는 pointer. 이것도 아래에서 설명!
  • $ra : 주로 jr 명령어와 함께 쓰인다. nested procedure에서 또 다른 함수가 호출되고 끝났을때 처음 호출된 함수가 진행되던 부분으로 돌아가야할텐데, 그 위치를 저장하는 register.

↓보기쉽게 정리해 놓은 표!


그리고 procedure이동을 위한 instruction 이다.

  • jal : jump and link. nested procedure에서 현재 위치를 저장(다시 돌아와야 하니까)하고 특정 procedure로 이동한다.
    ex) jal   function2
  • jr : $ra와 함께 쓰이며, 함수를 끝내고 원래의 위치로 돌아갈때 사용한다.



-Stack, Heap

이제 위에서 넘어갔던 $sp, $fp를 알아보자. 이를 위해 stack뿐만 아니라 메모리의 전체적인 구조를 알아볼건데, 너무너무 중요한 부분이니 반!드!시! 잘 이해하자.
먼저 메모리 구조를 4가지로 나눠보자.

  • Stack : 함수 호출시 생성되는 지역, 매개변수들이 저장된다. 컴파일시 그 크기가 결정되며, 위에서 아래로 크기가 커진다.
  • Heap : dynamic data가 저장되는 공간. 흔히 동적할당된 친구들이 여기에 저장된다고 보면된다. Run time에 그 크기가 결정되며, 아래서 위로 크기가 커진다.
  • static : 상수나, 정적 변수들이 저장되는 공간.
  • Text : MIPS machince code의 source file이 저장되는 공간.

우리가 주의 깊게 다뤄볼 것은 stack이다.
saved register나 함수의 argument의 경우 함수내에 또 다른 함수가 호출될 경우 그 값이 덮여 쓰일텐데, 그러면 원래의 값을 어떻게 기억할까? 바로 Stack에 저장해두고 그 함수가 종료되면 다시 값을 복원하는 것이다!


$fp : stack의 첫번째 item위치를 가리키는 pointer
$sp : stack의 현재 item위치를 가리키는 pointer

그림과 같이 stack은 값이 추가될 때 high address에서 low address로, 즉 위에서 아래로 그 크기가 자란다. 이번에도 역시 예시를 보도록하자!
위 MIPS 코드는 Function1안에 Function2가 있는 nested procedure이다.
F1이 끝난뒤의 return address와 argument register를 기억해주기 위해 stack pointer를 -8만큼(alignment restriction) 옮겨 2개의 공간을 만들고, sw 명령어로 $a0과 $ra를 저장한 것을 볼 수있다. 그리고 F2 이 끝난뒤 lw를 통해 그 값들을 다시 가져온것을 확인할 수 있다.

profile
기록장

0개의 댓글