이 글은 필자가 수업시간에 들은 내용과 강의록을 토대로 정리한 글입니다.
수업 필기이다 보니, 오류가 있거나 설명이 부족한 부분이 있을 수 있습니다.
궁금하신 점이나 지적하실 점이 있다면 댓글로 달아주세요! 확인 후 내용을 추가하거나 답변해드리도록 하겠습니다 :)
sll
sll
하면, 만큼 곱하는 것과 같다.sll $t2, $s0, 4
와 같이 사용한다.srl
srl
하면, 만큼 나누는 것과 같다.srl $t2, $s0, 4
와 같이 사용한다.and $t0, $t1, $t2
or $t0, $t1, $t2
nor $t0, $t1, $zero # not $t1
(# 은 주석이다)
현대의 컴퓨터들은 기본적으로 프로그램 내장형 컴퓨터이다. 프로그램 내장형 컴퓨터가 나타나기 전 까지는, 모든 컴퓨터들은 논리 회로들을 이용해서 직접 특정 문제를 해결하는 컴퓨터를 만들어야 했고, 다른 문제를 해결하기 위해서는 하드웨어(논리 회로) 자체를 다르게 연결했어야 했다. 그러나 현대 컴퓨터들은 프로그램이 내장되어 있는 컴퓨터이기 때문에, 프로그램(소프트웨어)만 다시 작성하면 프로세서(하드웨어)가 그를 순차적으로 실행하기 때문에, 하드웨어를 다시 설계할 필요가 없어졌다.
beq rs, rt, L1
rs == rt
이면, L1
이라고 라벨된 명령으로 분기한다.bne rs, rt, L1
rs != rt
이면, L1
이라고 라벨된 명령으로 분기한다.j L1
L1
이라고 라벨된 명령으로 점프(jump)한다.if (i == j)
f = g + h;
else
f = g - h;
f, g, h, i, j는 $s0
, $s1
, $s2
, $s3
, $s4
에 저장된다.
컴파일된 MIPS 코드
bne $s3, $s4, Else
add $s0, $s1, $s2
j Exit
Else : sub $s0, $s1, $s2
Exit : ...
while (save[i] == k)
i += 1;
i는 $s3
, k는 $s5
, save(배열 포인터)는 $s6
에 저장된다.
컴파일된 MIPS 코드
Loop : sll $t1, $s3, 2 # i << 2 , $t1 = i * 4
add $t1, $t1, $s6 # $t1 = save + i * 4 = &save[i]
lw $t0, 0($t1) # $t0 = *(&save[i]) = save[i]
bne $t0, $s5, Exit
addi $s3, $s3, 1 # i = i + 1;
j Loop
Exit : ...
위의 코드를 간단하게 설명해보면,
1. sll
을 이용하여 $t1
에 배열의 인덱스(index)를 저장한다. (4를 곱하기 위해 2번 시프트 한다)
2. 그 $t1
에 $s6
을 더하여 $t1
에 save의 i 번째 인덱스(index)의 주소를 저장한다.
3. 그리고 lw
를 이용하여 $t0
에 save[i]
를 불러온다.
4. 그 후, 조건 분기를 통해서 while 문의 조건을 확인하고, j
를 통해 반복문을 구현한다.
값들을 비교하고, 만약 조건이 참이라면 결과는 1이 되게 한다.
slt rd, rs , rt
rs < rt
이면, rd = 1
이고, 아니면 rd = 0
이다.slti rd, rs , constant
rs < constant
이면, rd = 1
이고, 아니면 rd = 0
이다.위의 명령들을 beq
, bne
와 함께 사용한다.
if ($s1 < $s2)
를 구현하려면 다음과 같이 쓰면 된다.slt $t0 $s1, $s2 # if ($s1 < s2), $t0 = 1
bne $t0, $zero, L # then, branch to L
부호가 있는 경우의 비교 : slt
, slti
부호가 없는 경우의 비교 : sltu
, sltui
참고로, 비교에 사용되는 값들의 비트는 어차피 음수나 양수나 같은 비트이다. 따라서 어떤 명령을 사용할 지에 대한 것은 온전히 프로그래머의 선택에 달려있다.
beq
, bne
는 매우 기본적인 경우에 사용되는 명령으로, 자주 쓰인다.프로시저 호출 절차
PC : 프로그램 카운터(Program Counter)
$ra
: 반환 주소(return address)
프로시저 호출 명령
jal ProcedureLabel
$ra
에 저장한다.프로시저 반환(return) 명령
jr $ra
$ra
를 복사한다.예시
다음과 같은 코드가 있다고 하자.
int func(int arg1)
{
...
...
foo(b); // call
...
...
}
int foo(int arg2)
{
...
...
bar(c); // call
...
...
} // return
int bar(int arg3)
{
...
...
...
} // return
그러면, 다음 그림과 같은 과정을 거치게 된다.
위 그림에서 순서는 아래와 같다.
1. foo 호출
2. bar 호출
3. bar 반환
4. foo 반환