ITEEDU

我尽量使每个程序都有富于趣味性的输出,不知大家对这个程序的输出结果是否有兴趣。这个程序给我们提出了两个问题:第一,为什么这一串文字是倾斜的?第二,为什么paradise一词中第二个字母a 是一个蓝方块?

答案十分简单:首先指令stosw可以让DI寄存器自动加2,因此当我们给DI加上80的时候,DI寄存器的实际增量是82,所以DI指向了下一行的下一列。大家可以修改程序给DI加上78,想想输出结果会是什么样子,然后运行程序看看实际输出和想象中是否一致。至于那个字母"a"的去向就更不用多说,我们每显示一个字符就将属性值加1,显示字符"a"时属性值恰好是11H,所以字符"a"和背影融为一体了。

这个程序十分简单,不过它很形象地说明了每个字符行与显示缓存中的80个字节的对应关系。下面这个程序稍微复杂一些,其中的子过程outchar可以接收字符的行号与列号,由它自行算出偏移量。

PARADISE.ASM
        data  segment
              assume    ds:data	;定义一个字符串
         msg  db        'Enter	into the paradise.',0	;保存当前的显示模式
        mode  db        ?
        data  ends
        code  segment
              assume    cs:code
        main  proc      far
              mov       ax,data	;初始化DS寄存器
              mov       ds,ax
			
              mov       ah,0fh	;取得当前的显示模式
              int       10h
              mov       mode,al	;保存当前的显示模式
			
              mov       ax,0001h	;设置新的显示模式为01H
              int       10h
			
              mov       dx,0	;设置第一个字符的起始位置
              mov       cx,2	;每次显示2个字符
              mov       ah,1	;设置第第一个字符的属性
              mov       si,offset msg	;SI寄存器指向字符串MSG
    dispmsg:
              lodsb     ;取得一个字符
              or        al,al	;已经到字符串结尾了吗?
              jz        exit	;已到结尾,转EXIT结束
              call      outchar	;显示AX寄存器中的字符及属性
              inc       ah	;属性字节加1
              inc       dh	;下一个字符的行、列号加1
              inc       dl
              jmp       dispmsg	;显示下一个字符
			
       exit:  mov       ah,0	;等待键盘输入
              int       16h
			
              mov       ah,0	;恢复显示模式
              mov       al,mode
              int       10h
			
              mov       ah,4ch	;结束进程
              int       21h
        main  endp
			
     outchar  proc      near	;OUTCHAR子过程
              push      es	;保存将要使用的寄存器
              push      di
              push      bx
              push      cx
              push      dx
              push      ax
			
              mov       ax,0b800h	;设置ES寄存器指向显示缓冲区
              mov       es,ax
              mov       al,dh	;字符所在行号送入AL寄存器
              mov       bh,80
              mul       bh	;计算"行号 80"
              mov       di,ax	;"行号 80"的结果送入DI寄存器
              shl       dl,1	;计算"列号 2"
              mov       dh,0
              add       di,dx	;偏移量=行号 80+列号 2
			
              pop       ax	;从堆栈中取出字符及属性
              rep       stosw	;送入显示缓冲区
			
              pop       dx	;恢复寄存器
              pop       cx
              pop       bx
              pop       di
              pop       es
              ret       ;返回
     outchar  endp
        code  ends
              end       main

助记符:MUL(Multiple)
用 途:将两个数相乘
格 式:MUL 寄存器
MUL 存储单元
执 行:指定寄存器或存储单元中的数据与累加器中的数据相乘,16位的结果

保存在累加器AX中,32位的结果由DX寄存器与AX共同保存,AX保存结
果的低16位,DX保存高16位。