왜 어셈블러 인가?

난 요즘들어 위 물음에 대한 답변을 조금씩 알게 되었다. C 도 잘 모르는 데, 어셈블러는 또 어떤 것인지…-_-
어셈블러를 사용하는 이유는 바로 속도라고 해도 과언이 아니다. 임베디드 개발에서 요즘에는 하이레벨 언어인 C 를 주로 사용하지만, 아직도 로우레벨 언어인 어셈블러는 사용되어지고 있다.
아마도 가장 많이 사용되어지는 곳이 바로 부트로더 일 것이다. 완전한 C 라이브러리가 메모리에 올라가지 않은 상태에서 어떤 명령을 수행하기에는 초기 부팅과정에서는 무리가 있다.
여기서는 내가 책을 보면서, 새로이 알게된 어셈블러 중에 몇몇개 만 간단히 짚고 넘어가기로 하겠다.

자주 쓰이는 명령어

MOVE R3, R2

레지스터 R2 에서 데이터를 읽어서 R3 로 값을 복사한다.

MOVE R5, (iTemperature)

메모리로 부터 iTemperature 의 값을 읽어 레지스터 R5 에 값을 저장한다.

MOVE R5, iTemperature

iTemperature 의 값이 아닌 어드레스 자체를 레지스터 R5 에 저장시킨다는 것을 주의해야 한다.

ADD R7, R3

레지스터 R3 의 값을 레지스터 R7 의 값에 더한다.

NOT R4

레지스터 R4 의 모든 비트를 반전시킨다.

일단, 아래의 코드를 보자!!

          ADD R1, R2
          JUMP NO_ADD
MORE_ADDITION:
          ADD R1, R3
          ADD R1, R4
NO_ADD:
          MOVE (xyz), R1

레지스터 R2 의 값을 레지스터 R1 에 더하고 나서, 레지스터 R3 와 R4 의 값을 더하지 않고, 레지스터 R1 의 값을 변수 xyz 에 저장하는 명령어로 분기해서 실행하게 된다. 또한 어셈블러는 특정한 조건이 참일 때만 점프하는 조건 분기 명령어도 가지고 있다. 아래의 코드를 보자!!

SUBTRACT R1, R5
JCOND ZERO, NO_MORE
MOVE R3, (xyz)
.
.
.
NO_MORE:
.
.
.

만약 레지스터 R1 과 레지스터 R5 가 같은 값을 가지고 있다면, 두 레지스터의 뺄셈의 결과는 0 이 될 것이고, 프로그램은 NO_MORE 라는 라벨로 분기하게 된다. 만약 두 레지스터의 값이 서로 다르다면, 뺄셈의 결과가 0 이 아닐 것이고, 프로세서는 변수 xyz 의 값을 레지스터 R3 에 옮길 것이다.
대부분의 어셈블러는 PUSH 와 POP 라는 명령어를 이용해서 스택에 접근한다. PUSH 명령어는 스택 포인터를 변경시키고, 데이터를 스택에 추가시킨다. POP 명령어는 데이터를 읽고 스택 포인터를 다시 되돌린다.

대부분의 어셈블러는 서브루틴이나, 함수로 분기해 실행하는 CALL 명령어를 가지고 있고, 다시 돌아오기 위해서 RETURN 명령어를 사용한다. 아래의 코드를 보자!!

     CALL ADD_EM_UP
     MOVE (xyz), R1
.
.
.
ADD_EM_UP:
     ADD R1, R3
     ADD R1, R4
     ADD R1, R5
     RETURN

일반적으로 마이크로프로세서는 CALL 명령어 다음에 수행할 명령어의 주소를 스택에 저장한다. 위의 예제의 경우는 MOVE 명령어의 주소를 스택에 저장한다. 마이크로 프로세서는 RETURN 명령어를 만나게 되면, 자동적으로 다음에 실행할 명령의 주소를 스택에서 가져온다.

  • computer/embedded/어셈블러_기초.txt
  • Last modified: 4 years ago
  • by likewind