※ procedure 목차

1. 스택의 구조

2. 호출의 관습

  - 제어의 전달

  - 데이터의 전달

  - 지역 데이터의 관리

3. 재귀실행

 

§ Procedure 소개

프로시저(procedure)는  특정 작업을 수행하는 서브 프로그램으로 자주 사용하기 위해 생성하는 메서드 같은 것이다.

이런 프로시저의 실행에는 3가지 유형이 있다.

 

§ 프로시저 실행의 유형 (모든 동작은 기계어로 구현된다.)

1. 제어의 전달

  ▷ 프로시저 코드의 시작부분으로 리턴지점으로 돌아간다.

2. 데이터의 전달

  ▷ 프로시저 인자

  ▷ return 값

3. 메모리 관리

  ▷ 프로시저 실행 중 할당하며 return시 반환한다.

 

 

 

 

 

 

 

※ procedure _ 2. 호출의 관습

§ x86-64 스택

- 메모리 영역으로 register %rsp는 가장 작은 스택주소를 저장.

 

 

 

 

§ procedure 제어흐름

▶ procedure 호출

stack frame을 이용해 procedure호출과 return을 지원하며 아래와 같은 호출 방법을 사용한다.

call Label

- Step 1: return 주소를 stack에 push

- Step 2: Label로 jump

cf) return 주소란?
call 바로 다음 줄의 명령어 주소로 아래 예시를 들자면, 400549가 바로 return 주소이다.

400544:  callq  400550  <mult2>
400549:  mov  %rax,  (%rbx)

 

▶ procedure 반환

stack frame을 이용해 procedure반환을 진행하는데, stack에서 return주소의 pop을 진행하며 아래와 같은 방법 사용하며, 이 return 주소로 jump한다는 의미이다.

ret

 

 

 

 

 

§ procedure 데이터의 흐름

이때, Stack Frame은 필요할 때에만 할당한다.

 

 

 

§ procedure 지역 데이터의 관리

▶ Stack Frame 기반 언어 = 재귀호출을 지원하는 언어로 C, Java와 같은 언어들을 예시로 들 수 있다.

- "Reentrant", 즉 재진입해야하는 코드로 각 실행개체의 상태를 저장할 장소가 필요하기 때문이다.

 

Ex. Recursion의 Stack Frame

 

 

▶ x86-64 / Linux 의 Stack Frame 

 

Ex-1).  incr 함수

 

Ex-2).  incr 함수

- incr #1

subq	$16,  %rsp         #rsp-16 = stack이 커진다 = stack frame할당으로 공간확보
movq	$15213,  8(%rsp)   #15213을 v1에 copy

- incr #2

movl	$3000,  %esi         # rsi에 3000을 넣음
leaq	8(%rsp), %rdi        # rdi에 주소 할당

- incr #3  (15213 + 3000을 더해 18213값이 들어감)

 

- incr #4

addq	8(%rsp),  %rax         # 현재 incr의 return값 rax는 v2에 저장되어 있어서 v1+v2를 다음과 같이 진행
addq	$16, %rsp              # pop을 진행

 

 

 

 

▶ register 보관관습 => stack frame에 필요한 register를 push해 저장함

- 똑같은 register를 다른 함수에서 사용가능해서 return 후 다시 register를 복원한다.

- 아래 예시를 보면 두 개 모두 %rdx라는 중복된 register를 사용한다.

 

때문에 compiler에 따라 다음 2가지 방식으로 구현할 수 있다.

 

 

 

 

 

 

§ 재귀 실행

Ex)

/*-----------Recursive popcount-----------*/
long pcount_r (unsigned long x) {
    if (x == 0)
        return 0;
    else
        return (x & 1) + pcount_r(x >> 1);
}

 

 

 

 

 

 

 

 

 

+ Recent posts