Data processing 중에 Move instruction를 알아보자
Move
Move는 ALU와 Rn을 사용하지 않는다. 즉, second soure operand만을 가지고 preprocessing 하여 Rd로 이동한다.
2가지 명령어가 존재한다.
1. MOV
- 단순히 Rm을 preprocessing 하여 N을 출력하고 N이 그대로 Rd로 이어진다. (Rd = N)
예를 들어보자,
MOV R0, R0, LSL#3 은 R0 = R0 * 8을 의미한다. 왜냐면 LSL은 logical shift left를 의미하니 왼쪽으로 3번 옮기면 *2^3을 하는 것과 같기 때문에 R0 * 8이라고 본다.
대표적으로 많이 쓰는 것이 MOV PC, R14이다. 언제 쓰냐면 function call로 사용한다. 함수를 호출하는 것이 아니라, 함수가 다 실행되고 돌아갈 주소를 r14에 저장해놨기 때문에 불러오는 것이다. r14는 link register로 사용한다.
그런데 MOVS PC, R14를 하면 조금 다른데 위와 똑같이 동작하지만 뒤에 S를 붙이면 CPSR도 업데이트 시켜준다. 무슨 말이냐면 Arm은 조건에 따라 동작한다 했다. 그러니 조건까지 바꿔주는게 S를 붙이는 것이다. 즉, nzcv Flag를 업데이트 시켜준다. 해서 MOVS PC, R14는 interrupt나 exception이 발생한 후 돌아올 때 사용한다.
조금 다른 MOVS를 예를 들어보면 (+ 뒤에 S를 붙이면 nzcv Flag를 업데이트한다.)
실행하기 전에 아래와 같은 상태라고 가정하자,
Before
cpsr = nzcv // 0000
r0 = 0x0000_0000;
r1 = 0x8000_0004;
+ 소문자 nzcv는 0000이라는 의미다.
MOVS r0, r1, LSL #1을 하면 r1을 왼쪽으로 1bit shift 시키면, MSB인 8은 1000이라 0000이 되고, LSB인 4는 0100이라 1000이 된다. 나머지는 다 0이기 때문에 연산 후에 업데이트를 하면 r0 = 0x0000_0008이 된다.
또한 C가 1로 세팅되는 이유는 r1에서 1이 carry로 나갔기 때문이다.
MOVS r0, r1 LSL #1
After
cpsr = nzCv // 0010
r0 = 0x0000_0008;
r1 = 0x8000_0004;
그런데 shift 시키는대도 한계가 있다. imm bit가 한정돼 있기 때문이다. 그래서 pseudo(가짜) 명령어가 존재하는데 그게 바로 ldr 명령어이다. ldr r0, =0x55555와 같이 쓰는데 0x55555를 r0에 집어넣는다. MOV 명령어와 동일한 동작을 한다.
2. MVN
- MOV와 유사하지만 MOV에서 inverting 한 결과를 Rd로 보낸다. 다시 말해 shift preprocessing을 거쳐서 나온 N을 뒤집에서 Rd로 보내는 것이다. (Rd = ~N)
'시스템 반도체 > Arm' 카테고리의 다른 글
Arm Branch instruction ( 분기 명령어, B, BL ) (0) | 2022.04.07 |
---|---|
Arm Aruthmetic instruction ( 산술 명령어, ADD, ADC, SUB, SBC, RSB, RSC, CLZ ) (0) | 2022.04.07 |
Arm Logical Instruction ( 논리 명령어, AND, ORR, EOR, BIC ) (0) | 2022.04.07 |
Arm Comparison instruction ( 비교 명령어, CMP, CMN, TEQ, TST ) (0) | 2022.04.07 |
Arm 명령어 구조 ( Instruction Format, 동작 ) (0) | 2022.04.07 |
댓글