4장 프로그램의 구조와 실행
프로그램의 구조와 인터럽트
프로그램 주소 영역은 코드 영역, 데이터 영역, 스택 영역, 힙 영역으로 되어 있고 프로그램 내부 구조는 함수들로 구성되어 있다.
인터럽트의 동작 원리 또한 함수의 호출 과정과 같은 맥락으로, 인터럽트 루틴 수행 후 복귀 주소가 FCB(프로세스 코드 블록)에 저장되어 사용된다.
컴퓨터 시스템의 작동 개요
CPU는 매 시점 메모리의 특정 주소에 존재하는 명령을 수행하는 것이며, 특정 주소를 PC(Program Counter)라는 레지스터에 저장한다.
즉, CPU는 PC가 가리키는 주소에 있는 명령을 수행하는 것이다.
위 사진은 컴퓨터 시스템을 구성하는 하드웨어 구조로 CPU와 메모리, 각 입출력 장치와 컨트롤러, 로컬 버퍼가 있다.
CPU에는 2가지 명령이 있는데 일반명령과 특권명령이 있다. (3장 참고)
CPU는 PC가 가리키는 메모리의 명령만 수행하므로 주변 장치는 CPU의 도움이 필요하다면 인터럽트를 통해 요청한다.
인터럽트를 발생시키기 위해서 주변장치는 인터럽트 라인을 세팅하고, CPU는 매번 명령을 수행한 직후 인터럽트 라인을 체크해 서비스 요청이 있는지 확인한다.
프로그램의 실행
프로그램의 실행은 1. 실행 프로그램이 메모리에 적재된다.
와 2. 프로그램이 CPU를 할당받고 명령을 수행하고 있는 상태
라는 뜻이다.
실행파일이 메모리에 적재될 때는 필요한 부분만 올리고 나머지는 스왑 영역에 파일시스템 형태로 저장된다. (2장)
각각의 프로그램은 코드, 스택, 데이터 영역을 가지고 있으며, 이러한 주소 공간을 가상메모리 또는 논리적 메모리라고 부른다.
운영체제 또한 프로그램이므로 운영체제 커널 또한 코드, 스택, 데이터 영역이 있다.
운영체제의 목적에 따라 커널에는 CPU와 메모리 등의 자원을 효율적으로 관리하는 코드와 사용자 편의를 위한 코드 등이 있다.
커널의 데이터 영역에는 각종 자원을 관리하기 위한 자료구조가 저장된다.
하드웨어 자원 관리를 위한 자료구조와 현재 수행 중인 프로그램을 관리하기 위한 자료구조가 데이터 영역에 있다.
현재 수행 중인 프로그램을 프로세스라고 하며, 커널의 데이터 영역에 각 프로세스의 상태 등을 유지하기 위한 자료구조인 PCB가 있다.
커널의 스택 영역은 현재 수행중인 프로세스 별로 개별적으로 부여된다.
프로그램이 내부 함수를 호출하면 프로그램의 스택 영역에 복귀 주소가 저장되지만, 프로그램에서 시스템 콜을 호출하여 운영체제의 코드가 실행되는 중에 함수 호출이 발생하면 커널의 스택을 사용하게 된다.
다만, 프로그램에서 시스템 콜이나 인터럽트로 운영체제로 CPU 권한이 넘어가는 순간에는 프로그램의 복귀 주소가 PCB에 저장된다. (3장 인터럽트 핸들링 참조)
사용자 프로그램이 사용하는 함수
프로그램이 사용하는 함수는 크게 사용자 정의 함수, 라이브러리 함수, 커널 함수가 있다.
앞의 2가지는 프로그램 내부의 코드 영역에 기계어 명령 형태로 존재한다.
커널 함수는 시스템 콜 함수나 인터럽트 함수가 있으며, 커널 함수는 운영체제의 커널의 주소 공간에 코드가 정의된다.
예를 들면, printf 함수는 라이브러리 함수이지만 입출력 연산을 수행하므로 내부적으로는 커널 함수가 사용된다.
커널 함수 예로는 read와 write가 있다.
인터럽트
CPU는 매번 프로그램 카운터 (PC)가 가리키는 메모리에 있는 명령을 수행하고 나서 항상 인터럽트 라인을 확인하여 인터럽트가 있는지 확인한다.
인터럽트가 발생하면 현재 수행하던 프로세스를 멈추고 인터럽트를 처리하고 나서 PCB에 저장해두었던 주소(실행 중이던 프로세스)로 복귀한다.
만약 인터럽트 처리 중 또 다른 인터럽트 발생 시 어떻게 처리되는가?
원칙적으로는 허용하지 않는데, 왜냐하면 데이터의 일관성이 유지되지 않는 문제가 발생하기 때문이다.
인터럽트를 처리 중 데이터를 변경하는 도중 또 다른 인터럽트가 발생해 그 인터럽트를 처리하게 되면 또 다시 데이터가 변경되어 원래 의도하지 않은 결과값이 될 수 있다.
그러나 인터럽트마다 중요도가 다르므로 더 시급한 인터럽트가 발생하면 예외적으로 허용해줄 필요가 있다.
결론은, 현재 처리중인 인터럽트보다 더 높은 우선순위의 인터럽트가 발생하면 현재 처리하던 인터럽트의 수행 지점을 저장하고 우선순위가 높은 인터럽트를 처리한 뒤, 저장한 주소로 복귀하여 재개한다.
시스템 콜
시스템 콜은 커널 함수를 호출하는 것이다.
프로그램 자신이 인터럽트 라인에 인터럽트를 세팅하면, CPU는 매 시점 명령을 수행하기 전에 인터럽트 라인을 봐야 하므로 인터럽트가 있으면 여태 배웠던 대로 PCB에 복귀 주소를 저장하고 인터럽트를 수행한다.
입출력 연산을 수행하는 속도는 CPU의 수행 속도에 비해 상대적으로 느리므로 이 시간엔 CPU가 필요한 다른 프로그램에게 CPU 권한을 이양하고, 인터럽트 작업을 마치면 작업을 한 컨트롤러에서 인터럽트를 통해 CPU에게 알리면, CPU 제어권을 다시 원래 프로그램에게 돌려준다.
프로세스의 두 가지 실행 상태
프로세스가 실행 중일 때, 2가지의 상태로 구분이 된다.
바로 사용자모드에서의 실행 상태(user mode running)과 커널 모드에서의 실행 상태(kernel mode running)이다.
주의점은 사용자 코드에서 시스템 콜을 통해 커널의 코드가 실행되지만, 이 때 커널의 실행 상태라 하지 않고 ‘프로세스가 커널모드에서 실행 중’ 즉, 프로세스가 실행 상태에 있다고 말한다.