ARM
- 임베디드 기기에 주로 사용되는 RISC 프로세서
- 저전력을 사용하도록 설계됨 → 모바일 기기 또는 IoT 디바이스에 사용됨
모드
- Thumb 모드 레지스터 : R0 ~ R7 (8개) 기계어 코드 길이 : 16bit(2byte)
- ARM 모드 레지스터 : R0 ~ R15 (16개) 기계어 코드 길이 : 32bit(4byte)
Thumb ↔ ARM 전환 : BLX/BX등 X로 끝나는 분기문 명령으로 모드를 전환한다.
레지스터
- R0 ~ R12 : 범용 레지스터, 인자값 및 임시 계산 저장소 등
- R0 : 함수 리턴값 저장
- R0 ~ R3 : 함수 호출 인자 전달
- R4 ~ R11 : 지역변수 저장
- R13 ~ R15 : 특수 레지스터
- R13(SP) : Stack Pointer 스택의 맨 위
- R14(LR) : Link Register, 함수 호출 전 LR에 리턴 주소 저장
- R15(PC) : 다음 실행할 코드의 주소 저장, x86의 EIP 레지스터와 동일한 역할
- CPSR : 현재 프로그램 상태 레지스터
- SPSR : CPSR값을 저장해두는 레지스터(CPSR 백업용)
ARM 아키텍처의 버전에 따라 레지스터의 개수는 다를 수 있다. ARMv8의 레지스터는 범용레지스터가 16개이고 총 레지스터 갯수는 30개가 넘는다.
함수 호출 규약
R0 ~ R3 : 인자 및 반환 값을 저장하기 위한 Register로 사용된다.
그러나 인자의 수가 4개 이상인 경우 stack을 통해 인자를 전달한다.
명령어
OP Code Rd, Rs, Rm
- OP Code : push, add, sub, mov 등 어셈블리 명령어
- Rd : Register Direction, 반드시 R0~R15인 Register만 가능하며 연산작업의 결과값을 저장하는 레지스터
- Rs : Register Source, 연산을 위해 사용되는 첫 번째 레지스터, 반드시 R0~R15인 Register만 가능
- Rm : Op2, 레지스터뿐만 아니라 상수(#), 주소([]), 쉬프트 연산식 등 다양한 값이 사용가능.
1-1) 산술연산
- ADD(Addition)
- ADD Rd Rs Rm → Rd = Rs + Rm
- ADC(Addition with Carry)
- ADC Rd Rs Rm → Rd = Rs + Rm + carry
- SUB(Subtraction)
- SUB Rd Rs Rm → Rd = Rs - Rm
- SBC(Subtraction with Carry)
- SBC Rd Rs Rm → Rd = Rs - Rm - !carry
- RSB(Reverse Subtraction)
- RSB Rd Rs Rm → Rd = Rs- Rs
- RSC(Reverse Subtraction with Carry)
- RSC Rd Rs Rm → Rd = Rm - Rs - !carry
1-2) 논리 연산
- AND(Logical AND)
- AND Rd Rs Rm → Rd = Rs AND Rm
- ORR(Logical OR)
- ORR Rd Rs Rm → Rd = Rs OR Rm
- EOR(Logical XOR)
- EOR Rd Rs Rm → Rd = Rs XOR Rm
- BIC(Bit Clear)
- BIC Rd Rs Rm → Rd = Rs AND (!Rm)
1-4) 시프트 연산
- LSL(Logical Shift Left)
- LSL #n : 최후에 밀려난 비트가 CPSR의 C-flag에 저장
LSL
: signed/unsigned
곱하기 2
- LSR(Logical Shift Right)
- LSR #n : 최후에 밀려 비트가 CPSR의 C-flag에 저장
- ASR
- ASR #n : MSB를 유지하고, 밀려난 비트가 CPSR의 C-flag에 저장
ASR
은 signed int
의 나누기 2 동작을 수행합니다.
- 레지스터를 우측으로 지정한 비트 수 만큼 부호를 유지하며 Shift합니다.
1-4) Register 값 저장
- MOV(Move)
- MVN(Move Negative)
1-5) 비교 연산
- CMP(Compare)
- CMP Rs Rm → status = Rs - Rm
- "Rs - Rm"의 결과를 Status flag에 반영
- CMN(Compare Negative)
- CMN Rs Rm → status = Rs - ( -Rm) = Rs + Rm
- "Rs + Rm"의 결과를 Status flag에 반영
- TST(Test bits)
- TST Rs Rm → Status = Rs AND Rm
- "Rs AND Rm"의 결과를 Status flag에 반영
- TEQ(Test Equivalence)
- TEQ Rs Rm → Status = Rs XOR Rm
- "Rs XOR Rm"의 결과를 Status flag에 반영
1-6) 분기 명령어
- B(Branch)
- B Rd
- B add : Global Label
- B 1f : Local Lable
- B . : 무한루프(‘ . ’ = 제자리)
- 뒤에 지정된 주소값으로 분기
- BL(Branch with Link)
- BL Rd
- 뒤에 지정된 주소값으로 분기하면서 현재 R15(PC) + 0x2 번지의 주소값을 R14에 저장
B와 BL은 분기 주소로 레지스터를 사용할 수 없다.
- BX(Branch indirect)
- BLX(Branch indirect with Link)
- BLX R
- 뒤에 지정된 레지스터 값으로 분기하면서 현재 R15(PC) + 0x2 번지의 주소 값을 R14에 저장
1-7) 메모리 접근 명령어
- LDR(Load) : 메모리 → 레지스터(Load to Register)
- ldr Rd, [Rs] : Rs의 값을 주소로 참조하여 Rd에 저장
- ldr Rd, [Rs], #4 : Rs의 값을 주소로 참조하여 Rd에 저장하고 Rs에 4를 더함
- ldr Rs , =Value : Rs레지스터에 상수값(최대 4byte) 저장
- STR(Store) : 레지스터 → 메모리(Store to Memory)
- ex)
- str Rd, [Rs] : Rd의 값을 Rs의 값을 주소로 참조하여 저장
- str Rd, [Rs], #4 : Rd의 값을 Rs의 값을 주소로 참조하여 저장하고 Rs에 4를 더함
상태 플래그
- N : 연산 결과가 음의 값을 가질 경우 → Set 1
- Z : 연산 결과가 Zero인 경우 → Set 1
- C : 연산 결과가 Carry를 가질 경우 → Set 1
- V : 연산 결과 Overflow가 발생한 경우 → Set 1
링크