제 목 : 인터럽트에 대해서
작성자: 캠퍼스 C
출 처 : 나우누리
U R L : http://explore.kwangwoon.ac.kr/~k98el560
기 타 : 여기에 게재되는 모든 글들은 이미 작성자의 동의를 얻은 것이기
        때문에 상업적 목적이 없는 한 출처(이 홈페이지)를 밝히고 다른
        곳에 게재할 수 있습니다.
======================================================================
*******************************************************************
<중급>                  < 캠퍼스 C >                            4회
*************************<  목 차  >*******************************
<1> 인터럽트(interrupt)의 개념
<2> 인터럽트(interrupt)와 폴링(polling)
<3> 인터럽트 벡터 테이블(vector table)을 확인하자
<4> 인터럽트의 종류
<5> 인터럽트를 위한 하드웨어의 구현(IBM-PC 에서)
<6> 하드웨어 인터럽트의 순서.
<7> C 에서 제공하는 인터럽트 함수 (turbo C 에서)
<8> 인터럽트의 작동을 눈으로 확인해 보자.
<9> 인터럽트를 이용하여 시계를 만들어 보자
************************< 내용 시작 >******************************
<1> 인터럽트(interrupt)의 개념
-------------------------------------------------------------------
        영어로 "inter" 라는 의미는 "중간에, 사이에서" 라는 뜻이다.
그래서 잘아시다시피, 농구에서 패스하는 공을  가로채는 것을 "인터셉트
(intercept)" 라고 한다.
        마찬가지로 지금 우리가 공부하려는 "인터럽트(interrupt)"도
"중간(inter)에서 탁 깨뜨려서(rupt) 흐름을 바꿔 놓는다"는 뜻이다.
        지금 이 강좌를  듣는 분 중에는 나름대로 C의  기초를 공부하고
온 분들이겠지만 컴퓨터안에 "흐름"이 있다는 것을 모두  알고 있는지
궁금하다.
        그 흐름이란 80x86  CPU내부에 있는 "IP" 라는  레지스터의 값의
변화를 말한다.
        IP 하니까 생각나는게  있다. 천리안,하이텔  같은  회사에 근무
하는 분들은 이 IP란 용어를 참 많이 사용한다.
        "저 사람 IP 야"
글쎄 "JP" 라면 누군지 금새 알 것도 같은데 "IP"는 누군지 잘모르겠다.
          여기서 얘기하는 "IP"란  (Information Provider)란 뜻으로 "
정보를 제공하는 사람"이라는 뜻이다. 이를테면  사주팔자 같은 데이타베
이스를 천리안,나우콤같은 업체에 제공하는 사람들이 "IP"인 것이다.
        그러나 지금  우리가 얘기하는, (똑같은 이름의)  "레지스터 IP"
는 (내가 보기엔) 그것보다 훨씬 더 중요한 의미를 가지고 있다. 여러분이
소위 "프로그램을 배우겠다"는 사람이면 이 IP의 흐름을 손바닥 보듯이
훤하게 보고 있어야만 한다. 그것은 마치 "혈액 순환계"를 공부하는 의사
들이, "심장에서 나온 피가 어디로 돌고 있는지"를 훤하게 알고 있어야 하는
것과 마찬가지이다.
        IP 는 (Instruction Pointer)의  준말이다. C 기초 강좌에서
"포인터"를 공부한  사람이라면 이 레지스터의 내부에 들어갈  값 (예를
들면 0x1234 따위)가 무엇을 의미하는지 짐작이 가실 것이다.
        이 IP의 역할은,  "다음번에 수행해야 할 명령어의  번지수를 가
리키는것"이다. 이 강좌는 그래도 "중급강좌"인데  이런 자질구레한 얘기
를 쓸 필요가 있는지 잘 모르겠지만, 그래도 혹시나 하는 마음에 적어본다
        이  IP의 기능을 생생하게 느끼실려면 "국민은행"에 가보시면 잘
알 수 있다.  지방 국민은행에도 이런 시스템이  되있는지 잘  모르겠지만
국민은행에서 일처리를 하려면  들어가자마자 무조건 "대기번호" 표를 뽑고
전광판에 내 번호가 나타나기를 "멍하니" 서서(혹은 앉아서) 기다려야 된다.
        수시로  "띵동" 하는  소리와  함께  전광판의 숫자는  39,  40,
