1.2. Context Change and Stack Handling

프로세서는 인터럽트가 걸려오면, 그때 수행하던 프로그램의 실행을 잠시 중단하고 인터럽트 핸들러를 수행한 후 다시 인터럽트가 걸리기 전에 수행하던 프로그램의 실행 흐름으로 돌아와야 한다. 그렇게 하기 위해서 인터럽트 핸들러의 코드로 점프하기 전에 프로세서는 하드웨어적으로 프로그램의 context 를 저장하는 작업을 한다. 마치 'call' 어셈블리 인스트럭션을 수행하는 것과 비슷한 동작을 하게 된다.

인터럽트가 걸려오면, 프로세서는 EFLAGS, CS, EIP 레지스터를 스택에 저장한다. 그 중, CS 와 EIP 레지스터의 값들은 인터럽트 핸들링이 완료된 후에 다시 리턴해서 돌아올 곳의 instruction pointer 의 역할을 하게 된다.

만약, 인터럽트 벡터가 가리키는 IDT 의 엔트리가 현재 수행되는 프로그램보다 더 낮은 dpl(descriptor privilege level) [1] 을 가지면, 즉, 보다 높은 권한을 가지는 경우에는 스택 스위칭이 일어난다. 스택 스위치가 일어나게 되면, 핸들러가 수행을 완료하고, 리턴해야 할 코드가 사용하던 스택의 주소에 대한 정보 또한 스택에 저장되게 된다. 이 경우에는 먼저 스택 체인지가 일어나고, SS, ESP 가 체인지된 스택, 즉, 핸들러의 스택에 저장되고, 그 후 EFLAGS, CS, EIP 가 핸들러의 스택에 저장되게 된다. 다음 그림을 보면 스택의 사용을 명확하게 알 수 있다 :

그림 1-4. Stack usage with NO Privilege level change

위의 그림은 DPL 의 변경이 없는 경우의 인터럽트 핸들러 게이트 호출시 스택의 모양이며, 아래의 그림은 DPL 의 변경으로 인한 Stack change 가 있을 경우의 인터럽트 핸들러 게이트 호출시의 스택의 모양이다.

그림 1-5. Stack usage with Privilege level change

주석

[1]

DPL, Descriptor Privilege Level, 디스크립터에 의해 기술되어지는 세그먼트 혹은 gate 의 privilege level. 세그먼트 디스크립터 혹은 gate 디스크립터의 DPL 필드에 기록된다. 0 에서 3 까지의 값을 가질 수 있음. 리눅스는 0 과 3 두개의 값만 사용함. DPL 은 디스크립터에 의해서 기술되어지는 세그먼트로의 접근(access)을 컨트롤 한다. 즉, 해당 세그먼트에 접근할 수 있는 권한 레벨(privilege level) 을 정의한다. 예를 들어, 2 의 DPL 을 가지는 디스크립터에 의해 기술되어지는 세그먼트에 접근하기 위해서는 프로세서가 0, 1, 혹은 2 의 privilege level 에서 동작하고 있어야 한다. 실은, DPL 이 어떤 종류의 디스크립터에 있는가에 따라서 DPL 값은 다르게 해석되지만, 자세한 것은 인텔의 매뉴얼을 참조하도록 한다 : Intel Architecture Software developer's Manual Vol.3, pp.4-8 to 4-9