![]() | 第2章 开始设计程序 | -23- | |||||||||||||||||||
-t | SP寄存器继续减量 | ||||||||||||||||||||
AX=1234 | BX=ABCD | CX=000A | DX=0000 | SP=FFEA | BP=0000 | SI=0000 | DI=0000 | ||||||||||||||
DS=0B01 | ES=0B01 | SS=0B01 | CS=0B01 | IP=0108 | NV UP EI PL NZ NA PO NC | ||||||||||||||||
0B01:0108 | 58 | POP AX | POP指令执行与PUSH恰好相反 | ||||||||||||||||||
执行了"PUSH BX"之后SP寄存器继续减2。 | |||||||||||||||||||||
-t | 注意AX寄存器的改变 | 执行POP指令后SP寄存器增量 | |||||||||||||||||||
AX=ABCD | BX=ABCD | CX=000A | DX=0000 | SP=FFEC | BP=0000 | SI=0000 | DI=0000 | ||||||||||||||
DS=0B01 | ES=0B01 | SS=0B01 | CS=0B01 | IP=0109 | NV UP EI PL NZ NA PO NC | ||||||||||||||||
0B01:0109 | 5B | POP BX | |||||||||||||||||||
现在指令"POP AX"执行完华,注意SP寄存器的变化,它加了2。另外看一看AX寄存器与BX的关系,究竟那个数从堆栈中跳出了呢? | |||||||||||||||||||||
-t | AX、BX寄存器内容交换 | SP寄存器复员 | |||||||||||||||||||
AX=ABCD | BX=1234 | CX=000A | DX=0000 | SP=FFEE | BP=0000 | SI=0000 | DI=0000 | ||||||||||||||
DS=0B01 | ES=0B01 | SS=0B01 | CS=0B01 | IP=010A | NV UP EI PL NZ NA PO NC | ||||||||||||||||
0B01:010A | 0883745B | OR [BP+DI+5B74],AL | |||||||||||||||||||
最后一条指令"POP BX"执行完了,我们可以很清楚地看到SP寄存器的变化情况,同时也会发现,AX寄存器和BX寄存器中的数据换了位置,这就是堆栈中数据"后进先出"的结果。 应用PUSH和POP指令时必须记住使用16位数据,PUSH AH、POP DL这样的用法都是不对的。 新增了两条指令,"救活"了一个循环,现在这个程序应该可以结束了吧?不过现在的回答仍然是否定的。 很多高级语言都不要求程序结尾必须有表示结束的语句,然而汇编语言可不行。除非你输入了要求返回DOS的指令,否则CPU是不会自行结束执行程序的。因此我们需要再学一条指令: |
|||||||||||||||||||||
![]() |
助记符:RET(Return) 用 途:从子程序返回到主程序 格 式:RET 执 行:结束子程序的执行,返回主程序 |
PROG2 0B1D:0100 MOV CX,0800 0B1D:0103 PUSH CX 0B1D:0104 IN AL,61 0B1D:0106 XOR AL,02 0B1D:0108 OUT 61,AL 0B1D:010A MOV CX,0500 0B1D:010D LOOP 010D 0B1D:010F POP CX 0B1D:0110 LOOP 0103 0B1D:0112 RET |
|||||||||||||||||||
关于这条指令的使用还有很多更深入的内容,但凭我们现在这点功底还不宜讲得过深,现在只需记住这条指令能够让我们的程序正常的结束就行了。PROG2就是程序最终改成的样子。 运行PROG2,喇叭里会发出一声鸣叫,然后屏幕上会重新出现DEBUG的提示符。改变外循环的计数值,就可以任意改变声音的长短。 |
|||||||||||||||||||||
-g=100[Enter] Program terminated normally(程序正常结束) 这个程序看来已经接近完美了,然而新的问题又出现了:想要听到0.5秒钟的声音,外循 |
|||||||||||||||||||||
Copyright © 2004-2015 Reanimator | www.cookmoon.org |