프로그램이 사용하는 함수: 사용자 정의함수, 라이브러리 함수와 커널 함수
사용자 정의함수와 라이브러리 함수는 그 프로그램의 코드 영역에 기계어 명령 형태로 존재하며 프로그램이 실행될 떄에 해당 프로세스의 주소 공간에 포함된다. 또한 함수 호출할 때 자신의 주소 공간에 있는 스택을 사용하게 된다.
커널함수는 커널의 코드에 정의된 함수이며, 시스템 콜 함수와 인터럽트 처리 함수가 포함된다. 커널 함수는 프로그램 주소 공간에 코드가 포함되지 않고 커널의 주소 공간에 코드가 정의된다.
일반적인 함수 호출은 사용자 프로그램 내에 존재하는 코드를 실행하는 것이고, 시스템 콜은 운영체제에게 CPU를 넘겨서 실행하는 것이다.
인터럽트 처리 중 또 다른 인터럽트가 발생하는 경우에는 어떻게 처리되는지에 대해 알아본다.
원칙적으로는 인터럽트 처리 중에 다른 인터럽트가 발생하는 것을 허용하지 않는다고 한다. 왜냐하면 처리 중에 다른 인터럽트를 처리하게 되면 데이터의 일관성이 깨지기 때문이다. 하지만 경우에 따라 예외가 존재하는데, 인터럽트가 발생해 현재 인터럽트 처리루틴을 수행하고 있지만 이보다 더 급하게 CPU를 사용해야할 일이 발생할 수 있다.
즉, 인터럽트마다 각각의 중요도를 갖고 있다. 따라서 낮은 중요도의 인터럽트를 처리하다가 높은 중요도의 인터럽트가 발생했다면 허락을 해줄 수 밖에 없다. 이 처럼 현재 처리 중인 인터럽트보다 더 높은 우선순위의 인터럽트가 발생하면 현재 수행중이던 인터럽트 코드의 수행 지점을 저장하고 더 중요한 인터럽트를 처리하도록 한다. 끝나면 저장된 주소로 복귀해 이전에 수행중이던 인터럽트 코드를 이어서 수행한다.
모든 프로그램은 자신만의 독립적인 주소 공간을 갖고 있고 프로그램이 함수호출을 할 때, 자신의 주소 공간 내에서 호출이 이루어지게 된다. 시스템 콜도 함수호출이긴 하지만 자신의 주소 공간을 거스르는 영역(커널)에 존재하는 함수를 호출하는 것을 말한다.
따라서 시스템 콜은 주소 공간 자체가 다른 곳으로 이동해야 하므로 프로그램 자신이 인터럽트 라인에 인터럽트를 세팅하는 명령을 통해 이루어진다. 프로그램이 스스로 인터럽트 라인을 세팅한다는 점만 다를 뿐, 일반적인 인터럽트 발생과 동일한 방법이다.
프로세스가 시작되어 수행을 완료하기까지 프로세스 자신의 주소 공간에 있는 코드와 커널의 주소 공간에 있는 코드도 실행된다. 프로그램이 사용자 정의 함수와 라이브러리 함수, 입출력 시스템 콜을 통해 커널 함수도 호출해 사용하기 때문이다.
시스템 콜을 사용하는 것이 프로세스의 코드가 아닌 커널의 코드이지만, 시스템 콜이 수행되는 동안 커널이 실행 상태에 있다고 하지 않고 해당 프로세스가 실행 상태에 있다고 말한다. 하지만 이런 상태를 프로세스가 커널모드에서 실행중이라고 구분 지어 이야기할 수 있다.