2

私はTurbo-Cでメインプログラムを書いていて、関数はアセンブリにあります。私のコードは次のとおりです。

lastc.c :

#include <stdio.h>
#include <dos.h>
#include <string.h>
extern void  eliminate_multiple_press(); // save old function adress in 32bit     pointer
                                    // setvect , add new function to inturupt 9
extern void  uneliminate_multiple_press(); // restore old function to inturupt 9
int main()
{
char *str;
eliminate_multiple_press();
printf("Enter a string:\n");
scanf("%s",str);
printf("the string you entered:\n");
printf("%s\n",str);

uneliminate_multiple_press();

return 0;
}

lasta.asm :

.MODEL LARGE
PUBLIC _eliminate_multiple_press
PUBLIC _uneliminate_multiple_press

.STACK 100H
.DATA
INT9SAVE DD ?
hexa_code db 0
scan_code db 0
.CODE

KEY_HANDLER PROC FAR
PUSH AX

MOV AH,0
int 16h
mov scan_code,ah
mov hexa_code,al
POP AX
iRET
KEY_HANDLER ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_eliminate_multiple_press PROC FAR

PUSH AX    
PUSH ES
MOV AX,0  
MOV ES,AX

;INT9SAVE = GETVECT(9);
MOV AX,ES:[9*4] ; **ax=c1 hex =193 dec**
MOV WORD PTR INT9SAVE,AX
MOV AX,ES:[9*4+2] **ax=15c7 hex = 5575 dec**
MOV WORD PTR INT9SAVE+2,AX

;SETVECT(9,KEY_HANDLER);
CLI
MOV WORD PTR ES:[9*4],OFFSET KEY_HANDLER ; **ES stays 0**
MOV WORD PTR ES:[9*4+2],SEG KEY_HANDLER ; **ES stays 0**
STI 
POP ES     
POP AX 
RET
_eliminate_multiple_press ENDP

;SETVECT(9,INT9SAVE);
_uneliminate_multiple_press PROC FAR
PUSH ES
PUSH AX
MOV AX,0
MOV ES,AX
CLI
MOV AX,WORD PTR INT9SAVE
MOV ES:[9*4],AX
MOV AX,WORD PTR INT9SAVE+2
MOV ES:[9*4+2],AX
STI
POP AX
POP ES
RET
_uneliminate_multiple_press ENDP



END

次のコマンドを使用して、エラーなしでファイルをコンパイルできます。

tcc -ml -r- lastc.c lasta.asm

このコードの目的は、キーボードでの複数の (重複した) キーの押下をなくすことです。この一連の文字を入力すると、次のようになります。

私のキーボードの334ffffghjjjj

画面上の出力は

34fghj


問題

プログラムlastc.exeを実行すると、でスタックしprintf("enter a string:\n");ます。割り込み 9h 割り込みサービス ルーチンを新しい関数に変更する際に問題が発生していると思いますkey_handler

関数key_handlerは完全ではありませんが、少なくとも関数を終了し、コードの最後まで続行する必要があります

scanfが呼び出されたときにプログラムが何もしていないように見えるのはなぜですか?

4

2 に答える 2

2

eliminate_multiple_pressおよびuneliminate_multiple_pressが割り込みハンドラとして宣言されているのはなぜですか? これらは、 を返す通常の関数である必要がありRETます。これらは関数として呼び出されており、割り込みへの応答として意図されていません。

C プログラムでは、次のようにします。

extern void eliminate_multiple_press(); // save old function adress in 32bit     pointer
                                    // setvect , add new function to inturupt 9
extern void uneliminate_multiple_press(); // restore old function to inturupt 9

RETの代わりに、あなたのアセンブリIRET。そして、それほど多くのレジスタを保存する必要はありません:

_eliminate_multiple_press PROC FAR
    push ES
    push AX

    MOV AX,0
    MOV ES,AX

    ;INT9SAVE = GETVECT(9);
    MOV AX,ES:[9*4] ; **ax=c1 hex =193 dec**
    MOV WORD PTR INT9SAVE,AX
    MOV AX,ES:[9*4+2] **ax=15c7 hex = 5575 dec**
    MOV WORD PTR INT9SAVE+2,AX

    ;SETVECT(9,KEY_HANDLER);
    CLI
    MOV WORD PTR ES:[9*4],OFFSET KEY_HANDLER ; **ES stays 0**
    MOV WORD PTR ES:[9*4+2],SEG KEY_HANDLER ; **ES stays 0**
    STI

    POP AX
    POP ES
    RET
_eliminate_multiple_press ENDP


;SETVECT(9,INT9SAVE);
_uneliminate_multiple_press PROC FAR
    PUSH ES
    PUSH AX

    MOV AX,0
    MOV ES,AX

    CLI
    MOV AX,WORD PTR INT9SAVE
    MOV ES:[9*4],AX
    MOV AX,WORD PTR INT9SAVE+2
    MOV ES:[9*4+2],AX   ; Was "[27*4+2]" which is incorrect.
    STI

    POP AX
    POP ES
    RET

_uneliminate_multiple_press ENDP
于 2014-01-16T15:27:33.333 に答える
-2

割り込み終了 (EOI) は、特定の割り込みの割り込み処理の完了を示すためにプログラマブル割り込みコントローラー (PIC) に送信される信号です。

mov al,020h ; =EOI
out 020h,al
于 2014-01-29T05:16:37.343 に答える