"ADD, ADC, SUB, SBC and RSB"의 두 판 사이의 차이

TRACE32
이동: 둘러보기, 검색
4번째 줄: 4번째 줄:
 
<p>레지스터 끼리의 값을 더하거나, 레지스터의 값과 상수값을 더합니다.</p>
 
<p>레지스터 끼리의 값을 더하거나, 레지스터의 값과 상수값을 더합니다.</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
<p>실행 전 :</p>
+
<p style="padding-left: 30px;">실행 전 :</p>
<p>"ADD R1,SP,#0x8" 명령을 통해</p>
+
<p style="padding-left: 30px;">"ADD R1,SP,#0x8" 명령을 통해</p>
<p>스택포인터(R13)의 값에 0x8을 더해 R1에 입력합니다.</p>
+
<p style="padding-left: 30px;">스택포인터(R13)의 값에 0x8을 더해 R1에 입력합니다.</p>
<p><img src="/data/wiki/2015-05-11/1431354901.jpg" alt="" /></p>
+
<p style="padding-left: 30px;"><img src="/data/wiki/2015-05-11/1431354901.jpg" alt="" /></p>
 +
<p style="padding-left: 30px;">&nbsp;</p>
 +
<p style="padding-left: 30px;">실행 후 :</p>
 +
<p style="padding-left: 30px;">R1값이 R13의 값(0x2000_2430)보다 0x8만큼 큰 0x2000_2438로 변했습니다.</p>
 +
<p style="padding-left: 30px;"><img src="/data/wiki/2015-05-11/1431354909.jpg" alt="" /></p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
<p>실행 후 :</p>
 
<p>R1값이 R13의 값(0x2000_2430)보다 0x8만큼 큰 0x2000_2438로 변했습니다.</p>
 
<p><img src="/data/wiki/2015-05-11/1431354909.jpg" alt="" /></p>
 
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 +
<p>ADC : Add with carry</p>
 +
<p>레지스터 끼리 값을 더할 때, Carry비트의 값을 추가해 줍니다.</p>
 +
<p>Carry비트의 SET/CLEAR 여부에 따라 결과가 달라집니다.</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 +
<p>Carry 비트가 "0"인 경우</p>
 +
<p style="padding-left: 30px;">실행 전 :</p>
 +
<p style="padding-left: 30px;">"ADC R2,R1,R0" 명령의 수행결과는, R2=R1+R0+Carry 와 같습니다.</p>
 +
<p style="padding-left: 30px;">아래의 그림에서 C(Carry)비트는 0으로 클리어 되어 있음을 확인할 수 있습니다.</p>
 +
<p style="padding-left: 30px;"><img src="/data/wiki/2015-05-12/1431383272.jpg" alt="" /></p>
 +
<p style="padding-left: 30px;">&nbsp;</p>
 +
<p style="padding-left: 30px;">실행 후 :</p>
 +
<p style="padding-left: 30px;">"ADC R2,R1,R0" 수행 결과, "R2 = 1(R1) + 0(R0) + 0(Carry)" 이 되어,</p>
 +
<p style="padding-left: 30px;">R2의 값이 1로 변경되었음을 확인할 수 있습니다.</p>
 +
<p style="padding-left: 30px;"><img src="/data/wiki/2015-05-12/1431383279.jpg" alt="" /></p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
<p>ADC : Add with carry</p>
 
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 +
<p>Carry 비트가 "1"인 경우</p>
 +
<p>&nbsp;</p>
 +
<p style="padding-left: 30px;">실행 전 :</p>
 +
<p style="padding-left: 30px;">"ADC R4,R3,R0" 명령의 수행결과는, R4=R3+R0+Carry 와 같습니다.</p>
 +
<p style="padding-left: 30px;">아래의 그림에서 C(Carry)비트는 1로 세트 되어 있음을 확인할 수 있습니다.</p>
 +
<p style="padding-left: 30px;"><img src="/data/wiki/2015-05-12/1431383285.jpg" alt="" /></p>
 +
<p style="padding-left: 30px;">&nbsp;</p>
 +
<p style="padding-left: 30px;">실행 후 :</p>
 +
<p style="padding-left: 30px;">"ADC R4,R3,R0" 수행 결과, "R4 = 1(R3) + 0(R0) + 1(Carry)" 이 되어,</p>
 +
<p style="padding-left: 30px;">R4의 값이 2로 변경되었음을 확인할 수 있습니다.</p>
 +
<p style="padding-left: 30px;"><img src="/data/wiki/2015-05-12/1431383291.jpg" alt="" /></p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
23번째 줄: 47번째 줄:
 
<p>SUB : Subtract</p>
 
<p>SUB : Subtract</p>
 
<p>레지스터 끼리의 값을 빼거나, 레지스터의 값에서 상수값을 뺍니다.</p>
 
<p>레지스터 끼리의 값을 빼거나, 레지스터의 값에서 상수값을 뺍니다.</p>
 +
