2014-11-20 4 views
0

이 프로그램을 실행하려고합니다. 그것은 인터럽트를 사용하고 우리가 w를 누르면 , 그것은 키보드 버퍼getvect 함수가 정의되지 않았습니다.

#include "stdafx.h" 
#include "stdio.h" 
#include "bios.h" 
#include <dos.h> 


void interrupt_oldint15(*oldint15); 
void interrupt_newint15(unsigned int BP, unsigned int DI, unsigned int SI, unsigned int DS, 
         unsigned int ES, unsigned int DX, unsigned int CX, unsigned int BX, 
         unsigned int AX, unsigned int IP, unsigned int CS, unsigned int flags); 
void main () 
{ 

oldint15 = getvect (0x15); 
setvect (0x15, newint15); 
keep (0, 1000); 
} 
void interrupt_newint15 (unsigned int BP, unsigned int DI, unsigned int SI, unsigned int DS, unsigned int ES, unsigned int DX, unsigned int CX, unsigned int BX, unsigned int AX, unsigned int IP, unsigned int CS, unsigned int flags) 
{ 
if(*((char*)&AX)==0x11) 
*((char*)&AX)=0x1F; 
else if(*((char*)&AX)==0x1F) 
*((char*)&AX)=0x11; 

} 

에의하여 대체하지만 getvect 및 setvect 기능에 오류가 있습니다.

+0

은 다음과 같습니다

는 사용의 예 (에 '@'초마다 인쇄)인가? 이들은 Turbo/Borland C에서만 사용할 수있는 비표준 C 함수 인 것으로 보입니다. – uesp

+0

"dos.h"를 사용했습니다. 그 일을하지 않겠습니까? – user3297557

+0

어떤 컴파일러를 사용하고 있습니까?컴파일러 문서 또는 헤더 파일에 해당 함수가 포함되어 있는지 직접 확인해야합니다. – uesp

답변

0

한 가지로 인터럽트 기능은 C에서 매개 변수도 반환 값도 없습니다.
인터럽트 이벤트에 대한 입력이 모든 키 레지스터 (일반적으로 현재 실행중인 프로세스의 스택에 있음)를 저장하기 때문에 모든 레지스터를 나열하는 것은 공간 낭비입니다 (컴파일하지 말아야 함). 모든 키 레지스터 (PC 및 상태 레지스터와 같은)는 인터럽트를 종료 할 때 복원됩니다.

컴파일러는 인터럽트 기능에서 변경된 범용 레지스터가 저장/복원되도록합니다. 그런 낮은 수준에서 작업하는 경우 인터럽트 벡터가있는 위치를 정확히 알아야합니다. 인터럽트 벡터를 오버레이하는 코드 세그먼트 및 인터럽트 벡터를 미러링하는 다른 코드 세그먼트 그런 다음 현재 인터럽트 벡터 집합을 미러에 복사 한 다음 원하는 개별 벡터를 작성한 인터럽트 함수에 대한 포인터로 바꿉니다. 코드가 끝나면 벡터를 원래 벡터 영역으로 다시 복사해야합니다. 문제가있는 기능이 해당 작업을 수행 할 수 있습니다. 아주 오래된 포스트에서

이,하는 c.comp 뉴스 그룹에서 도움이 될 수있다 : 당신은 언어를 혼합하는

. 볼랜드 C에서 ++는

공극 (인터럽트 *) (...)

이 입력 갖는다 볼랜드 C에 입력

공극 (인터럽트 *)()

을하고있다 "중단" 는 setvect의 매개 변수 유형 및 사용 된 언어에 따라 같은 방식으로 변경되는 getvect의 리턴 유형에 영향을줍니다. 'oldvec'컴파일러의 메시지에 따라 반환하는 "C 인터럽트"를 getvect로 선언

때문에 당신은 분명히 C 프로그램으로 C++ 프로그램으로 프로그램을 컴파일 아닌 "C++ 인터럽트".

0

당신의 C처럼 아무것도 보지 C에서 GET/설정 VECT()를 사용하여 ++ 예제를위한 형식은 다음과 같습니다 이미 언급 한 바와 같이

tick_isr_old = getvect(0x08); 

setvect(0x08, (void interrupt (*)(void)) tick_isr); 
0

는 기능 (getvect)와 setvect는()에서만 사용할 수 있습니다 Borland/Turbo C++. _dos_getvect() 및 _dos_setvect() 함수는 거의 동일하며 컴파일러 (Borland/Turbo C++, MS Visual C++ 1.x, Open Watcom C++)에서 더 나은 이식성을 제공합니다. 그들은 <dos.h>에 정의되어야합니다. `getvect()가`\`setvect()가`정의는

/*** Includes ***/ 
#include <stdint.h> // int*_t, uint*_t 
#include <stdbool.h> // bool, true, false 
#include <dos.h>  // _chain_intr(), _dos_getvect() , _dos_setvect() 
#include <stdio.h> // putchar() 


/*** Definitions ***/ 
#define TICKS_PER_SEC 18ul 
#define VECT_TIMER  0x1C 

/*** Global Variables ***/ 
bool timer_hooked = false; 
bool timer_1sec_elapsed = false; 
uint32_t ticks = 0; 
void (interrupt far * OrigTimerH)(); // vector to original 0x1C handler 


/*** Functions ***/ 
static void interrupt far TimerH(void) { 
    ticks++; 
    if (ticks % TICKS_PER_SEC == 0) { 
     timer_1sec_elapsed = true; 
    } 
    _chain_intr(OrigTimerH); // handler callback 
} 

void TimerStart(void) { 
    __asm { cli }    // critical section; halt interrupts 
    OrigTimerH = _dos_getvect(VECT_TIMER); // save original vector 
    _dos_setvect(VECT_TIMER, TimerH);  // put our handler in the vector 
    timer_hooked = true;  // remember that we're hooked if we wanted to unhook 
    __asm { sti }    // resume interrupts 
} 

int main(void) { 
    TimerStart(); 

    while (true) { 
     if (timer_1sec_elapsed) { 
      timer_1sec_elapsed = false; 
      putchar('@'); 
     } 
    } 
} 
관련 문제