41,42, 하는 식으로  증가한다. 두말할 것도 없이 "39번  손님 앞으로.."
하는 안내이다.
        IP의 역할도 전광판과 똑같다. IP가  현재 "0x0039"를 가지고 있
으면 그 주소에 있는 코드를 읽어다가 수행을  한다는 뜻이다. 그리고 이
연산이  끝나면 IP의  값은 역시  "자동적"으로 증가  된다. 즉  0x0039,
0x0041 하는식이다.(여기서는 꼭 1씩 증가 하지는 않음).
        인터럽트의 개념은  이렇다. 지금 전광판이 38번을  가리키고 있
다. 그리고 다음이 내 번호인 39가  될 차례이다. 그런데 갑자기  번호가
999번으로 바뀐다. 그러더니  뒤에 앉은 더 높은 은행원이  "999번" 표를
흔들며 나타나서 먼저 돈을 찾아간다.  "아니 뭐  저런 x가 다있어 ? "하
고 항의를 하려는 순간, 이제서야 전광판에 내 번호인 39번이 나타난다.
        아시다시피 이것은  일종의 새치기에  해당한다. 그러나  이것이
실제로 컴퓨터  내부에서 일어나고 있는  인터럽트의 기본 개념이다.  왜
정직한 컴퓨터가 이런 새치기를 허용하는지,  의문을  갖는 분도 있을 것
이다.
      그러나 알고 봤더니 999번의 은행원이  찾아간 돈은 급한 응급환자
의 수술비 라고 한다...
        이런 기본적인  인터럽트의 개념 외에  반드시 알아야 할  것은,
"인터럽트는  nesting(중첩)도 허용된다"는 사실이다.  이런 설명을 위해
서 아래에 (중급 독자를 실망시킬 지 모르는) 유치한 예를 들었다.
        예를 들면, 지금  "이 팔육" 이라는 학생이 고등학교 2  학년 이
라고 치고, 같은  반 친구와 "야구 얘기"를 나누고 있다고  하자. 그런데
갑자기 3 학년 학생이 말을 걸어오면 "이  팔육"은 일단 친구와의 얘기를
잠시 중단하고 선배인 3학년하고 얘기를 시작 해야 한다.
        그러는 도중에 갑자기  선생님이 말을 걸어 온다면  여러분은 어
떻게 할 것인가  ? 정신 나간 학생이 아닌 다음에야  당연히 하던 얘기를
멈추고 선생님과 얘기를 시작 할 것이다.
<문제>  그러다 이번엔 교장 선생님이 말을 걸어오면 ?
        위의 문제는  "완전히" 정신 나간  문제인것 같다. 이런  당연한
문제는 낼 필요가 없는 것 같은데, 나온김에 하나만 더 내보자.
<문제> 교장 선생님과  하던 얘기가 끝이났다. 이번엔 누구와  다시 얘기
를 나누어야 하나 ?
        역시 이 문제도 정신이 나간  문제인데, 당연히 선생님과 얘기를
한다. 그러다 또 선생님과 얘기가 끝나면 다시  3 학년 학생과 얘기를 한
다. 그리고 또  3학년 학생과 얘기가 끝나면 이제 비로소  2 학년 친구와
하던 "야구 얘기"를 계속 할 수 있다.
        하두 인터럽트가 많이  걸려서 "이 팔육"은 잠시  생각을 해봐야
할 것이다. "몇회전 까지 공을 던졌던가 ?"를...
        나중에도 자세히  나오겠지만, 이런 "문맥(context) 전환"을  위한
노력은 실제로 컴퓨터 안에서도 똑같이 일어나고 있다.
        그런데 이 순간, 갑자기 1 학년 후배가  "잠깐만 !"을 외치며 말
을 걸어 온다면 여러분은 어떻게 할 것인가 ?
        이런 때 그  사람의 인간성이 드러날 것 같은데,  나같으면 대꾸
없이 주먹을 한방 날릴 것 같다. "조용히 해, 너마저 인터럽트냐 ? "
        그러나 컴퓨터의  CPU "이 팔육(80286)"은  (착하게도) 때리지는
않지만 아무런 대꾸를 하지 않은 채 , 친구와 하던 얘기를 계속한다.
        이런 예가 "인터럽트의 nesting(중첩)"에  대한 실제적인 개념이
