assembly - 为什么 AL 每次都取值为零?
问题描述
al 总是将值设为零,而不是计算程序运行的时间。我必须使用时钟单元的端口 70 和 71 每 5 秒打印一次 @。
.model small
.data
.code
msg db '@ $'
lastv db 0
saver db 0
start:
mov ax, @data
mov ds, ax
PollClock:
mov al, 00h ; set operation to count seconds
out 070h, al ; set operation to count seconds
in al, 071h ; any write to 0x70 should be followed by an action to 0x71 or the RTC will be left in an unknown state
mov saver, al
mov ah, 0h
mov bl, 5h
div bl
test ah, ah ;check if reminder is zero
jnz PollClock
mov al, saver
cmp lastv, al
jne PollClock
mov dx, offset msg
mov al, 0h
mov ah, 09h
int 21h
inc lastv
jmp PollClock
mov ah, 04ch
int 21h
end start
解决方案
检查lastv
以防止在同一秒上多次循环是不正确的。
如果当前秒仍然等于最后保存的秒,它应该使用je PollClock
(注意缺少的n
)返回循环。
此外,您没有lastv
正确处理:
- 你用 0 初始化它,它是 5 的有效倍数。如果它恰好在第二个
0
(即在分钟边界上),这将使你的程序跳过第一个节拍。 - 可分性测试后您不保存它。如果您在打印后没有增加它(保持上述
jne
条件),它将使您的程序每分钟打印一次,但随着该增量,它只会打印一次(当一分钟到期时),因为未来的迭代将需要第二个既是 5 的倍数又等于 1。
你应该:
- 用一个不可能的值初始化
lastv
var(例如,一个非 5 的倍数或简单的 0ffh,它在几秒钟内超出范围) - 转换
jne
为je
- 在打印之前存储
al
into的值lastv
- 去除
inc lastv
lastv db 0ffh ;Changed and moved
...
mov al, saver
cmp lastv, al
je PollClock ;Changed
mov lastv, al ;Added
...
;inc lastv ;Commented
但在此之前,您需要将变量移动到数据段中,否则通过ds
(隐式段寄存器)访问它们不会为您提供正确的值。
这对于字符串尤其重要msg
。
额外的
CMOS 比这更复杂一些,日期格式可以是二进制或 BCD。
对于这个应用程序,它并不重要。
还有一个正在进行的日期更新位,在读取完整的日期时间之前需要检查它。
同样,在这个简单的应用程序(只读取秒数)中,这无关紧要。
最后,如果您有兴趣尝试中断驱动编程,您可以挂钩int 1ch
,由 IRQ0 处理程序 () 调用,或者在编程触发条件后int 08h
使用 IRQ8 () 线上的 CMOS 周期性中断。int 70h
还有一个等待服务(int 15h/ah=86h
),尽管这通常没有用,因为 DOS 不是多任务的。
推荐阅读
- javascript - 模态存在但正文仍在滚动
- pytest - 制作自定义测试结果
- java - 在 SpringBoot application.properties 中设置文件的相对路径不起作用
- node.js - 节点获取失败,但也可以
- javascript - Regex to match string with exact number of identifier characters
- python - 如何将 Django 项目的每个应用程序部署到不同的服务器中
- javascript - 反应上下文;子组件不重新渲染
- flutter - Flutter - 忽略系统显示尺寸设置
- python - 使用“re.findall”从字符串中提取浮点数
- ssh - 身份验证成功后关闭与堡垒主机的连接