2

我正在用 Turbo-C 编写主程序,并且函数在汇编中。我的代码如下:

最后一个.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;
}

最后一个.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_pressuneliminate_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 回答