유용한 ARM Assembly

정리: 이채원 (ichijo99@hanmail.net)
Homepage: http://user.chollian.net/~hebb
Date: 2004.12.27.

본 문서의 내용은 ARM System Developer’s Guide의 Ch. 5, 6 의 일부분에서 발췌한 것임을 밝힙니다.

[1] Conditional Execution

(A)
// Converts an unsigned int i(0 <= i <= 15) to a hexadecimal character c

if(i<10)  c = i + '0';
else  c = i + 'A' - 10;

.......................................................................
c RN 0  ; Assign c to r0
i RN 1  ; Assign i to r1

 CMP i, #10
 ADDLO c, i, #'0'      ; == ADDCC   c, i, #’0’
 ADDHS c, i, #'A'-10   ; == ADDCS   c, I, #’A’-10
 
(B)
// If c is either 'a', 'e', 'i', 'o', or 'u', then vowel increases

if(c=='a' || c=='e' || c=='i' || c=='o' || c=='u')  vowel++;

.......................................................................

c RN 0  ; Assign c to r0
vowel RN 1  ; Assign vowel to r1

 TEQ c, #'a'
 TEQNE c, #'e'
 TEQNE c, #'i'
 TEQNE c, #'o'
 TEQNE c, #'u'
 ADDEQ vowel, vowel, #1

.......................................................................
 
(C)
// If c is a letter, increase letter

if ( (c>='A' && c<='Z') || (c>='a' && c<='z') ) letter++;

.......................................................................

c RN 0  ; Assign c to r0
temp RN 1  ; Assign temp to r1
letter RN 2  ; Assign temp to r2

 SUB temp, c, #'A'
 CMP temp, #'Z'-'A'
 SUBHI temp, c, #'a'
 CMPHI temp, #'z'-'a'
 ADDLS letter, letter, #1

.......................................................................


 
[2] Loop

(1)
//Loop from 10 to 1
for(i=10; i>=1;i--) ...;

.......................................................................

i RN 0; Assign i to r0
N RN 1; Assign N to r1

 MOV N, #9
 MOV i, N
loop
 ; TODO: Loop body should be placed here...

 SUBS i, i, #1
 BGT loop

.......................................................................


(2)
// Loop from 9 to 0

for(i=9; i>=0;i--) ...;
.......................................................................
i RN 0; Assign i to r0
N RN 1; Assign N to r1

 MOV N, #9
 SUBS i, N, #1
loop
 ; TODO: Loop body should be placed here...

 SUBS i, i, #1
 BGE loop
 
(3)
// Loop from 0 to 9 => NOT efficient!
for (i=0; i<10; i++) …;

.......................................................................
i RN 0; Assign i to r0
N RN 1; Assign N to r1

 MOV i, #0  ; i = 0
loop
 ; TODO: Loop body should be placed here...

 ADD i, i, #1
 CMP i, #10
 BCC loop  ;  == BLO   loop  == BLT   loop

이 루틴은 앞서의 (2)번의 예제에 비해 3줄로 1줄이 더 추가되었다. 따라서 이런 비효율적인 방법보다 앞서의 (2)번 예제처럼 Counting down 하는 경우의 예제가 더 바람직하다.


(4)
//DO~WHILE
do
{
   …
}while(--N != 0);

.......................................................................
N RN 1; Assign N to r1

loop
 ; TODO: Loop body should be placed here...

 SUBS N, N, #1
 BNE loop  ;  == BLO   loop
 
[3] Switches on the range 0 <= x <= N

(1)
Switches to the absolute blocks (Position dependent)

switch(x){
 case 0: return method_0();
 case 1: return method_1();
 case 2: return method_2();
 default: return method_d();
}

.......................................................................

x RN 0 ; Assign x to r0

switch_absolute
 CMP x, #3
 LDRLT pc, [pc, x, LSL #2]
 B method_d
 DCD method_0
 DCD method_1
 DCD method_2

.......................................................................


 
(2)
Switches to the relative blocks (Position independent)

switch(x){
 case 0: return method_0();
 case 1: return method_1();
 case 2: return method_2();
 default: return method_d();
}

.......................................................................

x RN 0 ; Assign x to r0

switch_relative
 CMP x, #3
 ADDLT pc, pc, x, LSL #2
 B method_d
 B method_0
 B method_1
 B method_2

.......................................................................


☞ CMP, TST, TEQ에 대한 부연 설명
(1) CMP   r0, r1
“r0–r1”를 한다. “r0-r1”은 내부적으로 “r0 + ~(r1) + 1”로 처리된다.
이 때 “r0 >= r1”이면 “r0 + ~(r1) + 1” 이 overflow를 일으키고 Carry가 발생한다.

(2) TST    r0, r1;   r0 & r1
“r0 & r1”을 한다. 예를 들어 TST r0, #0x10 은 r0 & 0x10을 하여
그 결과가 ‘1’이면 (r0의 4번 비트가 ‘1’이면) Z = 0으로 만든다.
그리고 그 결과가 ‘0’이면 (r0의 4번 비트가 ‘0’이면) Z = 1 로 만든다.

(3) TEQ    r0, r1;   r0 ^ r1
r0 ^ r1을 한다. (^는 XOR)
r0와 r1이 같으면 결과가 0이므로 Z = 1로 만든다.
r0와 r1이 다르면 결과가 1이므로 Z = 0으로 만든다.

CMP 대신 TEQ를 쓰면 C플래그에 영향을 주지 않고 Z플래그 만으로 같은지 아닌지를 판별할 수 있다.


 
☞ Condition Code 표

출처 : http://www.aesop.or.kr

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,