Computer Science Lectures/Introduction to Computer Systems - CMU

Lecture 07: Machine-Level Programming 3: Procedures

오렌지색 귤 2022. 10. 25. 23:41
반응형

Mechanisms in Procedures

  • Passing Control : 빨간색 화살표와 같이 호출되면 이동했다가 리턴되면 다시 돌아가는
  • Passing data : P에서 정의된 x 값이 Q에 i로 전달되고, 리턴되는 값이 다시 P로 반환되는
  • Memory management : C에서는 반환되면 deallocate
  • x86-64에서는 오버헤드를 많이 줄였다

 

 

Procedures

x86-64 Stack

  • LIFO : Last In First Out

 

x86-64 Stack: Push

x86-64 Stack: Pop

 

 

 

Coding Conventions

Procedure Control Flow

 

 

  • %rip : program counter

 

callq instruction은 아래의 3가지 역할을 한다

  • decrement stack pointer (0x120  ->  0x118)
  • write address of following instruction which will be used after return
  • program counter jump to the address where should be read right next

 

retq instruction

  • increment stack pointer
  • pop up address from stack and put it in program counter

 

 

Procedure Data Flow

  • 6개 레지스터 순서는 외워야 한다
  • 반환값은 %rax에 저장된다
  • 인수가 6개가 넘게되면 메모리의 스택을 활용한다

 

 

  • 2개의 인수는 각각 %rdi, %rsi에 저장된다
  • 반환값은 %rax에 저장된다

 

 

Managing local data

Stack-Based Languages

 

 

Stack Frames

  • procedure은 stack의 Frame에 저장된다
  • Frame의 delimiter는 보통 Stack Pointer(%rsp)와 Base Pointer(%rbp)로 구성된다
  • Base Pointer는 Optional이라서 안쓰이는 경우도 있다
Q. Base Pointer가 안쓰이면 deallocate는 어떻게 하는가?

A. 보통 쓰이지 않는 경우에는 allocate한 바이트 만큼을 deallocate한다.

 

 

 

x86-64/Linux Stack Frame

  • 인수를 7개 이상 사용한다면 Caller Frame에 인수와 리턴할 주소값이 저장된다

 

 

  • x가 리턴되므로 x는 곧 %rax에 저장된다
  • %rax에 저장된 x값이 val값이 저장된 %rsi로 더해지면서 자동으로 이 값은 y가 된다

 

 

  • v1에 값을 할당하고 이어지는 코드에서 v1의 주소를 사용한다
  • 따라서 v1은 레지스터가 아닌 메모리에 저장되어야 한다
  • 이 경우에 %rsp의 값에 16바이트를 차감하고 8바이트를 더한 곳에 15213의 값을 저장한다

 

  • movl 명령어에서 3000은 작은 수라 32bit인 %esi 레지스터를 사용
  • leaq 명령어를 통해 %rsp에 8바이트를 더한 곳의 값을 %rdi에 복사한다

 

  • call incr

 

  • 반환값을 담을 %rax에 incr 결과가 담겨있는 %rsp + 8바이트의 값을 할당
  • addq를 통해 stack을 deallocate

 

 

 

 

Register Saving Conventions

Q. you가 %rdx에 15213을 할당 후 who를 콜하면 %rdx의 값이 유지될 수 있을까?

A. 보통은 불가능하다. who가 다른 값을 %rdx에 overwrite할 수 있다.

 

  • Caller Saved : Caller가 저장했던 값을 call이 호출되기 전에 프레임에 저장해두는 경우
  • Callee Saved : Callee가 해당 값을 사용하기 전에 임시로 저장해뒀다가 반환하기 전에 복구하는 경우

 

 

x86-64 Linux Register Usage

caller saved register
callee saved register

 

 

 

  • x의 값을 미리 저장해두려고 pushq
  • %rsp 16바이트 increment

  • %rsp 16바이트 decrement
  • popq 된 값을 %rbx에 저장

 

 

Illustration of Recursion

Recursive Function

 

Recursive Function Terminal Case

  • %eax에 반환값이 될 수 있는 0 할당
  • je (jump if equal)

 

Recursive Function Register Save

  • 반환전에 %rbx 값을 복구하기 위해 pushq

 

Recursive Function Call Setup

 

 

Recursive Function Call

 

 

Recursive Function Result

 

 

Recursive Function Completion

 

 

 

Observations About Recursion

 

 

 

Summary

 

반응형