我试图得到一个星期的答案。:)
但是,也许我问错了问题。所以就是这样:我需要加载然后卸载住宅程序(设置一些向量然后回到标准),我这样做但是在安装标准向量之后我尝试使用 49h 释放分配给住宅程序的内存:首先我得到标准向量返回,然后我清除环境,然后我清除内存用于住宅程序。然后我可以尝试通过单击窗口的 [X] 按钮来关闭 CMD,但出现错误:
这是我的代码:
ASTACK segment stack
dw 100h dup(?)
mark_END_OF_STACK = $
ASTACK ends
ACODE segment
assume CS: ACODE, DS: ACODE, SS: ASTACK
str_MOD db 'StdMod$' ;\ Residential data (ResMod - if residential program, StdMod - if not residential program)
val_COUNTER db 0 ; |
val_RES_PSP_ADDR dw 0 ; | PSP address of residential programm
val_OLD_INT_PROC_ADDR dd 0 ;/ Old int 1Ch address
NEW_INT_PROC proc far
push DS ;Saving registers
push AX
push CS
pop DS
cmp val_COUNTER, 10
je CLEAR_COUNTER
mov AL, val_COUNTER
add AL, '0'
inc val_COUNTER
call DIRECT_PRINT
jmp EXIT_RES
CLEAR_COUNTER:
mov val_COUNTER, 0
EXIT_RES:
pop AX ;Recovering registers
pop DS
mov AL, 20h
out 20h, AL
iret
NEW_INT_PROC endp
DIRECT_PRINT proc near
push AX
push BX
push CX
push DX
push SP
push BP
push SI
push DI
;Getting current cursor position
mov AH, 03h
mov BH, 00h
int 10h
push DX;Saving current row and column of cursor position
;Settin new cursor position
mov AH, 02h
mov BH, 00h
mov DX, 0000h
int 10h
;Print number from AL
mov AH, 09h
mov BH, 0
;mov BL, 153
mov CX, 1
int 10h
;Recovering cursor position
mov AH, 02h
mov BH, 00h
pop DX;Recoveing initial cursor position
int 10h
pop DI
pop SI
pop BP
pop SP
pop DX
pop CX
pop BX
pop AX
ret
DIRECT_PRINT endp
mark_NEW_INT_PROC_MEM = $
PRNT_MARKED_STRING proc near
;Print string with end of string mark
;String offset must be in DX
push AX
mov AH, 09h
int 21h
pop AX
ret
PRNT_MARKED_STRING endp
LOAD_RESIDENT proc near
push AX
push BX
push DX
mov [str_MOD], 'R'
mov [str_MOD + 1], 'e'
mov [str_MOD + 2], 's'
mov [val_RES_PSP_ADDR], ES ;Save PSP address to realise memory later
push ES
mov AX, 351Ch ;Getting CS:IP of standart interruption procedure
int 21h
mov word ptr [val_OLD_INT_PROC_ADDR], BX ;IP of standart interruption procedure saved
mov word ptr [val_OLD_INT_PROC_ADDR + 2], ES ;CS of standart interruption procedure saved
pop ES
push DS
mov DX, offset NEW_INT_PROC ;Installing new interruption on 1Ch
mov AX, seg NEW_INT_PROC
mov DS, AX
mov AX, 251Ch
int 21h
pop DS
pop DX
pop BX
pop AX
ret
LOAD_RESIDENT endp
FREE_RESIDENT proc near
push AX
push BX
push DX
push ES
mov AX, 351Ch
int 21h
mov AX, word ptr ES:[val_OLD_INT_PROC_ADDR]
mov word ptr [val_OLD_INT_PROC_ADDR], AX
mov BX, word ptr ES:[val_OLD_INT_PROC_ADDR + 2]
mov word ptr [val_OLD_INT_PROC_ADDR + 2], BX
mov BX, ES:[val_RES_PSP_ADDR]
mov [val_RES_PSP_ADDR], BX ;Get residential PSP address
pop ES
cli ;Recovering standart interruption
push DS
mov DX, word ptr [val_OLD_INT_PROC_ADDR]
mov AX, word ptr [val_OLD_INT_PROC_ADDR + 2]
mov DS, AX
mov AX, 251Ch
int 21h
pop DS
sti
mov AH, 49h
push ES
mov ES, [val_RES_PSP_ADDR]
push ES
mov ES, ES:2Ch
int 21h
pop ES
int 21h
pop ES
pop DX
pop BX
pop AX
ret
FREE_RESIDENT endp
IS_RES_RUNNING proc near
push ES
push AX
mov AX, 351Ch
int 21h
cmp ES:[str_MOD], 'R'
jne EXIT_RES_NOT_RUNNING
cmp ES:[str_MOD+1], 'e'
jne EXIT_RES_NOT_RUNNING
cmp ES:[str_MOD+2], 's'
jne EXIT_RES_NOT_RUNNING
cmp ES:[str_MOD+3], 'M'
jne EXIT_RES_NOT_RUNNING
cmp ES:[str_MOD+4], 'o'
jne EXIT_RES_NOT_RUNNING
cmp ES:[str_MOD+5], 'd'
jne EXIT_RES_NOT_RUNNING
mov DS:[val_RES_RUNNING], 1
EXIT_RES_NOT_RUNNING:
pop AX
pop ES
ret
IS_RES_RUNNING endp
USER_UNLOAD proc near
push ES
push AX
mov ES, [val_RES_PSP_ADDR]
cmp byte ptr ES:[80h], 04h
jne EXIT_USR_INLOAD
cmp byte ptr ES:[82h], '/'
jne EXIT_USR_INLOAD
cmp byte ptr ES:[83h], 'u'
jne EXIT_USR_INLOAD
cmp byte ptr ES:[84h], 'n'
jne EXIT_USR_INLOAD
mov [val_RES_USR_UNLOAD], 1
EXIT_USR_INLOAD:
pop AX
pop ES
ret
USER_UNLOAD endp
str_RES_LOADED db 'Residential program has been loaded', 10, 13, '$'
str_RES_RUNNING db 'Residential program is running', 10, 13, '$'
str_RES_NOT_RUNNING db 'Residential program is not running', 10, 13, '$'
str_RES_UNLOADED db 'Residential program has been unloaded', 10, 13, '$'
val_RES_RUNNING db 0
val_RES_USR_UNLOAD db 0
MAIN proc far
push DS
push AX
mov AX, ACODE
mov DS, AX
mov [val_RES_PSP_ADDR], ES ;Saving PSP address
call IS_RES_RUNNING
cmp val_RES_RUNNING, 1
je FREE_RESIDENT_PROG
mov DX, offset str_RES_NOT_RUNNING
call PRNT_MARKED_STRING
mov DX, offset str_RES_LOADED
call PRNT_MARKED_STRING
call LOAD_RESIDENT
mov DX, offset mark_NEW_INT_PROC_MEM
add DX, offset mark_END_OF_STACK
add DX, 10Fh
mov CL, 4
shr DX, CL
mov AX, 3100h
int 21h
FREE_RESIDENT_PROG:
mov DX, offset str_RES_RUNNING
call PRNT_MARKED_STRING
call USER_UNLOAD
cmp [val_RES_USR_UNLOAD], 1
jne EXIT
mov DX, offset str_RES_UNLOADED
call PRNT_MARKED_STRING
call FREE_RESIDENT
EXIT:
mov AX, 4C00h
int 21h
MAIN endp
ACODE ends
end MAIN
请帮忙。