강좌 & 팁
안녕 하세요!
이번주는 어셈블리어기초의 명령어에 대해서 강좌를 해보겠습니다.
어셈블리 기초
어셈블리어의 기본적인 표기법
어셈블러 코드에서는 명령어 형식이 일반적으로 사용됩니다.
EX) NVIC_IRQ_SEREN0 EQU 0xE000E100 NVIC_IRQ0_ENABLE EQU 0x1 ... LDR R0, =NVIC_IRQ_SETN0 ;LDR은 어셈블러에 의해 PC 상대값으로 변환되는 의사 명령어 입니다. MOV R1, #NVIC_IRQ0_ENABLE ;MOV는 상수 데이터를 레지스터로 이동합니다. STR R1, [R0] ;R0 안에 있는 주소에 R1을 써서 IRQ를 활성화합니다.
어셈블러 표기법은 사용하고 있는 어셈블러 툴에 따라 달라진다는 점을 기억해 두면 됩니다.
ARM 어셈블러 툴 형식이 소개 되어 있으며, 다른 어셈블러 툴의 표기법을 위해서는 그 툴에서 제공되는 예제 코드를 가지고
살펴보는 것이 가장 좋습니다.
어셈블리어 접미사의 사용
ARM 프로세서를 위한 어셈블러에서, 명령어들은 접미사가 뒤에 붙을 수 있습니다.
CORTEX-M3에서 조건부 실행 접미사들은 보통 분기 명령어를 위해 사용됩니다. 하지만 IF_THEN 명령어 구문 안에 사용되는
경우, 다른 명령어들에도 조건부 실행 접미사가 추가되어 사용 될 수 있습니다. 그러한 경우에는 S 접미사와 조건부 실행 접미사들이 동시에 사용될 수 있으며, 총 14개의 조건 선택이 가능합니다.
통합된 어셈블리어
Thumb-2 명령어 세트 중 가장 좋은 것들을 취득하여 지원하기 위해, 통합된 어샘블리어가 개발되었습니다. 이것은 16비트 명령어와 32비트 명령어들을 선택하는 것을 가능하게 해주었으며, 이 두 명령어에 대해 동일한 표기법을 사용하기 때문에 ARM 코드와 Thumb 코드 간에 어플리케이션 포팅이 더 쉬워졌습니다.
전통적인 Thumb 표기법도 여전히 사용될 수 있습니다. 다만 주의해야 할 점은 전동적인 Thumb 명령어 표기법에서 어떤 명령어들은 S 접미사가 사용되지 않더라도 APSR 안에 있는 플레그들을 변경시킨다는 점입니다. 하지만 UAL 표기법이 사용되면 명령어가 플레그를 변경시킬지 아닐지는 S 접미사에 의족적입니다.
아래와 같이 예를 들면
AND R0, R1 ; 전통적인 Thumb 표기법 ANDS R0, R0, R1 ; 동일한 UAL 표기법(S 접미사가 추가됨)
새로운 Thumb-2 명령어가 지원됨에 따라, 어떤 동작들은 Thumb 멸령어나 Thumb-2 명령어 중 하나로 처리될 수 있습니다.
R0 = R0 + 1은 16비트 Thumb 명령어 또는 32비트 Thumb-2 명령어로 구현될 수 있습니다. UAL에서는 접미사를 추가함으로써 원하는 명령어가 어떤 명령어인지를 규정항 수 있습니다.
W접미사는 32비트 명령어를 의미합니다. 만약 접미사가 없다면 어셈블러 툴은 둘 중 어떤 명령어든 선택할 수 있지만, 보통은
코드 크기를 줄이기 위해 16비트 Thumb 코드를 디폴트로 사용합니다.
툴은 지원에 따라, 16비트 Thumb 명령어를 규정하기 위해 N접미사가 사용되기도 합니다. 만약 접미사가 없다면 어셈블러는
최소한의 코드 크기를 갖는 명령어를 선택합니다. 대부분의 경우 어플리케이션들은 C로 코딩되는데, C 컴파일러는 더 작은 코드 크길를 위해 가능하다면 16비트 명령어들을 사용할 것입니다. 하지만 상수값이 어떤 범주를 초과하거나, 32비트 Thumb-2 명령어로 처리하는 것이 더 좋은 연산의 경우에는 32비트 명령어가 사용됩니다.
32비트 Thumb-2 명령어들은 하프워드로 정렬될 수도 있습니다.
Ex) 32비트 명령어가 하프워드에 놓인 경우 0x1000 : LDR r0 [r1] ; 16비트 명령어 (0x1000-0xx1001에 위치) 0x1002 : RBIT.W r0 ; 32비트 Thumb-2 명령어(0x1002-0x1005에 위치)
16비트 명령어의 대부분은 레지스터 R0 에서 R7까지만 접근 가능합니다. 32비트 Thumb-2 명령어는 이러한 제한을 갖지 않습니다.
하지만 어떤 명령어에서는 PC(R15)의 사용이 허용되지 않을 수 있습니다.
Cortex-M3에서의 몇 가지 유용한 명령어 아키텍처 v7과 v6에서의 몇 가지 유용한 Thumb-2 멍령어를 간단히
소개하겠습니다.
- MSR과 MRS
이 두 명령어는 Cortex-M3의 특별한 레지스터로의 접근을 가능하게 해줍니다.
APSR에 접근하는 것이 아니라면, MRS와 MSR 명령어는 특권 모드에서만 사용될 수 있습니다. 그렇지 않은 경우 이 동작은 무시 될 것이고 리턴되어 얽힌 값은 0이 됩니다.
- IF_THEN
IF_THEN(IT) 명령어는 조건부로 실행되는 4개의 연속적인 명령어 입니다.
- CBZ와 CBNZ
CBZ와 CBNZ 명령어들은 루프를 위해 유용합니다.(플래그들은 이 명령어에 의해 영향을 받지 않는다.)
- SDIV와 UDIV
부호화 및 비부호화 나눗셈 명령어를 위한 표기법 입니다.
0으로 나눌 때 결함 익셉션이 발생하도록 하기 위해서는 NVIC 설정 제어 레지스터 안에 있는 DIVBYZERO 비트를 1로 설정할 수 있습니다. 그렇게 하지 않으면 0으로 나누기를 하면 <Rd>는 0이 됩니다.
- REV, REVH, REVSH
REV는 데이터 워드 안에 바이트 순서를 바꿉니다. REVH는 하프워드 안에서 바이트 순서를 바꿉니다.
- RBIT
RBIT 명령어는 데이터 워드 안에서 비트 순서를 바꿉니다.
- SXTB,SXTH,UXTB,UXTH
네 개의 명령어는 한 바이트 또는 하프워드 데이터를 워드 데이터로 확장하기 위해 사용 됩니다.
- BFC와 BFI
BFC는 레지스터의 어떤 위치에 대응되는 비트 수만큼을 0으로 클리어 합니다.
- UBFX,SBFX
두 명령어는 비부토 및 부호 비트 영역 추출 명령어 입니다.
- LDRD,STRD
두 개의 명령어는 두 레지스터에 두 워드의 데이터를 전송합니다.
- TBB와 TBH
TBB(테이블 분기 바이트)와 TBH(테이블 분기 하프워드)는 분기 테이블을 구현하기 위해 만들어졌습니다.
TBB 명령어는 바이트 크기 오프셋의 분기 테이블을 사용하며, TBH는 하프워드 오프셋의 분기 테이블을 사용합니다.
명령어는 너무 많아 설명 드리기는 어려워 관련 블로그를 통해서 명령어 설명과 예제를 통해서 참고 하시길 바랍니다.
http://blog.naver.com/minareu?Redirect=Log&logNo=100117296550
http://mindwave.tistory.com/32
(출처 Posted by 윤석훈, 미나류 블로그 입니다) 감사합니다.
그럼 오늘의 강의는 여기서 마치겠습니다.
끝까지 읽어주셔서 감사드리고 부족한 부분은 댓글로 통해 말씀해주세요.^^