System Programming(ARM)

[ARM] 반복문으로 문자열 출력하기

suhwanc 2020. 11. 8. 04:31

 

이번엔 미리 버퍼에 저장해둔 문자열을 출력해봅시다!

 

순서는 다음과 같습니다.

 

1) 문자열의 주소(맨 앞 포인터)를 레지스터에 담습니다.(adr 명령어 사용)

2) 포인터를 하나씩 증가시키면서 바이트 단위로 로드해서 출력합니다.

3) 위 과정을 문장이 끝날 때까지 반복합니다.

 

소스 코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@ suhwan++20201108
@ write sentence
 
.text
_start: .global _start
 
    adr r3, msg     @ r3 <- msg
    mov r4, #0      @ r4 <- idx
    mov r5, #1
loop:
    cmp r5, #0      @ if r5 == 0 -> exit
    beq exit
    mov r0, #1
    add r1, r3, r4  @ r1 <- for(int i=0; i<msg.size(); i++)
    mov r2, #1      @ r2 <- len
    mov r7, #4
    swi 0
 
    add r4, r4, #1
    ldrb r5, [r1]   @ r5 <- msg[r1]
    bne loop
exit:
    mov r0, #0
    mov r7, #1
    swi 0
    .align
msg:
    .asciz "Hello, World!\n"
.end
cs

 

line 7) adr r3, msg -> r3 레지스터에 문자열 msg의 포인터 주소를 담습니다.

line 11) cmp r5, #0 -> 한 글자씩 불러 담은 r5 값이 0과 같다면 종료합니다. (왜 그런지 밑에 설명)

line 14~20) 주석에 써둔 것 처럼, 이 줄의 과정은 c언어에서의 for 문과 동일합니다.

14번째 줄에서, r3는 항상 msg의 첫번째 (msg[0])을 가리키고 있고, 항상 바뀌는 건 r4입니다.

19번째 줄은 i++을 의미합니다.

20번째 줄은 msg[i]를 r5 레지스터에 저장하는 것과 같습니다. 한 글자가 바이트 단위이기 때문에 반드시 ldrb를 사용해주어야 합니다.

 

line 28) .asciz로 문자열을 선언하였습니다. asciz의 "z"는 zero를 의미하며, 문자열 맨 뒤에 0이 붙는다는 의미입니다.

이 표현은 line 11에서 문자열 끝을 나타내는 의미로 유용하게 쓰입니다!