2011-12-03 3 views
3

명령 벡터 테이블을 다시 프로그램하려고합니다. 여기에 코드를 내가 사용된다C (DOS)의 임베디드 어셈블리 - 불법적 인 명령

#include <stdio.h> 

int a=1; 
void func(); 

void keyboard() 
{ 
    printf("\n\nkeyboard!!!\n"); 
    a=0; 
    asm{iret} 
} 

int main() 
{ 
    printf("starting..."); 
    func(); 
    return 0; 
} 

     int vectorcs = 0; 
int vectorip = 0; 

void func() 
{ 

    printf("\n*****\n"); 
    asm{ 
     cli 
     mov ax,0 
     mov es,ax 
     mov bx,36 
     mov ax,word ptr es:[bx] 
     mov vectorip,ax 
     push ax 
     mov ax,word ptr es:[bx+2] 
     mov vectorcs,ax 
     push ax 
     mov ax,cs 
     mov word ptr es:[bx],offset keyboard 
     mov es:[bx+2],ax 
     sti 
    } 
    printf("\n%d %d\n",vectorip,vectorcs); 

    while (a) { 
    } 
    asm { 
     cli 
     mov es,bx 
     mov bx,36 
     pop ax 
     mov word ptr es:[bx+2],ax 
    } 
    asm{ 
     pop ax 
     mov word ptr es:[bx],ax 
     sti 
    } 
} 

내가이 프로그램을 실행하려고하면 3.0 는, 터보 C++를 사용하고 "16 비트 MS-DOS 하위 시스템 :. NTVDM CPU가 불법 지시가 발생했습니다" 나타납니다. CS, OP 및 IP 레지스터의 내용을 보여줍니다. 나는 프로그램을 계속할 수 없다. 어떤 제안? 당신이 무슨 일을하는지

답변

8

여러 가지 이유로 잘되지 않습니다 : 제대로 저장, 부하와 CPU 레지스터를 복원하지 않기 때문에

  1. 일반 C 함수를 안전하게 인터럽트 서비스 루틴으로 사용할 수 없습니다. 키워드는 interrupt으로 선언해야합니다. 그리고 그들은 결국 당신을 위해 iret을 가질 것입니다.
  2. 인터럽트 루틴에서 프로그램에서 비동기 적으로 변경할 수있는 변수는 volatile으로 선언해야합니다. 그렇지 않으면 컴파일러에서 잘못 최적화 된 액세스가 발생할 위험이 있습니다.
  3. 인라인 어셈블리 코드가 CPU 레지스터의 내용을 손상시킬 수 있습니다. 이 코드에서 잘못된 점은 asm 블록이 스택 포인터를 엉망으로 만든다는 것입니다. 첫 번째 블록은 스택에 몇 가지 추가 단어가있는 상태로 종료됩니다. 이것은 컴파일러에게는 전혀 예상치 못한 일이며 프로그램을 중단시킬 수 있습니다. 다른 문제가있을 수 있지만 인라인 어셈블리 블록에서 레지스터를 보존해야하는 컴파일러 설명서를 확인하지는 않습니다. 이 모든 것을하지 않고 대신 setvect() 함수를 선택하십시오.
  4. 인터럽트 서비스 루틴 내부에서 대부분의 표준 라이브러리 함수를 호출하는 것은 일반적으로 이러한 함수가 재진입/스레드 안전이 아니기 때문에 문제를 요구합니다. 그들은 프로그램의 나머지 부분에 대해 예기치 않은 방식으로 일부 전역 변수 또는 상태를 수정할 수 있습니다. 인터럽트 서비스 루틴 (printf()가 의존하는 btw)에서 DOS 서비스 함수를 호출하는 경우에도 마찬가지입니다. 도스가 괜찮다고 말할 때만 전화 할 수 있습니다. InDos 플래그 변수를 통해 수행하지만 여전히 InDos = 0 일 때 모든 호출이 안전하지는 않습니다.

this question에 대한 답변에서, 인터럽트 벡터를 변경 인터럽트 서비스 루틴을 정의하고 터보 C의 모든, 그들로부터 DOS 함수를 호출하는 방법을 참조하십시오.

this question 및 그 대답이 유용 할 수도 있습니다.

편집는 :

#include <stdio.h> 

volatile int a = 1; 
void interrupt (*pOldInt9)(void); 
void func(void); 

void interrupt keyboard(void) 
{ 
    printf("\n\nkeyboard!!!\n"); 

    asm { 
     in al, 0x60 
     in al, 0x61 
     mov ah, al 
     or al, 0x80 
     out 0x61, al 
     mov al, ah 
     out 0x61, al 
    } 

    a = 0; 

    asm { 
     mov al, 0x20 
     out 0x20, al 
    } 
} 

int main(void) 
{ 
    printf("starting..."); 
    func(); 
    return 0; 
} 

void func(void) 
{ 
    printf("\n*****\n"); 

    asm { 
     push bx 
     push es 

     mov  bx, 9 * 4 
     mov  ax, 0 
     mov  es, ax 

     cli 

     mov  ax, es:[bx] 
     mov  word ptr pOldInt9, ax 
     mov  word ptr es:[bx], offset keyboard 

     mov  ax, es:[bx + 2] 
     mov  word ptr pOldInt9[2], ax 
     mov  es:[bx + 2], cs 

     sti 

     pop  es 
     pop  bx 
    } 

    while (a) {} 

    asm { 
     push bx 
     push es 

     mov  bx, 9 * 4 
     mov  ax, 0 
     mov  es, ax 

     cli 

     mov  ax, word ptr pOldInt9 
     mov  es:[bx], ax 

     mov  ax, word ptr pOldInt9[2] 
     mov  es:[bx + 2], ax 

     sti 

     pop  es 
     pop  bx 
    } 
} 
+0

dos.h를 사용하지 않는 것은 어떻습니까? getvect 및 setvect에 의해 귀하의 코드를 이해, 당신은 코드 세그먼트 후 원래의 키보드 함수를 호출합니다. getvect-setvect를 사용할 수 없다면 어떤 제안이 있습니까? – Mikael

+0

내 대답의 마지막 링크를 참조하십시오. 인터럽트 처리기로 시작할 수있는 충분한 asm 코드가 있습니다. –

+0

다시 보지만 인라인 어셈블리를 묻습니다. C 또는 인터럽트 벡터 테이블의 함수를 처리 할 수 ​​없어서 이틀 동안 같은 오류가 발생합니다. 나는 함수에 인터럽트 키워드를 사용하고, 함수의 끝 (다시)에 덧붙인 iret를 사용했다. 그러나 여전히 똑같은 것이다. – Mikael

1
asm { 
    cli 
    mov es,bx 
    mov bx,36 
    pop ax 
    mov word ptr es:[bx+2],ax 
} 

bx는 코드 앞에 무엇을 포함 않습니다

이것은 인라인 어셈블리와 dos.h의 기능없이 그것을 어떻게?

void keyboard() 
{ 
    printf("\n\nkeyboard!!!\n"); 
    a=0; 
    asm{iret} 
} 

이 함수는 올바르게 파괴하지 않은 스택 프레임을 설정합니다.

+0

bx는 0이어야합니다. LABEL1이라는 레이블이 있다고 가정) 인라인 어셈블리로 레이블을 지정하고 싶습니다. mov eax, offset LABEL1 - 이것을 사용할 수 없습니다. 어셈블러는 LABEL1을 기호로보고 정의되지 않았다고 말합니다. jmp LABEL1을 시도해도 - 레이블은 정의되지 않습니다. 그때 기능을 사용해야했다, 그것은 작동하지 않는 것 ... – Mikael

관련 문제