x86-64 호출 규약 (Calling Convention)

이 부분은 리눅스 기반 64비트(x86-64) 환경에서 함수 호출 규약을 요약한 것. 간단하게 설명하기 위해 일부 세부 사항은 생략되었음. 더 자세한 내용은 System V AMD64 ABI 문서를 참고

호출 규약은 다음과 같이 동작 :

  1. 사용자 수준 애플리케이션은 인자를 레지스터 순서대로 전달 :

    %rdi, %rsi, %rdx, %rcx, %r8, %r9

  2. 호출자(caller)는 **자신의 다음 명령어 주소(리턴 주소)**를 스택에 푸시한 뒤, 피호출자(callee)의 첫 번째 명령어로 점프 :

    CALL 명령어가 이 두 동작을 동시에 수행

  3. 피호출자(callee)가 실행됨

  4. 만약 피호출자가 반환 값을 가지면, 그것은 RAX 레지스터에 저장

  5. 피호출자는 스택에서 반환 주소를 꺼내서, RET 명령어로 해당 위치로 점프하며 복귀

예시 : f(1,2,3)

프로그램 시작 과정 (Program Startup Details)

Pintos의 사용자 프로그램 라이브러리(lib/user/entry.c)는 _start() 함수를 **프로그램 진입점(entry point)**으로 지정

_start()main()을 호출하고, 만약 main()이 반환되면 자동으로 exit()를 호출 :

void
_start (int argc, char *argv[]) {
    exit (main (argc, argv));
}

즉, 커널은 사용자 프로그램이 시작되기 전에 레지스터에 인자를 적절히 세팅 필요. 이 인자 전달 규칙은 일반적인 함수 호출 규약과 동일하게 적용

예시: /bin/ls -l foo bar

처리 과정

  1. 명령어를 공백 기준으로 분리