Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更换键盘中断(中断9)时,scanf不';似乎不接受输入_C_Assembly_Interrupt Handling_Dosbox_Turbo C - Fatal编程技术网

更换键盘中断(中断9)时,scanf不';似乎不接受输入

更换键盘中断(中断9)时,scanf不';似乎不接受输入,c,assembly,interrupt-handling,dosbox,turbo-c,C,Assembly,Interrupt Handling,Dosbox,Turbo C,我正在用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 // setvec

我正在用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;
}
我可以使用以下命令编译文件而不会出错:

tcc -ml -r- lastc.c lasta.asm
此代码的目标是消除键盘上的多次(重复)按键。如果我键入此字符序列:

我的键盘的334ffffghjjjj

屏幕上的输出应为

34fghj


问题 当我运行程序lastc.exe时,它卡在
printf(“输入字符串:\n”)。我想我在将中断9h中断服务例程更改为我的新函数
key\u handler

函数
key\u handler
未完成,但至少应该结束函数并继续到代码末尾


当调用
scanf
时,为什么我的程序看起来什么都不做?

为什么
消除多个按下按钮
取消多个按下按钮
被声明为中断处理程序?它们应该是返回
RET
的正常函数。它们被称为函数,而不是对中断的响应

mov al,020h ; =EOI
out 020h,al
在您的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
中断结束(EOI)是发送到可编程中断控制器(PIC)的信号,用于 指示给定中断的中断处理完成

mov al,020h ; =EOI
out 020h,al

哇,这是一篇多么怀旧的帖子:)顺便说一句,你可以在一个带调试器的虚拟机上尝试这段代码,我在Remouse\u multiple\u press中更新了调试器中发生的事情。我在调试器中看不到代码跳转到键处理程序函数,为什么
Remouse\u multiple\u press
Uneiminate\u multiple\u press
声明为中断处理程序?它们应该是返回
RET
的正常函数。唯一的中断处理程序是这两个函数管理的
KEY\u处理程序
。另外,如果你想推送一堆寄存器,我建议你推送
pusha
popa
。相关帖子:如果我理解正确的话……我的密钥处理器应该以iret结尾,我在这一点上正确吗?因为正是这个函数被原来的中断9函数所取代@mbratch@aminhalloun对
KEY\u HANDLER
是用来替换旧的中断处理程序,因此它需要
IRET
并保存寄存器(如果您不确定要修改哪些寄存器,我建议
pusha
popa
)。你从C中调用的函数不是中断处理程序。我在上面更新了我的代码。但是我的exe文件仍然被printf函数卡住了!!我想不出是什么问题?@aminhalloun代码在C语言中看起来还是一样的:您将被调用的函数声明为
中断
。此外,asm指令[27*4+2],AX
不正确。它应该是9而不是27我在那里被弄糊涂了-更新了-但仍然..卡住了:/