모든 ARM 명령어는 32비트 길이를 갖는다. 명령어들은 32비트 워드로 정렬되므로 명령어 주소의 최하위 2비트는 ARM 상태에서는 항상 0이다. 일부 명령어는 최하위 비트를 Thumb 코드인지 ARM코드 인지 확인한다.
ARM Instruction Set Format
ARM 명령어는 상위 4비트의 condition field를 포함해 아래와 같은 32비트 고정 포맷으로 인코딩된다. 어떤 명령어든 이 condition field 값에 따라 실행 여부가 결정되므로, 대부분의 ARM 명령어는 조건부로 실행될 수 있다.

ARM instruction은 아래와 같이 몇가지 그룹으로 분류된다.
- Branch instructions
- Data processing instructions
- Single register load and store instructions
- Multiple register load and store instructions
- Status register access instructions
- Semaphore instructions
- Coprocessor instructions.
각 그룹은 이 블로그에서 명령어별로 더 자세히 다루고 있으므로, 이 글에서는 그룹별 역할을 간단히 정리하고 상세 글로 연결한다.
Branch instructions
Branch instructions은 다음과 같은 용도로 사용된다.
- 루프(loop)를 생성하기 위한 backward 분기
- 조건 구조에서 forward 분기
- 서브루틴(subroutine)으로 분기
- ARM state 에서 Thumb state로 프로세서 변경
B, BL 명령어의 문법과 예제는 ARM Instruction Set: Branch Instructions (B, BL) 글에서 자세히 다룬다. 예외(exception)를 발생시켜 실행 흐름을 바꾸는 SWI 명령어는 ARM Instruction Set: Software Interrupt (SWI) 글을 참고한다.
Data processing instructions
두 레지스터 내용에 대해 더하기, 빼기 또는 비트 논리와 같은 연산을 수행하고 그 결과를 세번째 레지스터에 배치할 수 있다. 또한 오퍼랜드에 시프트(shift) 연산을 적용하거나, 두 레지스터 값을 비교해 결과 레지스터 없이 condition flag만 갱신하는 것도 가능하다. 대표적으로 ADD, SUB, AND, ORR, MOV, CMP 같은 명령어가 여기 속한다.
세부 문법은 ARM Instruction Set: Data Processing 글에서 다룬다. 두 레지스터를 곱하는 MUL, MLA 명령어는 ARM Instruction Set: Multiply and Multiply-Accumulate (MUL, MLA) 글을 참고한다.
Single register load and store instructions
메모리에서 레지스터로 값을 읽어오는 Load와, 레지스터 값을 메모리에 쓰는 Store 명령어다. Word, halfword, byte 단위로 전송할 수 있고, 부호 확장(sign-extend) 여부도 지정할 수 있다. 대표 명령어는 LDR, STR이다.
주소 지정 방식과 예제는 ARM Instruction Set: Single Data Transfer (LDR, STR) 글에서 다룬다.
Multiple register load and store instructions
한 번의 명령어로 여러 레지스터를 메모리에 저장하거나 메모리에서 불러올 수 있다. 함수 진입/종료 시 여러 레지스터를 스택에 한꺼번에 push/pop 하거나, 메모리 블록을 빠르게 복사할 때 주로 사용한다. 대표 명령어는 LDM, STM이다.
동작 방식과 예제는 ARM Instruction Set: Block Data Transfer (LDM, STM) 글에서 다룬다.
Status register access instructions
CPSR(Current Program Status Register)이나 SPSR(Saved Program Status Register)의 값을 일반 레지스터로 읽어오거나, 반대로 일반 레지스터 값을 CPSR/SPSR에 쓸 때 사용한다. Condition flag를 직접 조작하거나 프로세서 모드를 전환할 때 필요하다. 대표 명령어는 MRS, MSR이다.
세부 문법은 ARM Instruction Set: PSR Transfer (MRS, MSR) 글에서 다룬다.
Semaphore instructions
메모리의 값을 읽어옴과 동시에 새 값을 그 자리에 원자적(atomic)으로 기록하는 명령어다. 값을 읽고 쓰는 사이에 다른 프로세서나 인터럽트가 끼어들 수 없으므로, 멀티프로세서 환경에서 세마포어(semaphore)나 락(lock) 구현에 사용한다. 대표 명령어는 SWP다.
동작 방식과 예제는 ARM Instruction Set: Single Data Swap (SWP) 글에서 다룬다.
Coprocessor instructions
ARM 코어에 연결된 coprocessor(예: MMU를 제어하는 CP15)와 데이터를 주고받거나 coprocessor의 연산을 수행시키는 명령어다. ARM 레지스터와 coprocessor 레지스터 사이의 값 전송에는 MRC, MCR을 사용한다.
세부 문법은 ARM Instruction Set: Coprocessor Register Transfers (MRC, MCR) 글에서 다룬다.
조건부 실행과 공통 문법
위에서 다룬 그룹 대부분은 명령어 뒤에 condition code를 붙여 조건부로 실행할 수 있고, 데이터 처리 명령어는 S suffix로 연산 결과에 따라 condition flag를 갱신할지 선택할 수 있다.
ADD R0, R1, R2 ; R0 = R1 + R2, flag는 그대로
ADDS R0, R1, R2 ; R0 = R1 + R2, 연산 결과로 N/Z/C/V flag 갱신
ADDEQ R0, R1, R2 ; 이전 결과의 Z flag가 1일 때만 실행
분기문 없이도 짧은 조건문을 명령어 단위로 처리할 수 있어, 파이프라인을 끊는 branch를 줄이는 데 유용하다.
마치며
ARM instruction set은 Branch, Data processing, Load/Store(single·multiple), Status register access, Semaphore, Coprocessor 명령어로 크게 나뉜다. 각 그룹은 서로 다른 목적을 갖고 있지만, condition field를 통한 조건부 실행이라는 공통 특징을 공유한다. 명령어별 상세 문법과 예제는 아래 글에서 확인할 수 있다.
- ARM Instruction Set: Branch Instructions (B, BL)
- ARM Instruction Set: Software Interrupt (SWI)
- ARM Instruction Set: Data Processing
- ARM Instruction Set: Multiply and Multiply-Accumulate (MUL, MLA)
- ARM Instruction Set: Single Data Transfer (LDR, STR)
- ARM Instruction Set: Block Data Transfer (LDM, STM)
- ARM Instruction Set: PSR Transfer (MRS, MSR)
- ARM Instruction Set: Single Data Swap (SWP)
- ARM Instruction Set: Coprocessor Register Transfers (MRC, MCR)