<p>&nbsp;</p>
 +
<p style="padding-left: 30px;">실행 전 :</p>
 +
<p style="padding-left: 30px;">"SUB SP,SP,#0x1C" 명령을 통해</p>
 +
<p style="padding-left: 30px;">스택포인터(R13) 의 값을 0x1C만큼 감소시킵니다.</p>
 +
<p style="padding-left: 30px;"><img src="/data/wiki/2015-05-11/1431355268.jpg" alt="" /></p>
 +
<p style="padding-left: 30px;">&nbsp;</p>
 +
<p style="padding-left: 30px;">실행 후 :</p>
 +
<p style="padding-left: 30px;">수행 결과, R13의 값이 0x2000_244C에서 0x2000_2430으로 0x1C만큼 감소하였습니다.</p>
 +
<p style="padding-left: 30px;"><img src="/data/wiki/2015-05-11/1431355276.jpg" alt="" /></p>
 +
<p>&nbsp;</p>
 +
<p>&nbsp;</p>
 +
<p>SBC : Subtract with carry</p>
 +
<p>ADD, SUB, ADC, SBC 등의 명령어 중에서 가장 혼동되기 쉬운 어셈블리가 아닐까 생각됩니다.</p>
 +
<p>레지스터 끼리의 값을 빼되, Carry비트가 클리어(0)되어 있으면, 값을 추가로 1만큼 감소시킵니다.</p>
 +
<p>자세한 것은 아래의 예를 통해서 살펴보도록 하겠습니다.</p>
 +
<p>&nbsp;</p>
 +
<p>Carry 비트가 "1"인 경우</p>
 +
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>실행 전 :</p>
 
<p>실행 전 :</p>
<p>"SUB SP,SP,#0x1C" 명령을 통해</p>
 
<p>스택포인터(R13) 의 값을 0x1C만큼 감소하여, 다시 R13으로 입력합니다.</p>
 
<p><img src="/data/wiki/2015-05-11/1431355268.jpg" alt="" /></p>
 
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>실행 후 :</p>
 
<p>실행 후 :</p>
<p>수행 결과, R13의 값이 0x2000_244C에서 0x2000_2430으로 0x1C만큼 감소하였습니다.</p>
 
<p><img src="/data/wiki/2015-05-11/1431355276.jpg" alt="" /></p>
 
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
<p>SBC : Subtract with carry</p>
+
<p>Carry 비트가 "1"인 경우</p>
 +
<p>&nbsp;</p>
 +
<p>실행 전 :</p>
 +
<p>&nbsp;</p>
 +
<p>실행 후 :</p>
 +
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
43번째 줄: 85번째 줄:
 
<p>SUB 명령이 레지스터의 값에서 상수값을 뺀 것과는 반대(Reverse)로,</p>
 
<p>SUB 명령이 레지스터의 값에서 상수값을 뺀 것과는 반대(Reverse)로,</p>
 
<p>RSB 명령은 상수값에서 레지스터의 값을 뺍니다.</p>
 
<p>RSB 명령은 상수값에서 레지스터의 값을 뺍니다.</p>
 +
