ARM 아키텍처는 16개의 레지스터를 가지고 있다.
- R0 ~ R12 : 범용 레지스터. 인자값 저장 등
- R13(SP) : Stack Pointer. 스택의 주소를 저장하는 레지스터. x86 의 ESP 레지스터와 비슷
- R14(LR) : Link Register. 함수 호출 시 되돌아갈 함수의 주소가 저장되는 레지스터
- R15(PC) : x86 에서의 EIP 레지스터와 동일한 역할. 다음에 실행할 코드의 주소 저장
어셈블리어에 대해 간단히 살펴보자.
OP Code : MOV, ADD, SUB, LDR, STR 과 같은 어셈블리 명령어
cond : 조건부로 명령을 실행해야 할 경우 OP Code 뒤에 붙여서 사용.
Rd : Destination Register. 연산작업의 결과값을 저장하는 레지스터. 반드시 R0~R15 만 올 수 있음.
Rn : Operand1 Register. 반드시 R0~R15 만 올 수 있음.
Rm : Operand2 Register. 레지스터뿐만 아니라 상수, 주소, Shift 연산식 등 다양한 값 사용가능.
1. MOV
ex) MOV R0, [R2, R4] : R2 + R4 주소에 있는 값을 읽어서 R0 에 저장.
OP Code : MOV,
Rd : R0,
Rn : R2,
Rm : R4
ex) MOV R0, #1 : 상수 1을 R0 로 복사
2. ADD
ex) ADD Rd, Rn, Rm : Rd = Rn + Rm
3. SUB
ex) SUB Rd, Rn, Rm : Rd = Rn - Rm
4. AND
ex) AND R0, R1, #0xF3 : R0 = R1 & 0xF3
5. ORR
ex) ORR R0, R1, #0x02 : R0 = R1 | 0x02
6. EOR
ex) EOR R0, R1, #0xF3 : R0 = R1 ^ 0xF3
7. LSL
<< Left Shift
8. RSL
>> Right Shift
9.CMP
if(Rn - Rm == 0). Rn 과 Rm 의 값이 같은지 비교하는 명령어.
Rn 에서 Rm 을 뺀 결과를 Status Register 에 저장.
Status Register 에는 연산결과를 저장하는 4개의 필드가 있다.
CPSR (Current Program Status Register) 의 4개 필드
- N (Negative) : 연산결과가 음수이면 1로 SET
- Z (Zero) : 연산결과가 0이면 1로 SET
- C (Carry) : 덧셈 연산의 Carry이면 1로 SET, 뺄셈 연산의 Borrow 이면 0으로 clear.
- V (Overflow) : signed 연산의 덧셈, 뺄셈에서 연산결과로 overflow 가 발생하면 1로 SET
여기서 조건부 실행 옵션이 붙는데,
EQ 는 같을 때, NE 는 다를 때 실행되는 옵션이다.
예를 들어
CMP R0, R1
ADDEQ R0, R2, #1
MOVNE R0, #1
와 같은 어셈블리어가 있다면
R0 과 R1 의 값을 비교하여 같으면 ADD 연산 실행,
다르면 MOV 연산을 실행하라는 것과 같다.
10. Memory Operation
LDR : Load to Register
STR : Store to Memory
ex) LDR R0, =0x1000 : R0 에 상수 0x1000 저장 (LDR 에서 상수를 사용할 때는 #이 아닌, =을 붙여주자)
LDR R1, [R0] : 0x1000 번지에 있는 값을 R1 에 저장
STR R1, [R0] : R1 의 값을 0x1000 번지의 메모리 주소에 저장