'하드웨어/AVR·Arduino'에 해당되는 글 1건

AVR을 프로그래밍할 때 주로 C를 사용하지만, 다른 부품들과 시간을 맞추기 위해 어셈블리를 써서 최대한 성능을 뽑아내야 할 때가 있다.

그 과정 중 자주 사용하는 동작인, 레지스터 하나의 값을 0으로 만드는 방법 34개가 정리된 글을 발견했다. 특정 조건/값에서만 되는 경우도 있고, 할 수 있다는 것에 의의를 두고 굳이 이렇게 쓸 필요는 없겠다 싶은 방법도 있어서 이 글에서 34가지 전부는 아니고 중요한/쓸만한 방법 5개만 추려보았다.


우선 시작하기에 앞서 사실 첫번째 방법이 가장 많이 쓰인다. 나머지 방법들은 상태 레지스터 결과가 다르니 경우에 따라서는 유용할 수도 있다.


지우고자 하는 레지스터의 이름은 "reg"로 표현한다.


1. CLR / EOR

clr reg

r0~r31까지 모든 레지스터에 대해 사용할 수 있는 가장 단순하고 쉬운 방법이다. CLR 명령어는 기본적으로 아래의 EOR(배타적 논리합, XOR)과 동일하다.

eor reg, reg

위 두 가지 명령은 실행하면 상태 레지스터를 변화시킨다. S(부호), V(오버플로우), N(음수) 비트는 0으로 설정하고, Z(제로) 비트는 1이 된다. 나머지 H(절반 캐리), C(캐리) 비트는 전에 설정된 대로 유지된다.


2. LDI

ldi reg, 0

처음에 CLR과 LDI의 차이를 찾아보다가 이 글을 쓰는 계기가 되었다. reg에다가 0 값을 넣는 명령인데, LDI는 CLR과 달리 r16~r31까지 상위 16개의 레지스터에만 사용할 수 있다. 그리고 상태 레지스터는 변하지 않는다! 전에 설정된 상태 그대로 유지되므로 분기 명령 전 레지스터 초기화 상황에는 유용할 듯 하다.


3. SUB

sub reg, reg

자기 자신을 빼서 0으로 만드는 방법이다. 이 방법은 r0~r31까지 모든 레지스터에 대해 사용할 수 있다. 1번과 비슷한데, 결과로 설정되는 상태 레지스터가 살짝 다르다.

S, V, N, Z 비트는 1번과 동일하게 설정되는데, EOR에서는 설정되지 않았던 H, C 비트까지도 SUB을 사용하면 0으로 설정된다.


4. MOV

mov reg, r1

x86 어셈블리를 사용해봤다면 mov reg, 0의 형태에 친숙할 것이다. 그러나 AVR에서는 레지스터간 복사는 MOV, 즉시값은 LDI로 분리되어 있다.

이 방법은 MOV 명령을 이용해 값이 0인 레지스터를 복사해오는 것인데, r0~r31까지 모든 레지스터에 대해 사용할 수 있고, LDI와 마찬가지로 상태 레지스터를 변화시키지 않는다.


r1 레지스터를 사용한 점도 눈여겨볼 수 있다. 순수 어셈블리로만 프로그램을 작성했다면 모를까, avr-gcc를 사용해 C 프로그램을 작성하고 인라인 어셈블리를 사용한다면 r1은 항상 0으로 되어있기 때문이다.(참고) C 인라인 어셈블리에서 r0 레지스터는 아무렇게나 사용해도 되며, r1 레지스터는 사용한 후에 반드시 0으로 돌려놓아야 한다.

물론 어셈블리 코드 내에서는 자유롭게 r1을 사용해도 되고, 중간에 인터럽트가 발생해도 r1에 저장된 값을 유지해주므로 코드가 끝날 때 r1을 0으로 돌려둘 것만 기억하면 된다.(인라인 어셈블리 문법으로 r1을 사용한다고 표시하면 알아서 된다.) 단, 이 MOV 명령 사용 전 r1을 0이 아닌 값으로 바꿨다면 이 방법은 쓸 수 없을 것이다.


5. MUL ([F]MUL[S[U]])

mul r0, r1

여기서도 4번과 마찬가지로 값이 0인 r1 레지스터를 사용했다. 이 방법의 기본적인 원리는 레지스터의 값에 0을 곱해서 0으로 만드는 것이다. 그런데 reg 대신 r0으로 사용한 것을 볼 수 있는데, MUL 계열 명령어의 특성상 곱셈 결과가 r1:r0에 저장되기 때문이다. 따라서 r0을 초기화할 때에만(reg=r0) 사용할 수 있다.


그리고 곱셈 명령어는 2 사이클만큼 소요되고, 상태 레지스터의 H, S, V, N 비트는 전 상태 그대로 유지한다. Z, C 비트는 0으로 설정될 것이다.

'하드웨어 > AVR·Arduino' 카테고리의 다른 글

레지스터를 지우는 방법 5가지  (0) 2017.01.23
블로그 이미지

예비컴공돌이

각종 프로젝트 진행중! 생각날때마다 블로그 업데이트합니다.