다.   여기서, 위 등장  인물들의 "인터럽트 우선순위"를 높은  순서대로
적어보면 다음과 같다.
   교장 선생님 --> 선생님--> 3학년   --> 2학년 친구  --> 1학년
        컴퓨터 내부에서도 이런 우선 순위를  가지고 있는 것은 똑같다.
그럼 이제 문제를 하나 더 내보자.
<문제>  "이 팔육" 학생이 "하드 디스크 C"와  얘기를 나누고 있다. 그런
데 갑자기  "프린터" 가 얘기를 걸어  온다면, "이 팔육"은  주먹을 날릴
것인가 ?  아니면 하던 얘기를 멈추고 프린터와 애기를 시작할 것인가 ?
        이 문제를 틀린 사람도 역시 정신 나간  사람에 해당 하는데, 여
러분 중에 과연 몇 명이나 정신이 멀쩡한지 모르겠다.
*******************************************************************
<2> 인터럽트(interrupt)와 폴링(polling)
*******************************************************************
        인터럽트의 나머지 내용을  더 공부하기 전에 먼저  상식으로 알
아 두어야 할 것이 있다.
        컴퓨터 용어로 "폴링(polling)" 이라는 용어가  있다. 이 단어는
굳이 프로그래머가 알아야  할 필요가 있는 것은 아니다.  주로 하드웨어
를 디자인 하는  사람들이 여러가지 칩들을 가지고 사용할 때  자주 등장
하는 용어이기 때문이다.
        그럼에도 불구하고 굳이 이 용어에  대해서 이야기를 하는 것은,
마치 "홀쭉이와 뚱뚱이"란 용어가 서로의 개념을  더욱 명확하게 보여 주
듯이, "인터럽트 와  폴링"이 서로의 개념의 차이를 더욱  분명히 보여주
기 때문이다.
        poll이란 용어는, 아시다시피 "투표,  투표하다"라는 뜻이다. 그
러나 전산 용어가  많이 그렇듯이 이런 용어로는 정확한 뜻을  알기 어렵
다. 내가 가지고  있는 영어사전은 오래되서 그런지 [전산]에  관한 의미
는 아예 없는데, 다행히 아래한글 2.5에  속한 영어사전에서는 그 의미가
실려있다. 그런데...
        적어도 유명한 사전에  실린 해설이니까  엉터리  일리는 없는데
나로서는 무슨 의도로 이렇게 적어놨는지 도저히 알기가 어렵다.
poll : (신호, 스위치) 장치로 단말기기에 송신하도록 작용하다.
polling :  특정 단말을 지정하고  그 국(한자로 방송국 할때의  "국")이
          송신하도록 권유하는 과정
        컴퓨터 내부에서는  CPU가 "인터럽트 방식"으로  일을 한다.  즉
CPU의 역할은, 어느  한가지의 주변 기기만 상대하는 것이  아니다. 마치
대통령의 임무와 비슷하게,  일이 없다면 그냥 놀고 있다가 갑자기   "누
가 키보드를 눌렀습니다"(하드웨어 인터럽트에  해당함)라고 인터럽트 전
령이 연락을 하면, "음 읽어봐라" 하고 처리해준다.
        또 놀다가 "프린터가 데이타  보내랍니다"(역시 하드웨어 인터럽
트에 해당) 하면 역시 "음 보내줘라" 하고 처리를 하는 식이다.
        이에 비해 "폴링"이란  것은 마치 대통령이 길거리를  걸어갈 때
호위하는 경호원들의  역할과 비슷하다. 즉  한시도 감시를 늦추지  않고
주위를 두리번 거리며 살핀다(이것이 polling(폴링)임).  따라서 혹시 괴
한이 총을 뽑는 경우가 있으면, 경호원은 누구의  연락도 받지 않고 즉각
자기가 알 수 있다.
        하나 더 예를  들면, 영화에서 흔히 보는 것 같이,  교도소 담벽
에 누가  붙은 놈이 없나하고 왔다갔다  하는  "서치 라이트"  의 불빛과
같다. 즉  한시도 쉬지 않고 "한  가지 임무"만을 위해서 일을  하는 것,
이것이 폴링이라는 개념이다.
        이미 여러분이  짐작하시다시피 폴링  기능을 하는 것은  컴퓨터
