☑️ 운영체제 영상 보기
☑️ 운영체제 블로그 보기
☑️ 토요일 저녁 : CSAPP 3.7절 발표
☑️ 월요일 점심 먹고 : 동적 프로그래밍 발표
☑️ 화요일 점심 먹고 : Knapsack Problem 발표
프로시저는 명령 모음으로 이해하면 된다.
함수, 메소드, 서브루틴, 핸들러 등등이 전부 프로시저라고 할 수 있다.
프로시저가 실행될 때 제어권 전달, 데이터 전달, 메모리 할당과 반납 등이 필요하다.
오버헤드 : 명령을 처리하기 위한 작업들에 필요한 자원
레지스터에 다 안 들어가면 스택에 공간 할당. 이걸 스택 프레임이라고 부름.
일반적인 스택 프레임은 함수 인자 전달, 지역 변수 저장, 리턴 정보 저장 등의 역할을 한다.
항상 다 쓰는 건 아니고 인자 적으면 레지스터에만 전달. 심지어 대부분의 함수들은 스택 프레임을 요청하지도 않음.
아래가 스택 top이다.
스택에 차곡차곡 필요한 정보를 쌓아놓은 그림이다.
함수 P 실행 중간에 함수 Q를 실행해야 한다고 해보자.
함수 P에서 함수 Q로 제어권을 넘겨준 뒤에 다시 P를 실행해야될 때,
P를 어디서부터 다시 시작해야할지 적힌 위치가 필요하다. 이걸 리턴 주소라고 한다.
리턴 주소도 스택에 넣는다.
x86-64 머신에선 call Q
로 프로시저 Q를 호출해서 기록한다고 한다.
call Q
명령어는 2가지 일을 함.
ret
명령어는 리턴 주소를 스택에서 꺼내와서 P로 돌아간다. (프로그램 카운터를 P 주소로 세팅한다)
리턴할 때 이전 프로시저로 되돌아가기만 하는게 아니라 함수 매개변수같은 값을 전달하기도 한다.
대부분의 전달은 레지스터를 통해서 일어난다.
x86-64에서는 함수 인자 여섯 개까지는 레지스터로 전달됨.
여섯 개 넘어가면 스택으로 전달됨.
사실 책에 있는 대부분의 프로시저들은 레지스터 말고 다른 곳에 데이터 저장할 필요 없음.
메모리에 저장해야될 경우는 다음과 같음
일반적으로 프로시저는 지역 변수를 할당하기 위해 스택 포인터를 감소시켜서 스택 프레임에 공간을 할당함.
(원래 스택이 높은 메모리 주소에서 시작해서 데이터 늘어나면 낮은 메모리 주소까지 할당함.)
함수 인자나 지역 변수가 많은 함수 어셈블리 뜯어보면
함수 호출 준비를 위해서 스택에 저장공간 할당하는 데에 명령어가 많이 쓰이는 걸 알 수 있음.
CPU에 들어있는 레지스터들은 모든 프로시저들이 같이 사용하는 단일 자원임.
잠깐 다른 프로시저 실행할 수도 있긴 한데,
나중에 다시 써야 되는 레지스터 값을 덮어쓰지는 않는다.
함수 A 안에 있는 함수 B에 매개 변수 넣었을 때,
그 매개 변수가 B에서 뭔 짓을 당해서 어떻게 변하든
A로 다시 돌아오면 값은 그대로여야 한다.
그래서 그런 변수 값들은 스택에 따로 넣어서
겹치지 않게 한다.
재귀 호출 할 때 각 프로시저들은 스택에 자신만의 저장 공간을 갖는다.
그래서 지역 변수들이 서로 간섭하지 않는다.