windows - 如何在 16 位 MASM Assembly x86 中创建 sleep 函数?

标签 windows assembly sleep dos x86-16

我正在尝试在 16 位 MASM Assembly x86 中创建一个 sleep /延迟程序,也就是说,每 500 毫秒在屏幕上打印一个字符。 从我所做的研究来看,似乎有三种方法可以实现这一点 - 我想使用使用 CPU 时钟滴答的方法。

请注意,我在 Mac OS X Snow Leopard 上通过 VMWare Fusion 运行 Windows XP - 我不确定这是否会影响任何事情。

有人可以给我指出正确的方向,或者提供一段我可以调整的工作代码吗?谢谢!

我找到的代码应该每秒在屏幕上打印“A”,但不起作用(无论如何我都想使用毫秒)。

TOP:
MOV AH,2C
INT 21
MOV BH,DH  ; DH has current second
GETSEC:      ; Loops until the current second is not equal to the last, in BH
MOV AH,2C
INT 21
CMP BH,DH  ; Here is the comparison to exit the loop and print 'A'
JNE PRINTA
JMP GETSEC
PRINTA:
MOV AH,02
MOV DL,41
INT 21
JMP TOP

编辑:按照 GJ 的建议,这是一个工作程序。就叫它

DELAY PROC
 TIMER:
 MOV     AH, 00H
 INT     1AH
 CMP     DX,WAIT_TIME
 JB      TIMER
 ADD     DX,3         ;1-18, where smaller is faster and 18 is close to 1 second
 MOV     WAIT_TIME,DX
 RET
DELAY ENDP

最佳答案

这不能在纯 MASM 中完成。设置固定延迟的所有老技巧都假设您可以完全控制机器并且是 CPU 上运行的唯一线程,因此如果您等待 5 亿个周期,正好 500,000,000/f 秒将过去(对于频率为 f 的 CPU);对于 1GHz 的处理器,那将是 500 毫秒。

因为你运行在一个现代操作系统上,你正在和许多其他线程共享CPU(其中,内核——无论你做什么,你都不能优先于内核!),所以等待5亿仅您的线程 中的循环将意味着在现实世界中经过了超过 5 亿个循环。这个问题不能仅靠用户空间代码来解决;您将需要内核的合作。

解决此问题的正确方法是查找哪个 Win32 API 函数会将您的线程挂起指定的毫秒数,然后调用该函数。您应该能够直接从程序集执行此操作,可能还需要为您的链接器提供额外的参数。或者,可能有一个 NT 内核系统调用来执行此功能(我对 NT 系统调用的经验很少,老实说不知道 NT 系统调用表是什么样的,但我可能会使用 sleep 功能期待看到)。如果系统调用可用,那么从程序集发出直接系统调用可能是完成你想做的事情的最快方法;它也是最不便携的(但是,你正在编写汇编!)。

编辑:查看the NT kernel system call table ,似乎没有任何与 sleep 或获取日期和时间相关的调用(就像您的原始代码使用的那样),但是有几个系统调用来设置和查询计时器。在等待计时器达到所需延迟的同时旋转是一种有效但不优雅的解决方案。

关于windows - 如何在 16 位 MASM Assembly x86 中创建 sleep 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1858640/

相关文章:

assembly - 如何在MASM程序集中将十进制数转换为REAL10?

vb.net - 简单、无阻塞的 sleep 方式?

c# - 线程 sleep C#

c - GNU C 库是否可用于非 GNU(或 POSIX)平台?

python - sys.argv 不适用于具有先前 .py 关联的系统

c# - 在 Windows 10 C# UWP 通用 Windows 应用程序中获取用户名

python - 为什么 time.sleep() 准确性受 Chrome 影响?

windows - 在不同版本的 Windows 上测试相同版本的 IE 是否值得?

assembly - 关于 [base + index*scale + disp] 和 AT&T disp(base,index,scale) 的几个问题

assembly - x86 Assembly中的操作数大小冲突?