중에서도 "변방"의 단순 기능을 하는 장치들에 흔히 있다.
        그중에서도 가장 대표적인  것이 키보드 내부에 있는 8048 이라는
 "원 칩 (one chip) 마이크로 프로세서"이다.  원 칩 마이크로 프로세서는
간단히 얘기해서, "CPU +  RAM + ROM"을 하나의 칩 안에  전부 갖고 있는
것을 얘기한다.
        아마 세월이 좀 지나면 지금  우리가 쓰는 386컴퓨터, 486컴퓨터
정도의 기능을 하는 one chip 마이크로프로세서가  나올 것이다. 그 정도
쯤 되면  아마 "터미네이터(T2)"의 몸속에  넣어주고 쓸 만할 정도가  될
지도 모른다.  하지만 현재는 그렇게 막강한  기능을 갖는 것은  없는 것
같고 거의 장난감 수준이다. 하지만,  그래도  냉장고, 세탁기 정도의 자
동화를 위해서는 충분히 쓰일 수 있는 정도이다.
        이런 원칩  마이크로 프로세서가  우리의 키보드 안쪽에  장착이
되있는 것이다.(앞으로 기회가 되면 그림 파일로  보여드리겠고) 그리고
그 칩은 항상  폴링을 하고 있다. "인간이 키 자판을  누르나 안누르나를
항상 살피면서..."
        ---------------------------------------------------------
<참조>  (앞으로 이런 곳에서 같이 보내는 "그림 파일"을 참조하세요)
        ----------------------------------------------------------
        이와같이 "인터럽트 와 폴링"이라는 개념을  비교하면서 이해 하
시기를 바란다.
<숙제> 자신 있는 사람은 키보드를 뜯어보고  눈으로 직접 8042라는 칩을
        확인하세요 (반드시 전원을 내리고)
<숙제> 컴퓨터를 켠 상태에서 여러분 눈앞에  있는 키보드를 보고 8042가
        "폴링"하고 있는 것을 느껴 보세요.
        (서치 라이트 불빛이 왔다갔다 하듯이...)
*******************************************************************
<3> 인터럽트 벡터 테이블(vector table)을 알자
*******************************************************************
        현재 IBM-PC 에서는 256개의 인터럽트를  허용하고 있다. 그리고
각각의 인터럽트가 걸리면, 그에 해당하는 일을  하는 루틴이 있는데, 우
리는 그것을 "인터럽트 핸들러(interrupt handler)"라고 부르고 있다.
즉, 인터럽트가  걸리면 그  일을 처리(handle)하는 프로그램을  말한다.
이 인터럽트 핸들러라는  프로그램은 ROM BIOS 안에 어셈블러로  짜여 있
기도하고, DOS 안에도 있고, 우리가 직접 짤 수도 있다.
        이 각각의 인터럽트 핸들러의 시작 번지를  모아 놓은 것을 우리
는 "인터럽트  벡터 테이블(interrupt  vector table)"이라고 부르고  있
다.
        이 인터럽트 벡터  테이블을 직접 살펴보기 전에  상식으로 알아
야 할 것은 다음과 같다.
        1. 각 핸들러의 주소는 총 4바이트로 이루어져 있다.
            -> 세그먼트(2바이트) + 오프셋(2바이트) = 4 바이트
                예) 0x1234 : 0x5678
        2. IBM-PC 에서는, 메모리에 각 주소가 뒤집어져서 들어간다
             -> 이걸 "역 word" 방식이라고 부르며,  x1234  : 0x5678인
               값이  0번지부터 메모리에 들어가는 모습은 다음과 같다.
                78     56     34     12
                --     --     --     --
                0번지  1번지  2번지  3 번지
        3. "인터럽트 벡터 테이블"은 메모리의 절대번지
                --------------------------------
                0x0000 : 0x0000부터 할당되 있다.
                --------------------------------
        4. 벡터 테이블의 총 크기는 1K의 메모리 size이다.
                총 인터럽트 벡터 수 :   256개
                크기                :     4 바이트
                ---------------------------------------
                                        1024 바이트
<숙제> 디버거(debugger)의  덤프 명령(d)를 이용하여 인터럽트  벡터 테
        이블을 프린트하고 책상앞에 붙여 놓으세요.(총 1K 만큼)
