Suhwanc

 

본 포스팅에서는 sp(stack pointer)를 이용해
항상 .data 밑에다가 자잘하게 써왔던 버퍼를 대체하는 것을 보여드립니다!

 

 

1. 기존 버퍼 코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@ suhwan++20201108
system call test
 
.text
_start: .global _start
 
@ sys_read (fd, pstr, len);
@            r0   r1  r2
    mov r0, #0      @ fd <- stdin
    ldr r1, =buf    @ r1 = buffer(4 bytes)
    mov r2, #4      @ len <- 4
    mov r7, #3      @ syscall <- sys_read
    swi 0           @ system call
 
lf: .byte '\n'
.data
.align
msg:
    buf: .skip 4
.end
cs

 

-> 간단한 4바이트 입력 코드입니다.

 

2. 스택을 사용한 코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@ suhwan++20201108
system call test
 
.text
_start: .global _start
 
@ sys_read (fd, pstr, len);
@            r0   r1  r2
    mov r0, #0      @ fd <- stdin
    sub sp, sp, #4
    mov r1, sp
    mov r2, #4      @ len <- 4
    mov r7, #3      @ syscall <- sys_read
    swi 0           @ system call
    add sp, sp, #4
.end
cs

 

  • line 10) sub sp, sp, #4 -> 공간을 만들기 위해 스택 포인터를 4바이트 빼줍니다.
  • line 11) mov r1, sp -> r1 레지스터에 스택 포인터가 담고있는 주소를 대입합니다. 이는 4바이트 버퍼를 r1 레지스터가 로드(ldr)한 것과 동일한 효과를 가져옵니다.
  • line 15) add sp, sp, #4 -> 아까 뺀 스택 포인터를 다시 더해줍니다. (스택에 뭐가 더 들어있는지 모르니 꼭 원상복구 해줍시다!)

 

 

음.. 방법은 알겠는데 대체 왜 쓰나요?

라이브러리처럼 여러 object file들을 하나로 묶을 때
밑에 버퍼가 있으면 이들도 모두 묶어서 써야하기 때문에 전역변수가 되어버립니다.

 

라이브러리는 수 많은 파일을 묶어버리기 때문에 그에 따라오는 전역변수도 엄청 많아질 것이고

그렇게 되면, 메모리 오버헤드가 발생할 수 있고, 링커가 해야할 일들이 많아지게 되기 때문에

가급적이면 레지스터와 스택을 이용하는 것이 효율적입니다.

'System Programming(ARM)' 카테고리의 다른 글

[ARM] Signal Handling  (0) 2020.12.03
10. Signals  (0) 2020.12.03
[ARM] 디버깅하는 법  (0) 2020.11.08
[ARM] 반복문으로 문자열 출력하기  (0) 2020.11.08
[ARM] System Call 정리  (0) 2020.11.08