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]

 

  왜? Subtract 가 있는데 Reverse-Subtract 라는 것을 따로 만들었을까?

이유는, 모든 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에 대해 알아보자.

 

 

 

 

 

 

Posted by 하늘_