본문 바로가기

무언가 만들기 위한 지식/SPARC Assembler

SPARC Assembler Switch

이번에는 SPARC Assembler에서 Switch문을 사용해보자.
Switch문에서는 특수하게 Switch Table을 사용하게 된다.


위의 C언어상의 switch문을 보자.
C언어에서 switch문은 위와 같은 형식으로 사용된다. 단 switch의 가로안에 들어갈 수 있는 수는 int 형과 char형만 가능하다. 이는 low Level에서 값이 주소연산으로 사용되기 때문이다. (이건 약간의 추측)
(char type은 아스키값으로 연산가능)
위처럼 i라는 구분자에 의하여 특정 루틴으로 가서 처리후 빠져나오게 된다.
이는 어셈블리어에서는 switch table 또는 Address table에 의해 사용된다.
(사실 C나 기타 언어가 이런 어셈블리언어 방식으로 구현되어 있다는 것이 옳다.)

[작성환경 : solaris sparc machine  작성툴 : Vi editor   컴파일러 : gcc]

<코드분석>
13~15 Line
: scanf를 통하여 수를 입력받아 메모리에 저장한다.
17~24 Line : 입력받은 값을 Load하여 만약 1보다 작거나, 10보다 클경우 default 루틴으로 가서 명령 수행후 종료한다. 이 때, cmp를 사용하지 않고, subcc를 사용한점을 유의한다. subcc의 마지막인자가 %g0가 아니라 원래의 %l0이다. 그렇기 때문에 두번째 10이 넘을 경우의 처리는 10이 아닌 9로 해준다. 둘다 cmp로 하고 정석으로 1, 10으로 비교해주어도 지장은 없다.
25~29 Line : Switch Table(address Table)을 이용하여 주소를 얻어와서 jmpl 명령어로 특정 루틴으로 바로 넘어간다. set은 table상의 주소를 사용하기 위해 %o1에 넣어준 것이고, sll은 입력된 값에서 4의 배수 처리를 해준 것이다. 이는 table에 .word로 저장되어 있는  L1, L2, L3....에 접근하기 위해서이다. 하나의 주소가 4byte이기 때문에 sll을 이용하여 계산하였다. %o0와 %o1을 이용하여 연산한 값이 %o0에 최종 저장되고, 그 주소로 jmpl을 이용하여 건너뛰게 된다.

코드에서 "table :  .word L1, L2, L3..." 은 Text영역에 있는 코드이나 명령어가 아닌 const 데이터이다. (수정 또는 실행 불가) 그렇기 때문에 혹시 순서에 의해 이부분이 실행되게 되면 컴파일 에러가 발생한다. 그렇기 때문에 이런방식으로 코드내에 data를 넣어줄 경우 절대 실행되지 않도록 프로그래머에 의해서 제어되어야 한다. 위 코드에서 처럼 jmpl이나 branch로 확실히 건너주어야 한다. 물론 switch table이 최 상단 data영역에 존재하여도 지장은 없다.

switch table에 의해 주소가 계산되고, 해당 루틴으로 빠지게 되면 그 위치에서 명령을 실행하고 마지막 종료 부분으로 branch 하게 된다.
위 코드에서는 각 루틴에서 %o1에 출력 값을 저장하고, 마지막에 printf를 하고 종료하게 된다.

switch 문에 중요한 점은 다음과 같다.
만약 switch 값이 1과 10, 30이 있을 경우, 문제가 생긴다.
그 경우 2~9, 11~29가 비워지게 된다. 이 경우 주소를 찾는 연산쪽에서 비워지는 공간에 쓸데 없는 메모리를 잡아먹게 된다. (하나에 4byte씩) 즉 이 경우 8x4+19x4=108byte가 쓰이지 않고 낭비된다.
한마디로 switch 문은 변수가 밀집된 상황에서만 효율적으로 사용된다는 것이다.
(변수라 함은 switch(i) 스위치문에서 i에 해당함)
변수가 너무 광범위하거나 차이가 크면 전혀 효율적이지 않다.


결과 값은 다음과 같다.


<위와같이 실행후 숫자를 입력하면 해당루틴으로 가서 그 값을 출력, 1~10사이가 아니면 모두 Default 루틴으로 감>