| 
 | 
 
 
发表于 2013-3-20 16:36:17
|
显示全部楼层
 
 
 
我给个我自己打得程序你把,具体的要注意什么都有写了 
具体干什么的,上面都有写,是书本的例子吧,也有一些注释什么的 
- ;编程:实现一个子程序setscreen,为显示输出提供如下功能:
 
 - ;(0) 清屏。
 
 - ;(1) 设置前景色。
 
 - ;(2) 设置背景色。
 
 - ;(3) 向上滚动一行。
 
 - ;
 
 - ;入口参数说明:
 
 - ;(1) 用 ah 寄存器传递功能号:0 表示清屏,1表示设置前景色,2 表示设置背景色,3 表示向上滚动一行;
 
 - ;(2) 对于2、3号功能,用 al 传送颜色值,(al) ∈{0,1,2,3,4,5,6,7}
 
  
- ;程序的流程:先安装好中断程序,再执行主程序
 
 - ;1 主程序调用传递 ah,al的值,调用 int 7ch中段
 
 - ;2 跳到目标地址,选择执行的子程序 call,如果ah的值错误,直接跳到第四部
 
 - ;3 子程序执行完毕,ret返回目标地址的程序 0:200h处的中断程序
 
 - ;4 中断程序执行完毕,iret,返回主程序
 
 - ;5 主程序结束 mov ax, 4c00h      int 21h
 
  
- assume cs:code
 
  
- code segment
 
  
- do0:        
 
 -                 push bx
 
 -                 push cx
 
 -                 push dx
 
 -                 push si
 
 -                 push di
 
 -                 push ds
 
 -                 push es
 
 -                 
 
 -                 jmp short select       
 
 -                 
 
 -         table dw sub1, sub2,sub3,sub4
 
 -           
 
 - select:
 
 -                 mov dl, al
 
  
-                 cmp ah, 3
 
 -                 ja goiret      ;判断传递的是否大于 3
 
 -                 
 
 -                 mov bl, ah
 
 -                 mov bh, 0
 
 -                 add bx, bx           ;根据ah中的功能号计算对应子程序的地址在table表中的偏移
 
 -                                                 
 
 -                 call word ptr table[bx]            ;调用对应的功能子程序
 
 -                 
 
 - goiret: pop es
 
 -                 pop ds
 
 -                 pop di
 
 -                 pop si
 
 -                 pop        dx
 
 -                 pop cx
 
 -                 pop bx
 
 -                 
 
 -                 iret
 
 -                 
 
 -                 
 
 - ;功能子程序1:清屏                
 
 - sub1:   mov ax, 0b800h
 
 -                 mov es, ax
 
 -                 mov di, 0
 
 -                 mov cx, 2000
 
 -                 
 
 -   sub1s:mov byte ptr es:[di], ' '
 
 -                 add di, 2
 
 -                 loop sub1s
 
 -                 ret
 
 -                 
 
 -                 
 
 - ;功能子程序2:设置前景色                
 
 - sub2:        mov ax, 0b800h
 
 -                 mov es, ax
 
 -                 mov di, 1
 
 -                 mov cx, 2000
 
 -   sub2s:and byte ptr es:[di], 11111000b
 
 -                 or es:[di], dl
 
 -                 add di, 2
 
 -                 loop sub2s
 
 -                 ret
 
 -                 
 
  
- ;功能子程序3:设置背景色                
 
 - sub3:        
 
 -                 mov cl, 4
 
 -                 shl dl, cl
 
 -                 mov ax, 0b800h
 
 -                 mov es, ax
 
 -                 mov di, 1
 
 -                 mov cx, 2000
 
 -   sub3s:and byte ptr es:[di], 10001111b
 
 -                 or es:[di], dl
 
 -                 add di, 2
 
 -                 loop sub3s
 
 -                 ret
 
  
 
- ;功能子程序4:向上滚动一行                
 
 - sub4:        mov ax, 0b800h
 
 -                 mov ds, ax
 
 -                 mov si, 160        ;ds:si指向第n+1行
 
 -                 
 
 -                 mov es, ax       ;es:di指向第n行
 
 -                 mov di, 0
 
 -                 
 
 -                 cld 
 
 -                 mov cx, 24      ;共复制24行
 
 -   sub4s:push cx
 
 -                 mov cx, 160
 
 -                 rep movsb     ;复制
 
 -                 pop cx
 
 -                 loop sub4s
 
 -                 
 
 -                 mov cx, 80
 
 -                 mov di, 0
 
 -   sub4d:mov byte ptr es:[160*24+di], ' ' ;最后一行清空
 
 -                 add di, 2
 
 -                 loop sub4d
 
 -                 ret
 
 -                 
 
 - doends: nop                
 
  
 
