ITEEDU

从上面的跟踪结果我们可以看到数学运算和逻辑操作结果的符号位如果有变化,则SF标志随之改变。但是用数据传递指令和移位指令改变符号位后SF标志无变化(注意上面程序中指令MOV和ROR执行后的SF标志)。为保险起见,我们专门验证一下各类移位指令对SF的影响:

C:\ASM\>DEBUG [Enter]	
-a100[Enter]	
13CD:0100 mov ax,7fff	;AX寄存器送入7FFFH
13CD:0103 shl ax,1	;逻辑左移
13CD:0105 shr ax,1	;逻辑右移
13CD:0107 mov ax,4000	;AX寄存器送入4000H
13CD:010A rol ax,1	;循环左移
13CD:010C[Enter]	
-t      AX寄存器送入7FFFH
AX=7FFF BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13CD ES=13CD SS=13CD CS=13CD IP=0103 NV UP EI PL NZ NA PO NC
13CD:0103 D1E0 SHL AX,1    准备进行逻辑左移   注意SF标志为0

以下是逻辑左移指令的跟踪结果,可以看到符号标志位发生改变。

-t      逻辑左移的结果
AX=FFFE BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13CD ES=13CD SS=13CD CS=13CD IP=0105 NV UP EI NG NZ NA PO NC
13CD:0105 D1E8 SHR AX,1 SF标志置1

逻辑右移指令同样影响SF标志,这可以通过下面的跟踪结果看出。由此我们可以认为逻辑移位指令是可以影响SF标志的。

-t      逻辑右移的结果
AX=7FFF BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13CD ES=13CD SS=13CD CS=13CD IP=0107 NV UP EI PL NZ NA PO NC
13CD:0107 B80040 MOV AX,4000    SF标志清0

循环右移指令"ROR"并不影响SF标志,看来"ROL"指令也不会影响SF,请看下面的跟踪结果:

-t      累加器送入4000H
AX=4000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13CD ES=13CD SS=13CD CS=13CD IP=010A NV UP EI NG NZ NA PO NC
13CD:010A D1C0 ROL AX,1 循环左移指令?SF标志清0


-t      移位后的结果
AX=8000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13CD ES=13CD SS=13CD CS=13CD IP=010C NV UP EI PL NZ NA PO NC
13CD:010C 745B JZ 0169  SF标志未改变

 结果还真有些戏剧色彩,可以看到"ROL/ROR"指令对SF标志确实无影响,而"SHL/SHR"则能影响SF标志。看来不做调查研究就下结论是很不可取的。
讨论了有关SF标志的一些问题,现在我们还是回到演示程序上来。由于这个程序令终止线位置不变,而光标起始线由0FH向00H不断减小,所以当CH寄存器减至-1时程序就应该结束,所以我们使用指令JNS来判断CH寄存器减量的情况,这可以使我们不必设计单独的循环。当然使用JNZ指令也可以,只是看不到光标起始线为0时的情况。

现在我们来考虑这样两个问题:

(1)如果终止线的位置恰好在00H处会有什么现象?
(2)如果终止线不在第15线会有什么现象?

C:\ASM\>DEBUG[Enter]	
-a100[Enter]	
09DF:0100 mov ah,1	;选择10H中断的1号功能
09DF:0102 mov ch,0	;设置光标起始线为0
09DF:0104 mov cl,0	;设置光标终止线也为0
09DF:0106 int 10	;改变光标类型
09DF:0108 mov ah,1	;选择10H中断的1号功能
09DF:010A mov ch,1	;设置光标起始线为1
09DF:010C mov cl,0	;设置光标终止线为0
09DF:010E int 10	;改变光标类型
09DF:0110[Enter]
-g 100 106[Enter]      注意CX寄存器光标的起始、终止线都为0
AX=0100 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=09DF ES=09DF SS=09DF CS=09DF IP=0106 NV UP EI PL NZ NA PO NC
09DF:0106 CD10 INT 10   准备改变光标形状

 注意下面要用"P"命令跟踪INT指令的执行,不要使用"T"命令,那样DEBUG将跟踪到BIOS中去。

-p
AX=000B BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=09DF ES=09DF SS=09DF CS=09DF IP=0108 NV UP EI PL NZ NA PO NC
09DF:0108 B401 MOV AH,01

 执行过的这一小段程序将光标的起始线与终止线都设为0,跟踪完"INT 10"后我们可以看到光标跑到了字符的上面且变成了一条细线。(我是看到了,你呢?)看来第二个问题有了答案:若光标终止线位置不在字符区的最后一线,那么光标就会出现在字符区的不同位置。

-g=108 10e[Enter]  起始线在终止线以下
AX=010B BX=0000 CX=0100 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=09DF ES=09DF SS=09DF CS=09DF IP=010E NV UP EI PL NZ NA PO NC
09DF:010E CD10 INT 10

程序的后半部分设置了新的光标形状,起始线在终止线以下,不知会出现什么结果。我们来跟踪一下:

-p
AX=000B BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=09DF ES=09DF SS=09DF CS=09DF IP=0110 NV UP EI PL NZ NA PO NC
09DF:0110 08847453 OR [SI+5374],AL

由跟踪结果我们可以得出这样的结论,即当使用01H功能改变光标形状时光标终止线可以不设在字符行的最底线,但是应保证起始线在终止线上面,否则就无法知道光标会变成什么样子。笔者使用一块具有PCI接口的"S3 868"显示卡,执行后一半程序时光标被关闭,使用其它显示卡会出现什么结果可就不好说了。所以除非必要,最好还是按规矩办事。

关于光标的问题我们暂且讨论到这里,下面我们要来研究一个非常关键的问题,那就是如何清屏幕。我想我们没有任何理由认为这个问题不重要,几乎所有高级语言都提供了清屏的语句或函数,即使是DOS也提供了CLS命令。这些语句、函数以及CLS命令究竟是如何起作用的呢?这就是我们将要研究的问题。