驻留程序结构和逻辑

问题描述 投票:0回答:1
使用8086微处理器和DOSBox。

这个驻留程序是通过这两个命令完成的: TASM.exe 程序.asm & TLINK.exe /t 程序.obj

为什么当我运行另一个必须中断的.exe时它不起作用?

以下代码必须在屏幕上显示分钟和秒,并在大约 1 秒后更新一次值(因为驻留程序每秒运行 18 次)。

.MODEL SMALL .CODE ORG 100H PROGRAMA: JMP RESIDE MINUTOS DB 0d SEGUNDOS DB 0d FONDO DB 00001111b CONTADOR DB 18d RUTINA PROC CLI PUSH AX PUSH BX PUSH CX PUSH SI PUSH ES MOV AX, SEG @DATA MOV DS, AX CMP CONTADOR, 0b JNE FIN CMP SEGUNDOS, 60d JNE CONTINUE SISEG60: MOV SEGUNDOS, 0d INC MINUTOS CONTINUE: MOV AX, 0B800h MOV ES, AX XOR AX, AX ;APLICAMOS ATRIBUTO A LAS 4 CASILLAS MOV AH, FONDO MOV SI, 3001d MOV ES:[SI], AH ADD SI, 2d MOV ES:[SI], AH ADD SI, 4d MOV ES:[SI], AH ADD SI, 2d MOV ES:[SI], AH XOR AX,AX MOV SI, 3000d ;ESCRIBIMOS LOS MINUTOS XOR AX,AX MOV AL, MINUTOS MOV BL, 10d DIV BL ADD AL, 30h MOV ES:[SI], AL ADD SI, 2d ADD AH, 30h MOV ES:[SI], AH ;ESCRIBIMOS LOS SEGUNDOS XOR AX, AX ADD SI, 4d MOV AL, SEGUNDOS MOV BL, 10d DIV BL ADD AL, 30h MOV ES:[SI], AL ADD SI, 2d ADD AH, 30h MOV ES:[SI], AH INC SEGUNDOS MOV CONTADOR, 18d FIN: DEC CONTADOR POP ES POP SI POP CX POP BX POP AX STI IRET ENDP RESIDE: MOV DX, offset RUTINA MOV AX, 0 MOV ES, AX MOV SI, 1Ch CLI MOV ES:[SI], DX MOV ES:[SI+2], CS STI MOV DX, offset RESIDE INT 27h END PROGRAMA
    
assembly x86-16 tasm dosbox tsr
1个回答
0
投票
为什么当我运行另一个必须中断的 .exe 时它

不工作

使用

mov si, 1Ch

,您没有设置 
int 1Ch
 的向量,而是设置 
int 07h
 的向量(保留中断)。每个中断向量占用4个字节,所以正确的指令是
mov si, 1Ch * 4

你可以稍微简化一下苦差事,因为

一个DOS函数可以为你设置中断向量。 reside部分则变为:

reside: mov dx, OFFSET rutina mov ax, 251Ch int 21h ; DOS.SetInterruptVector mov dx, OFFSET reside int 27h ; DOS.TerminateAndStayResidient
它“停止工作”的另一个原因是您允许处理程序修改 DS 段寄存器。被中断的程序不会预料到这一点!

如果依赖于 DS 的内存访问次数很少,那么可以选择使用 cs: 段覆盖前缀,而不是设置需要 4 个字节的 DS (
push ds

 
push cs
 
pop ds
 ... 
pop ds
)。
有关您的处理程序的更多信息。

当您的处理程序开始执行时,中断标志 (IF) 已被 CPU 重置。你的

cli
    指令是多余的。
  • 当处理程序结束时,
    iret
  • 指令会将中断标志恢复到触发中断时的状态。你的
  • sti
    没有用。
    您的处理程序(当前)不使用 CX 寄存器,因此不需要/没有用在堆栈上保留该寄存器。另一方面,DS ...
  • 快速回顾

您的“ESCRIBIMOS LOS MINUTOS”和“ESCRIBIMOS LOS SEGUNDOS”非常相似。这些是子程序的绝佳候选者,以避免

DRY

我还会吸收子程序中的“APLICAMOS ATRIBUTO A LAS 4 CASILLAS”: RUTINA PROC push ax push bx push si push ds push es push cs pop ds ... CONTINUE: mov ax, 0B800h mov es, ax mov al, MINUTOS mov si, 3000 call ESCRIBIMOS mov al, SEGUNDOS mov si, 3006 call ESCRIBIMOS inc SEGUNDOS mov CONTADOR, 18 FIN: dec CONTADOR pop es pop ds pop si pop bx pop ax iret ; ------------------ ; IN (al,es:si) ESCRIBIMOS: cbw ; Clears AH because AL is positive [0,59] mov bl, 10 div bl add ax, 3030h ; Make ASCII both digits at once mov bh, FONDO ; Attribute mov bl, al ; AL is tens digit mov es:[si], bx mov bl, ah ; AH is ones digit mov es:[si+2], bx ret ; ------------------ ENDP


© www.soinside.com 2019 - 2024. All rights reserved.