- start:
 
 -                 mov ax, cs
 
 -                 mov ds, ax
 
 -                 mov si, offset do0      ;设置源地址
 
 -                 
 
 -                 mov ax, 0
 
 -                 mov es, ax
 
 -                 mov di, 200h                        ;设置目标地址
 
 -                 
 
 -                 cld                                                ;df置零
 
 -                 mov cx, offset doends - offset do0    
 
 -                 rep movsb                                 ;把do0放到目标地址 0:200h
 
 -                 
 
 -                 mov ax, 0
 
 -                 mov es, ax
 
 -                 mov word ptr es:[7ch*4], 0       
 
 -                 mov word ptr es:[7ch*4+2], 20h   ;设置中断向量表
 
 -                                                                                  ;注意:此时 cs = 20h, ip = 0
 
 -                 mov ax, 4c00h
 
 -                 int 21h
 
 -                         
 
 - code ends
 
 - end start
 
  
 
 
- ; 主程序:-------------------------------------------------------------------------------------------------------
 
 - ; assume cs:code
 
 - ; ;入口参数说明:
 
 - ; ;(1) 用 ah 寄存器传递功能号:0 表示清屏,1表示设置前景色,2 表示设置背景色,3 表示向上滚动一行;
 
 - ; ;(2) 对于2、3号功能,用 al 传送颜色值,(al) ∈{0,1,2,3,4,5,6,7}
 
 - ; code segment
 
 - ; start:
 
 -                 ; mov ah,02h
 
 -                 ; mov al,04h 
 
 -                 ; int 7ch
 
 -                 
 
 -                 ; mov ax, 4c00h
 
 -                 ; int 21h
 
 - ; code ends
 
 - ; end start
 
 - ; -----------------------------------------------------------------------------------------------------------------
 
  
 
 
 
 
 
 
- ;-------------------------------------------------------------------------------------------------------------------
 
 - ; 注意事项!!!!!!!!!: 
 
 - ; 如果安装16.4给出的功能子程序的安装程序习惯采用下面图1安装结构会出问题,问题有两个: 
 
  
- ;问题1:  table dw sub1……中SUB1存放的应该是子程序的偏移地址,这个偏移地址是相对于中断程序入口的,
 
 - ;         而此时Sub1中存放的是相对于安装程序入口的地址。所以应该将被安装代码放到code段标号Start前边。 
 
  
-         ; assume cs:code 
 
 -         ; code segment 
 
 -                 ; start: 
 
 -                         ; 安装程序 
 
 -                 ; ;-------------------------- 
 
 -                 ; 被安装代码: 
 
 -                 ; ;-------------------------- 
 
 -         ; code ends 
 
 -         ; end start 
 
 -           ; ==   图1   == 
 
 -                   
 
 - ; 问题2:在设置中断向量表的时候,0:[7ch*4]   Ip内存单元中的值应该设置为0,
 
 -                                ; 0:[7ch*4+2]  CS内存单元中的值应该设置为 20h
 
 -                                                            
 
 -                 ; 原因:这个虽然和一般设定 mov ax, 0
 
 -                                          ; mov es, ax
 
 -                                                                  ; mov word ptr es:[7ch*4], 200h
 
 -                                                                  ; mov word ptr es:[7ch*4+2], 0
 
 -                                                                  
 
 -                 ; 内存单元是一样的,都能找到目标中断程序的入口,但是,如果按照第二种方法
 
 -                 ; 在主程序调用中断程序int7的时候,
 
 -                 ; 相当于 (IP) = (n*4) = 200,(cs) = (n*4+2) = 0
 
 -                         
 
 -                 ; 于是 在执行中断程序中的 call word ptr table[bx],的过程中,当前的cs为0,ip为某个值
 
 -                 ; 这个指令相当于 push ip, jmp cs:[table+bx],cs为0,那么内存空间0:[table+bx]为未知,程序出错
 
 -                 
 
 -                 ; 如果按照第一种做法,此时cs:[table+bx], 是内存空间 20h:[table+bx], 是我们想得到的结果
 
 
  复制代码 
 
 |   
 
 
 
 |