지난 글에서는 분기 최적화에 대해 정리하였다.
분기 최적화를 하는 방법에는 from before, from after, annulled branch 3가지가 있었다.
from before 은 분기 명령어 이전에 실행되는 명령어를 가져오는 것으로, 보통 mov 명령어를 이용한 레지스터 값 세팅을 가져올 수 있다.
from after 은 분기 명령어 이후에 실행되는 명령어를 가져오는 것으로, 보통 분기 이후 실행되는 명령어 중, 분기 여부에 상관없이 반드시 실행되는 명령어를 당겨올 수 있었다.
annulled branch 는 분기를 할 때는 delay slot 명령어를 실행하고, 분기를 하지 않을 때는 delay slot 명령어를 실행하지 않는 분기 명령어로서, 반드시 분기 후 첫 명령어를 delay slot에 넣을 수 있는 효과가 있었다.
이번 글에서는 지금까지 정리한 분기 명령어를 활용하여 switch - case 구문을 구현해본다.
구현할 코드는 다음과 같다고 해보자.
int main() {
int a = 10;
siwtch (a) {
case 10:
a += 1;
break;
case 20:
a -= 1;
break;
case 30:
a *= 2;
break;
case 40:
a /= 2;
break;
case 50:
a %= 2;
break;
default:
a += 100;
break;
}
// a 의 값에 따라 분기가 잘 되는지 확인해보자.
return 0;
}
첫번째로 switch - case 를 구현하는 방법은, if else 를 여러번 작성하는 방법으로 구현할 수 있다.
다음과 같이 if, else 를 범벅으로 짜면 위와 같이 나온다.
한번 실행시켜보자.
모든 cmp 구문에서 어셈블 에러가 났다..
cmp 구문에서는 cmp register, register/constant 로 작성해야 한다.
상수, 상수 비교는 안된다.
5개의 cmp 구문을 위와 같은 방식으로 모두 바꿔주었다.
A = 10 으로 설정했을 때 11이 나온다.
A = 20 으로 설정했을 때 20 - 1 이 실행되어 19가 나온다.
A = 30 으로 설정했을 때 30 * 2 가 실행되어 60이 나온다.
A = 40 으로 설정했을 때 40 / 2 가 실행되어 20이 나온다.
A = 50 으로 설정했을 때 50 % 2 = 0 이므로 0 이 나온다.
A = 60 으로 설정했을 때 default 부분을 들어가 100이 더해지면서 160이 나온다.
이번엔 switch - case 구문을 좀 더 case 구문 답게 바꿔보자.
case 구문에서 실행될 코드들을 모아둔 case 부분과 조건체크를 하는 부분을 나눠서 분기를 통해 각 case 라벨로 이동시키는 것이다.
아까 else 부분에 있는 코드들을 모아서 condition check 구문을 만들고, 각 조건 체크 후 적절한 곳으로 보내버린다.
이때는 be 명령어를 쓰기 때문에 더 직관적으로 알 수 있다는 장점이 있다.
case work 하는 부분은 아까의 if 부분만 모아둔 것과 같다.
한번 A 값을 바꿔보면서 실행결과를 봐보자.
의도대로 실행이 되는 것을 알 수 있다.
이것으로 Switch - Case 구문을 SPARC 어셈블리로 구현하는 과정을 정리해보았다.
다음 글에서는 메모리에 대한 내용을 정리한다.
'CS > 어셈블리' 카테고리의 다른 글
[SPARC] 22. 정적 메모리와 경계정렬 (0) | 2023.10.20 |
---|---|
[SPARC] 21. 메모리 (0) | 2023.10.19 |
[SPARC] 19. Delay Slot Optimization (0) | 2023.10.17 |
[SPARC] 18. Branch Delay Slot 의 발생 이유 (0) | 2023.10.17 |
[SPARC] 17. 분기 명령어 (0) | 2023.10.15 |