본문 바로가기

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

SPARC Assembler "Set" Instruction

지금 간단하게 이야기 할 것은 Set이라는 명령어에 관한 이야기이다.
set은 우리가 printf나 scanf등을 사용할때 무언지도 모르고
일단 Label을 %o0에 저장하기 위해 사용하였다.
이제 그 set에 대해 알아보자.

결론부터 이야기 하자면 set은 두가지의 명령어가 축약된 형태이다.
두가지란 [sethi] [or]이다.

먼저 예제를 보자.
[작성환경 : solaris sparc machine  작성툴 : Vi editor   컴파일러 : gcc]



위는 printf함수를 두가지 방법에 의하여 호출해 본 것이다.
물론 결과값은 아래와 같이 모두 정상적으로 printf문이 실행된다.


위 코드를 gdb로 돌려본후 excute문으로 확인해보면 다음과 같다.


GDB상에서 set이나 cmp등 기타 요약된 문장들은 모두 풀어서 나오는 모습을 확인 할 수 있다.

그럼 set이 어떤 기능을 하느냐 하면,
1. 메모리 주소의 번지를 옮겨준다. (라고만 생각한다면 맞기는 하나 기능중 하나이다.)
2. 32bit 를 32bit 대상으로 복사한다. (이것이 정답임~!)

즉 set은 32bit->4byte의 Register의 값을 다른 Register로 복사한다.

이 말에 대해 mov 100, %l0 로 복사가 되지 않느냐고 말할 수 있다.
하지만 이같은 경우 상수 부분이 5000정도의 제한이 오게 된다.
(주소값은 32bit이기 때문에 data영역의 주소를 가져다 사용하기 위해서 set을 사용하는 것이다. 기존 방법으로 한번에 32bit를 바로 다른 레지스터로 복사할 수 없다. ※ 참고로 Label값은 일종의 32bit 상수 값이다.)
그 이유는 mov 명령어 자체는 4byte(32bit)로 되어 있는데 명령어와 레지스터로 쓰고 남은 bit만 상수부분으로 사용할 수 있기 때문이다. 즉 상수 부분(일종의 Label_32bit)을 다른 레지스터로 복사하기 위해서는 전체 32bit를 두번에 걸쳐 나누어 복사하는 수 밖에 없다. (이와 관련해서는 명령어 OpCode 분석을 해보면 확실히 알 수 있다.)

그 두분중 sethi부분이 상위 bit를 복사하는 것이고 다시 or을 통해 하위 bit를 복사하는 것이다.
보통 set을 쓰지만, set다음에 바로 call등 delay slot영향을 끼치는 함수가 온다면, nop을 없애서 효율적으로 프로그램을 작성하기 위해 sethi와 or을 나눠서 프로그램을 작성하는 경우가 있다.

사용법은,
 sethi %hi(fmt1), %o0
 call printf
 or %o0,%lo(fmt1),%o0

위와 같이 %hi와 %lo를 사용하면 된다. 참고로 fmt1은 Label 이름이다.