<p>(예 : SUB R1,R0,#0x700 ==&gt; R1=R0-0x700</p>
 +
<p>&nbsp; &nbsp; &nbsp; &nbsp;RSB R1,R0,#0x700 ==&gt; R1=0x700-R0)</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
<p>실행 전 :</p>
+
<p style="padding-left: 30px;">실행 전 :</p>
<p>"RSBS R1,R1,#0x700" 명령을 통해,</p>
+
<p style="padding-left: 30px;">아래의 "RSBS R1,R1,#0x700" 명령을 통해,</p>
<p>0x700에서 R1을 뺀 후, 그 값을 R1으로 입력합니다.</p>
+
<p style="padding-left: 30px;">0x700에서 R1을 뺀 후, 그 값을 R1으로 입력합니다.</p>
<p><img src="/data/wiki/2015-05-11/1431355476.jpg" alt="" /></p>
+
<p style="padding-left: 30px;"><img src="/data/wiki/2015-05-11/1431355476.jpg" alt="" /></p>
<p>&nbsp;</p>
+
<p style="padding-left: 30px;">&nbsp;</p>
<p>실행 후 :</p>
+
<p style="padding-left: 30px;">실행 후 :</p>
<p>"RSBS R1,R1,#0x700" 수행결과,</p>
+
<p style="padding-left: 30px;">"RSBS R1,R1,#0x700" 수행결과,</p>
<p>R1의 값이 0x600에서 0x100으로 변경되었습니다. (R1 = 0x700-0x600)</p>
+
<p style="padding-left: 30px;">R1의 값이 0x600에서 0x100으로 변경되었습니다. (R1 = 0x700-0x600)</p>
<p><img src="/data/wiki/2015-05-11/1431355483.jpg" alt="" /></p>
+
<p style="padding-left: 30px;"><img src="/data/wiki/2015-05-11/1431355483.jpg" alt="" /></p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>

2015년 5월 12일 (화) 07:36 판

이번에는 가장 간단한 레지스터 연산인 ADD, ADC, SUB, SBC, RSB 에 대해 알아보겠습니다.

 

ADD : Add

레지스터 끼리의 값을 더하거나, 레지스터의 값과 상수값을 더합니다.

 

실행 전 :

"ADD R1,SP,#0x8" 명령을 통해

스택포인터(R13)의 값에 0x8을 더해 R1에 입력합니다.

 

실행 후 :

R1값이 R13의 값(0x2000_2430)보다 0x8만큼 큰 0x2000_2438로 변했습니다.

 

 

 

ADC : Add with carry

레지스터 끼리 값을 더할 때, Carry비트의 값을 추가해 줍니다.

Carry비트의 SET/CLEAR 여부에 따라 결과가 달라집니다.

 

Carry 비트가 "0"인 경우

실행 전 :

"ADC R2,R1,R0" 명령의 수행결과는, R2=R1+R0+Carry 와 같습니다.

아래의 그림에서 C(Carry)비트는 0으로 클리어 되어 있음을 확인할 수 있습니다.

 

실행 후 :

"ADC R2,R1,R0" 수행 결과, "R2 = 1(R1) + 0(R0) + 0(Carry)" 이 되어,

R2의 값이 1로 변경되었음을 확인할 수 있습니다.

 

 

Carry 비트가 "1"인 경우

 

실행 전 :

"ADC R4,R3,R0" 명령의 수행결과는, R4=R3+R0+Carry 와 같습니다.

아래의 그림에서 C(Carry)비트는 1로 세트 되어 있음을 확인할 수 있습니다.

 

실행 후 :

"ADC R4,R3,R0" 수행 결과, "R4 = 1(R3) + 0(R0) + 1(Carry)" 이 되어,

R4의 값이 2로 변경되었음을 확인할 수 있습니다.

 

 

 

SUB : Subtract

레지스터 끼리의 값을 빼거나, 레지스터의 값에서 상수값을 뺍니다.

 

실행 전 :

"SUB SP,SP,#0x1C" 명령을 통해

스택포인터(R13) 의 값을 0x1C만큼 감소시킵니다.

 

실행 후 :

수행 결과, R13의 값이 0x2000_244C에서 0x2000_2430으로 0x1C만큼 감소하였습니다.

 

 

SBC : Subtract with carry

ADD, SUB, ADC, SBC 등의 명령어 중에서 가장 혼동되기 쉬운 어셈블리가 아닐까 생각됩니다.

레지스터 끼리의 값을 빼되, Carry비트가 클리어(0)되어 있으면, 값을 추가로 1만큼 감소시킵니다.

자세한 것은 아래의 예를 통해서 살펴보도록 하겠습니다.

 

Carry 비트가 "1"인 경우

 

 

실행 전 :

 

실행 후 :

 

 

Carry 비트가 "1"인 경우

 

실행 전 :

 

실행 후 :

 

 

 

 

 

RSB : Reverse subtract

서로 값을 빼는 것은 "SUB(Subtract)"와 동일하나,

SUB 명령이 레지스터의 값에서 상수값을 뺀 것과는 반대(Reverse)로,

RSB 명령은 상수값에서 레지스터의 값을 뺍니다.

(예 : SUB R1,R0,#0x700

> R1=R0-0x700</p> <p>� � � �RSB R1,R0,#0x700

> R1=0x700-R0)

 

실행 전 :

아래의 "RSBS R1,R1,#0x700" 명령을 통해,

0x700에서 R1을 뺀 후, 그 값을 R1으로 입력합니다.

 

실행 후 :

"RSBS R1,R1,#0x700" 수행결과,

R1의 값이 0x600에서 0x100으로 변경되었습니다. (R1 = 0x700-0x600)

 

 

 

The Condition flags

N(Negative) : 연산의 결과가 음수이면 "1"로 세팅되고, 아니면 "0"으로 클리어 됩니다.

Z(Zero) : 연산의 결과가 "0x0"이면 "1"로 세팅되고, 아니면 "0"으로 클리어 됩니다.

C(Carry) : 더한 결과가 2^32보다 크거나 같으면 "1"로 세팅되고, 아니면 "0"으로 클리어 됩니다.

뺀 결과가 음수가 아니면 "1"로 세팅되고, 음수이면 "0"으로 클리어 됩니다.

V(oVerflow) : 더하기, 빼기 혹은 비교의 결과가 2^31 이상이거나, -2^31 보다 작으면 "1"로 세팅됩니다.

 

 

이상으로 기본적인 레지스터 연산인 ADD, SDC, SUB, SBC, RSB에 대해 알아보았습니다.

잘못된 점이나, 추가 문의사항은 TRACE32@mdstec.com 으로 연락 부탁드립니다.

 

"TRACE32로 바라본 ARM - Cortex-M" 으로 돌아가기