<숙제> 디버거(debugger)를  이용하여 실제  메모리 00번지 부터  dump로
살펴보세요. 이 때  [525쪽] 에서 인터럽트 번호 9h의 실제  인터럽트 서
비스 루틴"의 주소를 "세그먼트 : 오프셋" 형태로 적어보세요.
*******************************************************************
<4> 인터럽트의 종류
*******************************************************************
        인터럽트의 갯수는 총 256개 (한바이트  크기분 )가 있다고 했지
만, 이것도 크게 다음과 같이 나누어 볼 수가 있다.
        1. 소프트웨어 인터럽트
        2. 하드웨어 인터럽트
        먼저 교재를 가지신  분은 [524쪽]에 나와 있는 표를  지금 펴보
자.(교재가 없는 분들은 각자 가지고 있는  인터럽트 벡터 표를 참조해주
세요)  이 표를 보는 방법은 다음과 같다.
<첫째>
        제일 왼쪽  칸이 "인터럽트 번호"  인데, 이게 아파트  당첨순서
처럼 "0 순위"에 가까울수록 우선순위가 높은  것이다. 따라서 제일 처음
에 나오는 "0" 번 인 "devide by zero  error"가 교장 선생님 처럼  컴퓨
터 내부에서는 가장 우선순위가 높은것이다. 숫자  뒤에 붙은 h는 16진법
을 의미한다. 즉  1h --> 0x01 과 같은 의미이다.
<둘째>
        가운데 "Address"  칸이 있는데, 이  칸은 전부 4바이트  크기의
주소이다. 주소가 4바이트인 이유는 "세그먼트  : 오프셋" 형식으로 먼거
리 포인터(far pointer)를 이용하기 때문이다.
1> 하드웨어 인터럽트
----------------------
        이 중에서도  일단 하드웨어 인터럽트를 구분해보자.  각기 색이
다른 형광펜으로 다음의 번호에 표시를 해두자.
   * 인터럽트 번호 : 8h 부터  fh 까지
       <메모>   - 하드웨어 인터럽트
                - 8259 인터럽트 콘트롤러 1번에서 발생한다.
   * 인터럽트 번호 : 70h 부터 77h 까지
        <메모>  - 하드웨어 인터럽트
                - 8259 인터럽트 콘트롤러 2번에서 발생한다.
   * 인터럽트 번호 : 0h  부터 04h 까지
        <메모> - CPU 에서 발생하는 인터럽트
2> 소프트웨어  인터럽트
------------------------
        위에서 표시한 하드웨어 인터럽트를 제외한  모든 것이 소프트웨
어 인터럽트라고 생각하면 된다. 이것도 크게  BIOS 인터럽트와 DOS 인터
럽트로 구별할  수 있다. 먼저   DOS 인터럽트의 구별을  위해서, 표에서
다음과 같은 줄에 "확실히"표시를 해두기로 하자.
        * 인터럽트 번호 -->  21h    84-87    (Dos function call)
        이 DOS function  call을 호출하면 (메모리에 올라와  있는) DOS
의 일부분인 command.com 안의 루틴을 호출하게 된다.
        BIOS function  call을 호출하면  ROM-BIOS 안의 루틴을  호출한
다.
*******************************************************************
<5> 인터럽트를 위한 하드웨어의 구현(IBM-PC 에서)
*******************************************************************
        인터럽트를 발생시키는 기능은 8259라는  콘트롤러(칩) 2개가 이
용된다. 더 자세한 개념도는 나중에 그림 파일로 보여드리기로 하겠다.
*******************************************************************
<6> 하드웨어 인터럽트(8259에서 발생하는))의 순서.
*******************************************************************
        하드웨어 인터럽트에 대해서  생각해야 할 것은 다음과  같은 두
가지이다.
        -----------------------------------------------------------
        1. 인터럽트를 걸 수 있는 디바이스(장치)의 종류는 무엇인가 ?
        2. 그 우선순위는 어떻게 결정되어 있는가 ?
        -----------------------------------------------------------
        이런 문제는 컴퓨터를  만드는 회사에서 이미 결정이  된 것이기
