Data Processing Instructions Arithmetic Operations 앞에서는 논리적인 연산들 (Bolean / AND (&), OR (^) 등) 에 대해 알아보았다. 이번에는 논리 연산이 아닌 직접적인 수와 수 사이의 산술에 대한 연산 ( ADD (+), SUB (-)) 들에 대해 알아볼것이다. 시스템 프로그래밍 - 4 (1) : Data Processing Instructions - Logical operations
+ 모든 Data Processing Instructions 은 오직 레지스터에서만 실행된다. 절대로 메모리에서 실행되지 않는다.
- Basic Arithmetic Operations
Add : 덧셈
- ADD r0, r1, r2 @ r0 := memory [r5]
Subtract : 뺄셈
- SUB r0, r1, #3 @ r0 := memory [r5]
Reverse Subtract : 역 뺄셈
- RSB r0, r1, r2 @ r0 := memory [r5]
이유는, 모든 Instruction 들은 기본적인 사용 형식이 있다. ( 4 (1)에서 설명 ) XXX rd, rm, op 와 같이 각각 rd, rm, op 에 들어갈 수 있는 것들이 따로 정의되어 있는데 rm 의 부분에는 #3과 같은 상수값이 들어갈 수가 없다 (오직 레지스터만 들어갈 수 있다.). 그래서 SUB r0, r1, #3 대신 SUB r0, #3, r1 이렇게 자리를 바꾸어서 [ 상수(#7) - 레지스터안의 값(r1) ] 형태로 SUB을 쓸 수 없기에 RSB를 사용하는 것이다.
- Condition Code Flags
Condition 은 굉장히 중요한 부분이면서, ARM 프로그래밍에 있어서 여러 코드들을 프로그래머 마음대로 이용할 수 있게 만들어 주는 유용한 코드이다. Condition 코드는 다른 Instruction set 들과 똑같이 32 bits 레지스터를 할당받는데, Conditon 코드 전체 32 bits 의 각 비트는 산술 및 논리 연산의 결과를 저장하여 조건 분기 명령의 조건을 표시한다. 조건 분기 명령의 조건을 표시한다는 점에서, 조건 분기가 많이 쓰이는 프로그래밍 분야에서 이것이 얼마나 중요하고, 유용한 코드인지 알 수 있다.
사용자 수준(User Mode)의 프로그램에서는 일반적으로 레지스터가 어떻게 구성되어 있는지 자세히 알 필요는 없다. Condition 코드(PSR = CPSR)는 전체 32 bits의 '방'을 제공받으며, 상태 레지스터(PSR)라고도 불리우며, 32bits 의 '방'은 Flag bits 와 Control bits 로 나누어져있다. PSR(=CPSR) 에서 우리가 공부할 파트인 '사용자 수준(User Mode)의 프로그램'에서 알아야할 것은 Flag bits 뿐이다.
- CPSR ( Corrent Program Status Register )
CPSR 은 PSR 이라는 상태 레지스터 (Statue register) 이며 월래 본 명칭은 PSR 이지만, CPSR 로도 부른다. PSR 에는 위에서도 말했듯이 Flag bits 부분과 Control bits 부분으로 나누어지지만 여기에서는 우리에게 필요한 Condition Code Flags 만을 알아보자.
CPSR 의 전체 32bits 의 '방'에서 최상위 부분(MSB)에 있는 4 bits 가 Flags bits 이다. ( CPSR의 상위 MSB '4 비트' = N, Z, C, V ) Flag는 말 그대로 깃발이라는 뜻으로, 어떠한 정보를 청기(1) 혹은 백기(0)를 들어서 특정 성질의 유무를 쉽게 알아볼 수 있게 만든것이다. 다음 Flag 들은 특정 정보가 맞으면 '1' 이라는 값을 갖고, 틀리면 '0'이라는 값을 가진다.
N : Negative result - 바로 이전의 Computation 에서 결과 값이 음수인가 아닌가?
Z : Zero result - 바로 이전의 Computaion 에서 결과 값이 제로(영)인가 아닌가?
C : Carried out - 바로 이전의 Computaion 에서 Carry out 이 발생하였는가?
V : oVerflowed - 바로 이전의 Computaion 에서 oVerflow 가 발생하였는가?
어떤 특정한 Computation 의 결과로 발생하는 N, Z, C, V 에 대한 Flag 값들을 읽어내기 위해 그 특정 Computation 을 실행하는 Instruction 에 접미어 S 를 붙이면 그 Computation 이후에 여러 조건들(N, Z, C, V)에 해당하는 Condition flag 에 값들을 1과 0으로 세팅하게 된다. (Postfix "S") 그리고 우리는 그 세팅된 flag 값들을 이용하기만 하면 된다.
ex. ADD r2, r2, r0 / ADDS r2, r2, r0 - S 가 붙은 후자의 Instruction 에서만 Flag 값들이 설정된다.
- Arithmetic Operations with Carry Bit
위에서 어떤 Computation 을 하는 Instruction 에 Postfix S 를 붙임으로써 Condition Code Flags 를 이용하였다.
예를 들어, SUBS r2, r2, r0 ß S 를 붙여서 condition flags 세팅하였다. 다음 라인부터 이 Flags 를 이용가능하다.
이렇게 Flag를 Postfix S 를 이용하여 사용할 수 도 있지만, 아예 Computation 자체 결과에서 (다음 라인까지 갈 필요없이) Flag 를 세팅하여 그 Flag 값을 적용하기 위해서는 따로 S 를 붙일 필요없이 특정 Instruction 을 사용하면된다. ( 단, Carry out 에 관련된 C Flag 에 국한된다. ) 예를 들어, SBC r3, r3, r1 ß SUB 연산을 하는 동시에 그에 대한 결과를 이용햐 C Flag 를 세팅하고 그렇게 세팅된 C Flag 를 SUB 연산의 결과에 바로 적용시킨다.
ADC r3, r3, r1 / ADC 는 ADD + Carry bit 표현
/ ADD 의 결과 값이 기본 32bits를 넘어설 경우 발생하는 Carry를 같이 표현해주기 위함.
ADD r0, r1, r2 @ r0 ß r1 + r2
ADC r0, r1, r2 @ r0 ß r1 + r2 + C
SUB r0, r1, r2 @ r0 ß r1 - r2
SBC r0, r1, r2 @ r0 ß r1 - r2 + C - 1
RSB r0, r1, r2 @ r0 ß r2 - r1
RSC r0, r1, r2 @ r0 ß r2 - r1 + C - 1
왜? Subtract 연산에서는 Carry Bit 를 붙여준 후에 1을 빼줄까?
- 뺼셈 연산은 실제로 컴퓨터 안에서는 2 진수들의 덧셈 연산을 이용하고 우리에게 뺄셈의 결과를 보여주는 것이다. 그렇게 해서 발생한 Carry bit 는 덧셈에 대한 Carry bit 일 수 밖에 없다. 이렇게 컴퓨터의 연산방법에 의하여 내제적인 Carry bit의 문제점을 없애서 바로 잡아야한다. 그래서 이 뺼셈을 수행하는 구조적인 문제에서 발생한 Carry bit 를 마지막에서 빼주어 없애기 위해 '-1' 연산을 하는 것이다.
이렇게 지금까지 산술 연산 (Arithmetic operation)에 대해 알아보았다.
다음은 Comparisons '비교' Instruction에 대해 알아보자.
'시스템 프로그래밍 > - 강의 정리' 카테고리의 다른 글
시스템 프로그래밍 - 4 (3) : Data Processing Instructions - Comparisons (0) | 2012.04.05 |
---|---|
시스템 프로그래밍 - 4 (1) : Data Processing Instructions - Logical operations (0) | 2012.04.05 |
시스템 프로그래밍 - 3 : Load / Store Instructions (0) | 2012.04.05 |
시스템 프로그래밍 - 2 : System Data Structure (시스템 데이터 구조) (0) | 2012.04.04 |
시스템 프로그래밍 - 1 (2) : ARM(SoCs) 개발, 공부를 위한 환경 구축하기 (0) | 2012.03.12 |