【MASM】延时

1. 代码格式

1.1 方法一

通过反复跳转实现延时。

MOV 寄存器, 跳转次数
跳转位置:
	DEC 寄存器
	JNZ 跳转位置

当跳转次数较大时,可以体现出延时的效果。要使得效果更明显,即使得延时时间更长,可以嵌套一层跳转。

MOV 寄存器1, 跳转次数1
跳转位置1:
	MOV 寄存器2, 跳转次数2
跳转位置2:
		DEC 寄存器2
		JNZ 跳转位置2
	DEC 寄存器1
	JNZ 跳转位置1

1.2 方法二

使用LOOP实现延时。

MOV CX, 循环次数
循环区间: LOOP 循环区间

1.3 方法三

调用BIOS系统功能实现延时。

MOV AH, 86H
MOV AL, 0
MOV CX, “时间”(详见2.3.2)
MOV DX, “时间”(详见2.3.2)
INT 15H

2. 解释说明

2.1 关于方法一

这种方法比较基础,貌似也比较常用。但不清楚如何确定延时的具体时间。

2.2 关于方法二

使用LOOP前,需要将循环次数存入CX寄存器中。

此方法与方法一相比使用起来较为简单,但同样不清楚如何确定延时的具体时间。

2.3 关于方法三

与方法一、二相比,此方法代码量稍大一点。但好处在于可以确定延时的具体时间。

2.3.1 功能调用

当需要进行指定时长延时的时候,可以调用BIOS系统功能,即INT 15H。在这之前,需要通过为AH寄存器赋值以指定调用对应的功能。其中,86h号功能便是延时。

2.3.2 时间参数计算方法

  1. 时间的单位为微秒(1μs = 10^-6s)
  2. 计算以微妙为单位的时长的十六进制数(例:10s = 10,000,000μs,10,000,000 = 0x 98 9680)
  3. 将十六进制数的高四位存入CX,低四位存入DX(例:10s => “MOV CX, 98HMOV DX, 9680H”)

2.3.3 补充说明

  • 参考文献[1]中,在举例说明时,是通过在数的前面加0x来表示十六进制数。然而,在MASM中,是通过在数的后面加h来表示十六进制数。
  • 根据参考文献[2],建议在写延时程序的时候加上一句MOV AL, 0(方法三第二行),不然可能出现意料之外的不稳定行为。

3. 参考文献

[1] 车子 chezi. x86汇编如何延时[EB/OL]. (2017-04-12)[2020-06-20]. https://blog.csdn.net/u013490896/article/details/70149027?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase.

[2] Stack Overflow. Problems with BIOS delay function (INT 15h / AH = 86h)[EB/OL]. (2015-12-04)[2020-06-20]. https://stackoverflow.com/questions/34089884/problems-with-bios-delay-function-int-15h-ah-86h?r=SearchResults.