때문에 , 일반 사용자들은 [525쪽] 표를 참조하기만 하면 된다.
        표에서 "하드웨어  인터럽트"라고 표시한 부분을  참조하고 다음
의 문제를 풀어 보기로 하자.
<문제> 키보드와  하드디스크 인터럽트가  동시에 걸렸다고 하자.  CPU는
어느 인터럽트를 먼저 실행하겠는가 ?
*******************************************************************
<7> C 에서 제공하는 인터럽트 함수  (Turbo C 에서)
*******************************************************************
        C에서 인터럽트를  사용하는 방법은 지극히 간단하다.  이미 C에
서 준비되  있는 함수를 불러다 쓰면  되기 때문이다. 그  종류는 다음과
같다.
int86()
int86x()
intdos()
intdosx()
        이 내용은 교재의 [440쪽] (라이브러리  함수)편에 잘나와 있다.
(교재가 없는  분은 각자 가지고  계신 "라이브러리 레퍼런스"를  참조해
주세요.) 이 강좌를 읽는 분들은 "함수읽는  방법"에 대해 잘 아시리라고
생각하지만, 혹시나 하는 마음에 하나만 설명해 보기로 한다.
        먼저  [440쪽]의 int86()  함수를  살펴보면, 반드시  "dos.h"를
포함하라고 되어있다. 이유는,  union REGS의 정의가 이 곳에  되있기 때
문이다. 인터럽트를 사용하기 위해서는 CPU의  레지스터를 직접적으로 이
용해야 하는데, 그 변수의 정의가 dos.h 안에 이미 되있는 것이다.
        그리고,  int86()함수의 파라메타로  사용되는 변수는  3개인데,
교재에 보다시피. 첫번째 값은 "인터럽트의 번호"이다.  이 번호가 이 강
좌의 첫부분에서 얘기했던 "인터럽트 번호"를 의미한다.
        그리고 두번째,  세번째의 파라메타는 아래와 같이  똑같은 형태
이다.
                union REGS *inregs
                union REGS *outregs
스트락춰 와 유니온의  표현 방법에 대해서 익숙치 않은 분들은  각자 연
습하기로 하고 ,  앞으로는 아래에 보이는 상투적인 표현을  그대로 따라
쓰도록 하자.
#include <dos.h>        <-- 반드시 포함
main()
{
 union REGS r;          <-- 변수 r을 임의로 지정.
 r.h.ah = 0x02;      <-- 인터럽트  call 하기전에 필요한 값 대입
 int86(0x1a,&r,&r);  <-- 인터럽트 호출 (현재는 0x1a번)
                         &r의 형태로 쓴 걸 주의할 것
                        (함수에서 주소를 쓰라고 정의되 있기때문)
 hour = r.h.ch;      <-- 레지스터에 저장된 결과를 이용
 min  = r.h.cl;
 sec  = r.h.dh;
}
        int86x() 함수는 똑같은 내용이지만,  특별히 세그먼트 레지스터
를 더 지정 할 수 있는 형태이고,  intdos() 형태는 "DOS 인터럽트"를 호
출하는 함수이므로 굳이 인터럽트 번호 0x21을  안써도 되는 형태일 뿐이
다.
*******************************************************************
<8> 인터럽트의 작동을 눈으로 확인해 보자.
*******************************************************************
        다음에 인터럽트가 직접 작동되는 모습을 살펴보기로 하자.
먼저 [524쪽] 인터럽트 번호표를 보면, 인터럽트  0번은 "divide by zero
error"이다. 이말은 짐작하시다시피, 프로그램 실행중  "0으로 나누는 경
우"가 있으면  발생되는 인터럽트이다. 0으로  나누면 안되는 이유야  잘
아실 것이고, 이 인터럽트는 성격상 CPU  내부에서 발생하는 것이고 우리
가 임의로 호출할 수 있는 것은 아니다.
        다음을 직접  실행시키고 인터럽트 0번이 실행되는  모습을 살펴
보기로 하자.
main()
{
        int i;
        i = 0;
        i = 100/i;
}
<문제> 인터럽트 0번의 인터럽트 핸들러  (인터럽트 서비스 루틴)의 실제
주소는 얼마인지 디버거를 이용하여 찾아보세요.  (00 - 03까지에 들어가
있는 주소)
        하나 더  예를 들어,  인터럽트 번호 1c  를 살펴보자. 이  것은
