我正在尝试编程驱动程序以在55h内提供服务。我正在尝试确保一切正常但我发现当我用INT 21h
= 09h调用AH
来打印字符串时,即使使用正确的偏移量,它也不会打印任何内容在DX
中,我不知道这是怎么回事。在代码的其他部分,它工作正常。
这是我的代码:
codigo SEGMENT
ASSUME CS :codigo
ORG 256
inicio:
MOV AL, DS:[83H] ;Parameters: when call with '/I' installs driver
CMP AL, 49H
JE inst
CMP AL, 44H ;Parameters: when call with '/D', uninstalls
JE desinstalar_55h
JE rsi
PRUEBA DB "THIS IS A TEST",0AH,'$'
rsi PROC FAR
STI
CMP AH, 00
JE firm ;used to check if driver is install
MOV CX, 0
CMP AH, 11H
JE codificar
volver:
IRET
desinst:
JE desinstalar_55h
inst:
CALL instalador
firm:
CALL firma
rsi ENDP
firma PROC NEAR
MOV AX, 0F0F0H
RET
firma ENDP
desinstalar_55h PROC
PUSH AX
PUSH BX
PUSH CX
PUSH DS
PUSH ES
CALL check_driver
CMP AX, 1
JE no_instalado
MOV CX, 0
MOV DS, CX
MOV ES, DS:[55H*4+2]
MOV BX, ES:[2CH]
MOV AH, 49H
INT 21H
MOV ES, BX
INT 21H
CLI
MOV DS:[55H*4], CX
MOV DS:[55H*4+2], CX
STI
no_instalado:
POP ES
POP DS
POP CX
POP BX
POP AX
RET
desinstalar_55h ENDP
instalador PROC
CALL check_driver
CMP AX, 1
JNE ya_instalado
MOV DX, OFFSET PRUEBA
MOV AH, 09H
INT 21H ;here it works fine
MOV AX, 0
MOV ES, AX
MOV AX, OFFSET rsi
MOV BX, CS
CLI
MOV ES:[55h*4], AX
MOV ES:[55h*4+2], BX
STI
MOV DX, OFFSET instalador
ya_instalado:
INT 27H
instalador ENDP
codificar PROC
CLD
MOV DX, OFFSET PRUEBA
MOV AH, 09H
INT 21H ;here it doens't print anything
RET
codificar ENDP
check_driver PROC
MOV AX, 0
MOV ES, AX
MOV AX, OFFSET rsi
CMP WORD PTR ES:[55H*4], 0
JNE detectar_mi_driver
CMP WORD PTR ES:[55H*4 + 2], 0
JE no_driver
detectar_mi_driver:
MOV AH, 0
INT 55H
CMP AX, 0F0F0H
JE fin_check
no_driver:
MOV AX, 1
fin_check: RET
ENDP check_driver
codigo ENDS
END inicio
例如,在安装驱动程序的'instalador'rutine中,我调用INT 21h
并且它正常工作,打印字符串。但是当我从另一个.EXE程序调用{{1}} = 11h的中断55h时,它应该执行rsi进程并跳转到'codificar'ruutine,它调用AH
,但在这种情况下,它会执行' t打印任何内容,尽管它在INT 21h
中具有相同的偏移量。谁知道为什么会这样?在此先感谢您的帮助。
编辑:我尝试用TD调试它并且工作正常,打印字符串。但是,当我从另一个程序调用{{1}} = 11h的中断55h时,它不会打印任何内容或只是卡住而且永远不会返回。
答案 0 :(得分:2)
此计划存在几个问题。
inicio:
MOV AL, DS:[83H] ;Parameters: when call with '/I' installs driver
CMP AL, 49H
JE inst
CMP AL, 44H ;Parameters: when call with '/D', uninstalls
JE desinstalar_55h
JE rsi
PRUEBA DB "THIS IS A TEST",0AH,'$'
在前面的代码段中,JE rsi
没用,应该用程序终止替换。您可以使用RET
,因为该程序是.COM
rsi PROC FAR
STI
CMP AH, 00
JE firm ;used to check if driver is install
MOV CX, 0
CMP AH, 11H
JNE volver <------------ codificar is a routine that ends with
CALL codificar <------------ a mere RET so call it (don't jump to it!)
volver: <------------ and fall through in the IRET.
IRET
;;;;desinst: \
;;;; JE desinstalar_55h | Move this code outside the proc!!!
;;;;inst: | Here it has no sense.
;;;; CALL instalador /
firm:
CALL firma
IRET <-- Add this because the RETF provided by ENDP is not enough!
rsi ENDP
rsi 程序遇到的问题最多。您已将其声明为FAR PROC,但实际上它是一个中断处理程序,因此它的所有出口都应该使用IRET
指令。
instalador PROC
CALL check_driver
CMP AX, 1
JNE ya_instalado
在标签 ya_instalado ,您有终止并保持常驻电话但是检查表明您已经安装了!通过
解决这个问题 int 27h
ya_instalado:
int 20h
最后但最明显的问题在于打印程序。从执行.COM调用时,DS寄存器由DOS设置。从中断处理程序55h中调用时,您必须手动设置DS。只需从CS复制它。你也不需要CLD指令。因为这毕竟是一个中断处理程序,所以你应该保留寄存器。
codificar PROC
;;;;CLD
PUSH AX
PUSH DX
PUSH DS
PUSH CS
POP DS
MOV DX, OFFSET PRUEBA
MOV AH, 09H
INT 21H
POP DS
POP DX
POP AX
RET
codificar ENDP