![]() | 第4章 奇妙的声音 | -63- | |||||||||||||||||||
请看用方框框住的程序段:程序先将BX寄存器置成0,以BX为指针分别在NOTE表和DL_TIME表内取得音符值和时间值。NOTE[BX]表示NOTE表内的第"BX"个数据,此写法和C语言中数组的表示法类似,其实NOTE本身就是一个"CHAR"类型的数组。 取到音符和时间后程序把BX寄存器加1,也就是把数组下标加1,而后将BX和AX保存到堆栈中,因为这两个寄存器下面还要使用。程序用CBW指令将音符值由"字节"转换成"字"并将其拷贝到BX中,然后再以BX为下标在FREQ数组中找到音符对应的N值。将此N值送入定时器,并将定时器和电子开关打开,此时就能听到声音。取得时钟计数值,从堆栈中弹出AX,将AH寄存器中的节拍值转成字,利用前面讲的方法完成延时后关闭定时器通道3,至此一个音符发音结束。 下面给出此程序的反汇编形式,注意指令MOV AL,NOTE[BX]被编译成MOV AL,[BX+0012],这和我们在第三章中编制的PROG3-A中的用法一样,由于标号NOTE本身就表示数组的起始地址,因此这条指令的源程序也可写成"MOV AL,[BX+NOTE]。" |
|||||||||||||||||||||
C:\ASM\>DEBUG MUSIC.COM[Enter] -u0 50[Enter] |
|||||||||||||||||||||
0A53:0000 0A53:0003 0A53:0005 0A53:0007 0A53:0009 0A53:000C 0A53:0010 0A53:0014 0A53:0015 0A53:0016 0A53:0017 0A53:0018 0A53:001A 0A53:001C 0A53:0020 0A53:0022 0A53:0024 0A53:0026 0A53:0028 0A53:002A 0A53:002C 0A53:002E 0A53:0030 0A53:0031 0A53:0033 0A53:0034 |
B84E0A 8ED8 B0B6 E643 BB0000 8A871200 8AA72D00 43 53 50 98 D1E0 8BD8 8B870000 E642 8AC4 E642 E461 0C03 E661 B400 CD1A 58 8AC4 98 03C2 |
MOV MOV MOV OUT MOV MOV MOV INC PUSH PUSH CBW SHL MOV MOV OUT MOV OUT IN OR OUT MOV INT POP MOV CBW ADD |
AX,0A4E DS,AX AL,B6 43,AL BX,0000 AL,[BX+0012] AH,[BX+002D] BX BX AX AX,1 BX,AX AX,[BX+0000] 42,AL AL,AH 42,AL AL,61 AL,03 61,AL AH,00 1A AX AL,AH AX,DX |
||||||||||||||||||
Copyright © 2004-2015 Reanimator | www.cookmoon.org |