"사용자 정의 timer tick" 이라고 설명되 있다.  이 내용을 이미 알고 계
신 분도 많겠지만, 지금 우리가 쓰고  있는 IBM-PC에서는 1초에 18.2번의
인터럽트가 걸리고 있다. 더 근본적인  일련의 이야기는 다음번에 하나의
강좌로 다시 쓰기로  하고 지금은 이런 사실을 그대로 확인해  보기로 하
자.
<문제>  먼저 도스 상태에서 모니터를 쳐다보세요.  즉 다음과 같은 상태
입니다. 여기서는  지금 안보이지만 모니터상에서는 커서가  깜박이고 있
을 것입니다.
           c:\tc>
지금 컴퓨터는 무슨 일을 하고 있습니까 ?
        요즘 아주 인기있는  "문화 유산 답사기"에 관한  책을 읽어보면
"사람은 아는 만큼  느낀다"는 아주 근사한 말이 나온다.  우리가 지금하
고 있는  기계적인 컴퓨터 공부에서도  이런 말을 쓰는 것이  어울리지는
잘 모르겠지만,  여러분이 바로  위의 문제를 풀면서(모니터를  쳐다보고
있으면서) 무엇을 느끼실 지 궁금하다.
        평상시에 커서는 (DOS 상태에서), 사람이  키보드를 치기를 기다
리며 한가롭게  껌벅이고 있는 것  같지만, 사실은 이 상태에서도  1초에
18.2번씩 인터럽트가 걸리고 있다는 걸 알아야 한다.
        이 인터럽트가 걸리면 ( 인터럽트 1c 번이므로)  70 - 73 번지에
적혀 있는  주소로 가서 일을 하고  온다. 그러나 이 곳에  가보면 (보통
상태에서는) 아무 일도  안시키고 "그냥 돌아가" 하는 쓸쓸한  대답만 듣
고 돌아온다. 따라서  외관상으로는 마치 아무것도 안하는 것  같이 보인
다.
        따라서 우리는 이제 아주 간단항 일을  하나 시킴으로서 정말 인
터럽트가 1초에 18.2번씩 걸리는 지 확인해 보기로 하자.
        시키는 일은 간단하다.  그냥 기념으로 '0' 이라는  숫자를 하나
찍고 돌아가라는  것이다. 먼저 프로그램을 보기로 하자
#include <dos.h>
interrupt intr_exam();
main()
{
        unsigned segment, offset;
        segment = FP_SEG(intr_exam);
        offset  = FP_OFF(intr_exam);
        poke( 0x0000, 0x0070, offset);
        poke( 0x0000, 0x0072, segment);
}
interrupt intr_exam()
{
        putch('0');
}
        위  프로그램은  보시다시피   두개의  함수로  이루어져  있다.
main() 함수에서  하는 일은 intr_exam()  이라는 함수의 주소를  읽어서
0000 : 0070, 번지와 0000 : 0072 번지에 넣어 주는 일만 한다.
        현재 변수로 쓰인 segment, offset 두개는 int 타입(2 바이트)
에 해당하는 것을 기억하자. 따라서 이 값들은  70 - 73까지의( 인터럽트
1c의 서비스 루틴 주소) 값을 변경하고 있는 것이다.
        이 작업은  짐작하시다시피, "일 안시키는 현재의  서비스 루틴"
으로 가지 말고 intr_exam() 이라는 함수로 오라는 뜻이다.
        현재 intr_exam() 함수는 '0' 을  찍으라는 일을 시키고 있다.그
리고 이 함수는 보통 프로그램의 서브  루틴이 아니고, 특별히 "인터럽트
서비스 루틴" 이라는 의미로 함수명 앞에  "interrupt" 라는 휘장을 달아
준 걸 눈여겨 보자.
        이제 이 프로그램을 그대로 잘라내서  실행시켜 보기로 하자. 이
프로그램은 원래의 서비스 루틴으로 되돌리는  프로그램이 없으므로 평상
시와 같이 DOS를 쓰고 싶으면 커퓨터를 껐다가  켜야 한다는 것을 기억하
자.  그리고 아래에 적혀 있는 숙제를 메모해 두고 직접해 보기로 하자.
Posted by 김용환 '김용환'

댓글을 달아 주세요