汇编网首页登录博客注册
hky987654321的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
最新留言
好友圈
文章收藏
友情链接

[2013-11-13 17:09] 提交课设2作业

下面是:简版课设2、新版课设2 、原版课设2。
一、简版课设2
本程序极简,仅88行,无操作提示、清屏和检错,用户须“正确地”输入。主界面选项可键入1~4。键入3或4,均进入时钟界面,按Esc键返回。在时钟界面,按F1键变色实现功能3;按“→”键转到功能4 —— 可移动黑色光斑至“正确”位置键入,无须保存。
assume cs:code                      ;简版课设2  输入正确性由用户维护 
code segment 
        mov  bx,offset MyData       ;共275b写入软盘 
        mov  ax,cs                   
        mov  es,ax                  ;操作提示:主界面选项键入数字为1~4。 
        mov  ax,0301h               ;键入3或4,进入时钟界面,按Esc键返回, 
        mov  cx,0001h               ;功能3与功能4间的相互切换更加简单, 
        mov  dx,0000h               ;可先按F1键变色实现功能3, 
        int  13h                    ;也可先按右移键“→”转去实现功能4,
        mov  ax,4c00h               ;实现功能4后自动切换到时钟界面。
        int  21h 
MyData: jmp  short Entry                                        ;7C00h 
db '1)Reset pc 2)Start system 3)Clock 4)Set clock$2000/00/00 '  ;7C02h 
db '00:00:00$',9,9,-1,8,8,-1,7,7,-1,4,4,-1,2,2,-1,0,0,-1,-1,10h ;7C3Bh 
   Exit:je   StartSystem                                        ;7C58h 
Resetpc:jmp  dword ptr cs:[7C53h]   ;1) Reset pc 
StartSystem: sub ax,ax              ;2) Start system 
        mov  es,ax 
        mov  bx,7C00h 
        mov  ax,0201h 
        mov  cx,0001h 
        mov  dx,0080h 
        int  13h 
 Entry: mov  dx,0B800h              ;主程序入口
        mov  es,dx 
        mov  si,7C02h 
        mov  bx,12*160+34 
        call ShowString             ;显示主界面 
        sub  ax,ax 
        int  16h                    ;读、转 
        cmp  al,32h 
        jna  Exit 
    F1: cmp  al,3Bh                 ;3)Clock / 4)Set clock 
        jne  ShwTime 
        inc  dh                     ;变色,进行3)Clock操作
ShwTime:call Time                   ;显示时钟
        in   al,60h 
        cmp  al,1h                  ;Esc返回 
        je   ResetPc 
        cmp  al,4Dh                 ;右移键,进行4)Set clock操作 
        jne  F1 
ShiftRight:mov  es:[bx].1,dh        ;还原颜色 
        add  bx,2 
        inc  bp 
        mov  byte ptr es:[bx].1,0Fh ;着色 
        sub  ah,ah 
        int  16h 
        cmp  ah,4Dh                 ;右移键 
        je   ShiftRight 
        and  al,0Fh 
        mov  ch,al                  ;暂存键入数字 
        mov  al,cs:[bp-2] 
        out  70h,al 
        in   al,71h 
        cmp  byte ptr cs:[bp-2].1,-1;判断光斑所处位置为个位数或十位数
        jne  Tdigit 
        and  al,0F0h                ;抹去个位数 
Wri_in: or   al,ch 
        out  71h,al                 ;更新时钟
        jmp  ShwTime 
Tdigit: mov  cl,4 
        shl  ch,cl 
        and  al,0Fh                 ;抹去十位数 
        jmp  Wri_in 
  Time: mov  bp,7C32h               ;① Time子程序 (任务:显示时间) 
Time_s: mov  al,cs:[bp].18 
        out  70h,al 
        in   al,71h 
        mov  cs:[bp],3030h 
        sub  ah,ah 
        div  byte ptr cs:[7C57h]    ;与10h相除,分离十位数和个位数
        add  cs:[bp],ax             ;得到时钟的ASCII形式
        add  bp,3 
        cmp  bp,7C44h 
        jb   Time_s  
        mov  bx,14*160+62
        mov  si,7C30h 
ShowString:  mov  dl,cs:[si]        ;② ShowString子程序 (任务:显示字符串)
        inc  si 
        cmp  dl,'$' 
        je   Ok
ShwStr: mov  es:[bx],dx
        add  bx,2 
        jmp  ShowString
    Ok: mov  bx,14*160+62 
        ret 
code ends
end
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
二、新版课设2
assume cs:code
code segment
        mov ax,cs                   ;设置es
        mov es,ax
        mov bx,offset Boot          ;es:bx指向将写入磁盘的数据
        mov ax,0303h                ;3号子程序写入扇区;扇区数量3
        mov cx,0001h                ;磁道号0;扇区号1
        mov dx,0000h                ;磁头号0;驱动器号0 软盘A
        int 13h                     ;int 13h中断例程;成功则(ah)=0
        mov ax,4c00h                ;返回
        int 21h
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Boot:
        mov ax,0                    ;设置es
        mov es,ax
        mov bx,7e00h                ;es:bx指向接收扇区数据的内存区
        mov ax,0202h                ;2号子程序读取扇区;扇区数量2
        mov cx,0002h                ;磁道号0;扇区号2
        mov dx,0000h                ;磁头号0;驱动器号0 软盘A
        int 13h                     ;int 13h中断例程
        jmp bx                      ;将cs:ip指向0:7e00
        db 510-($-Boot) dup(0)      ;填充扇区空余部分
        dw 0aa55h                   ;引导标志置于本扇区末
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
My_data:                          ; <ⅰ> 程序数据区
    jmp near ptr My_code          ; 首址 7e00h,本指令占3个字节
dw  0,0ffffh                      ; 首址 7e03h = 7e00h + 3h
db 'Home page','$'        ;界面名称 首址 7e07h = 7e03h + 4h
db '1) Reset pc','$'    ;重启计算机 首址 7e11h = 7e07h + ah
db '2) Start system','$';引导现系统 首址 7e1dh = 7e11h + ch
db '3) Clock','$'     ;进入时钟程序 首址 7e2dh = 7e1dh + 10h
db '4) Set clock','$'     ;设置时间 首址 7e36h = 7e2dh + 9h
db 'Type 1 to 4.','$'     ;操作提示 首址 7e43h = 7e36h + dh
db 'Choice: ','$'     ;选项输入位置 首址 7e50h = 7e43h + dh
db 'Clock','$'            ;界面名称 首址 7e59h = 7e50h + 9h
db 'Set clock','$'        ;界面名称 首址 7e5fh = 7e59h + 6h
                                  ; Clock 操作提示
db 'You can press F1 or Esc.','$' ; 首址:7e69h = 7e5fh + ah
                                  ; Set clock 操作提示1
db 'You can press -> , <- ,type 0 to 9 .','$';首址:7e82h = 7e69h + 19h
                                  ; Set clock 操作提示2
db 'Press Enter or Esc.','$'      ; 首址 7ea7h = 7e82h + 25h
                                  ; Adr——时钟单元地址表
db 9 , 8 , 7 , 4 , 2 , 0          ; 首址 7ebbh = 7ea7h + 14h
                                  ; Tim——时钟记录等
db '2000/00/00 00:00:00$',0,1,7,0 ; 首址 7ec1h = 7ebbh + 6h
                                  ; 尾址 7ed8h = 7ec1h + (18h-1h)
                ;Tim[0~18]时钟字符 Tim[19]='$',结束标识
     ;Tim[20]按F1、Esc的次数,初值0 Tim[21]初值1为非F1态,置0为F1态
        ;Tim[22]为颜色值,初始化为7 Tim[23]为光标位置值,初始化为0

My_code:                  ;<ⅱ> 程序代码区
        mov bx,0b800h     ;设置es
        mov es,bx
        mov dx,'cl'       ;清屏入口参数
        call Ornament     ;清屏
        mov si,7e07h      ;读取“Home page”首址
        mov bx,0007h      ;第0页;黑底白字
        mov dx,0410h      ;第4行;第16列
Home_s: call Show_String  ;显示字符串
        mov dl,32         ;显于中部
        cmp si,7e59h      ;是否显示完“Home page”界面
        je My_type        ;是,跳出循环
        cmp si,7e11h      ;是否正要读写首选项
        je ad_lin         ;是,增空行
        cmp si,7e43h      ;是否正要读写选择提示语
        jne next          ;否,输出下一行
ad_lin: add dh,4          ;是,多增一空行
        jmp Home_s        ;显示字符串
  next: add dh,2          ;行号增2,产生行间隔
        jmp Home_s        ;显示字符串

My_type:mov ah,0          ;0号子程序
        int 16h           ;读取键入值
        cmp al,34h        ;与4号比较
        je ca_S_ck        ;相等,执行 4) Set clock
        cmp al,33h        ;与3号比较
        je Clock          ;相等,执行 3) Clock
        cmp al,32h        ;与2号比较
        je c001_csip_7c00 ;相等,执行 2) Start system
        cmp al,31h        ;与1号比较
        je csip_ffff      ;相等,执行 1) Reset pc
        jmp My_type       ;无匹配,重新键入

ca_S_ck:call Set_clock    ;转“4) Set clock”
        jmp My_code       ;完成,返回
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;功能选项子程序
;1) Reset pc
    csip_ffff: jmp dword ptr cs:[7e03h] ;将cs:ip指向ffff:0

;2) Start system
    c001_csip_7c00:
        mov ax,0
        mov es,ax
        mov bx,7c00h      ;es:bx指向接收扇区数据的内存区
        mov ax,0201h      ;2号子程序读取扇区;扇区数
        mov cx,0001h      ;磁道号;扇区号
        mov dx,0080h      ;磁头号;驱动器号80 硬盘C
        int 13h           ;int 13h中断例程
        jmp bx            ;cs:ip指向0:7c00,退出课设2

;3) 名称:Clock
;   任务:动态显示时钟,按下F1变色,按下Esc返回
;   参数:无
;   返回:无
Clock:  call Interface    ;1、“贴上”祥云、界面名称、操作提示

Cok_s:  call Time         ;2、显示Clock
        mov ah,1          ;1号子程序
        mov cx,2000h      ;光标形式(偷学)
        int 10h           ;隐藏光标

        in al,60h         ;3、动态时钟、变色及退出
        cmp al,1h         ;Esc扫描码
        je Out_cyc        ;退出循环
        cmp al,3bh        ;F1扫描码
        je Chg_cl         ;去实现按F1变色
        mov ah,1          ;nonF1(非F1)态,值为1
        mov cs:[7ed6h],ah ;(Tim[21])=1,记下nonF1
        jmp Cok_s         ;新循环
Chg_cl: mov ah,cs:[7ed6h] ;非F1态为1,F1态为0
        add cs:[7ed5h],ah ;与Tim[20]相加,得按下F1的次数
        mov al,cs:[7ed5h] ;取出按下F1的次数
        mov ah,0          ;置0
        mov cs:[7ed6h],ah ;(Tim[21])=0,记下isF1态
        mov bl,8          ;除数值
        div bl            ;相除
        mov al,ah         ;余数变幅为0~7
        cmp al,0          ;为0否
        jne Su_col        ;否,转Su_col
        mov al,4          ;是,调整0(黑)为4(红)
Su_col: or al,00001000b   ;调整颜色属性为高亮
        mov cs:[7ed7h],al ;转存于Tim[22]
        call Change_Color ;实现受控变色
        jmp Cok_s         ;新循环

Out_cyc:add byte ptr cs:[7ed5h],1  ;4、清空缓冲区;加1次Esc,得次数总和
        cmp byte ptr cs:[7ed5h],15 ;容量与次数比较
        jna Emp_syb                ;不大于,转清空
        mov byte ptr cs:[7ed5h],15 ;置15
Emp_syb:mov ah,0                   ;0号子程序
        int 16h                    ;清空缓冲区
        dec byte ptr cs:[7ed5h]    ;减记录
        cmp byte ptr cs:[7ed5h],0  ;清空否
        ja Emp_syb                 ;否,继续清空

        mov ah,01h                 ;5、复原及结束;01号子程序
        mov cx,1213h               ;光标形式
        int 10h                    ;复原隐藏光标(偷学)
        mov al,7h                  ;白色
        call Change_Color          ;复原颜色
        mov byte ptr cs:[7ed7h],7h ;复原Tim[22]的颜色属性值
        jmp My_code                ;返回

; 4) 名称:Set_clock
;    任务:显示“一点红尘戏黑白”时钟式样,设置时钟并返回
;    参数:无
;    返回:无
Set_clock:
        call Interface       ;1、“贴上”祥云、界面名称、操作提示

        mov di,'CC'          ;2、显示时钟并着色首个“光标处字符”
Stc_s:  call Time            ;调用时钟
        mov ah,01            ;01号子程序
        mov cx,2000h         ;光标形式
        int 10h              ;隐藏光标

 H_key: mov ah,0             ;3、光标移动,字符着色及流程控制
        int 16h              ;读取键盘输入
        cmp ah,4dh           ;“→”扫描码
        jne Curs_L           ;否,转Curs_L
        inc dl               ;是,光标位置值增1右移1
        jmp Sh_Cur           ;转Sh_Cur,着色新光标处字符
Curs_L: cmp ah,4bh           ;“←”扫描码
        jne Ok               ;否,转继续判读
        dec dl               ;是,光标位置值减1左移1
Sh_Cur: mov si,7ec1h         ;cs:si指向Tim首址
        call Show_String     ;着色“光标处字符”
        jmp H_key            ;键入新符号
    Ok: cmp ah,1ch           ;“Enter”扫描码
        je Stc_s             ;是,查看“新”时钟
        cmp ah,1h            ;“Esc”扫描码
        je Over              ;是,退出

        cmp dl,33            ;4、光标处性质判断;(dl)=光标列值
        jb H_key             ;小于首个十位数位置值,转待输入
        cmp dl,49            ;与最后个位数位置值比较
        ja H_key             ;大于,转待输入
        mov bh,0             ;置0
        mov bl,dl            ;光标转存
        mov bp,bx            ;光标分存
        sub bx,33            ;减初值,得该数在Tim上对应位置
        mov si,ax            ;暂寄
        mov ax,bx            ;16位被除数
        mov ch,3             ;8位除数
        div ch               ;相除,商(al)为Adr上时钟单元地址之地址
        cmp ah,2             ;余数值0,1和2代表十位数,个位数和不可输入
        je H_key             ;相等则该处不可输入,转待输入
        mov cx,ax            ;转存相除结果
        mov ax,si            ;还原

        cmp al,30h           ;5、过滤和显示数字
        jb H_key             ;小于'0',转待键入
        cmp al,39h           ;与'9'比较
        ja H_key             ;大于'9',转待键入
        mov cs:[bx].7ec3h,al ;键入数字分存Tim[bx]备用
        add bp,bp            ;字节数加倍成字符位置值
        add bp,1920          ;加上160*12,得字符显示位置
        mov es:[bp],al       ;显示键入数字

        and al,00001111b     ;6、更新时钟数据;脱去ASCII码
        cmp ch,1             ;是否为个位数处的余数值
        je Digit             ;是,转Digit
        mov ah,al            ;否,让ah统存十位数,al统存个位数
        mov al,cs:7ec3h[bx].1;十位数地址加1,取Tim对应个位数
        sub al,30h           ;脱去ASCII码,得低4位的纯个位数
        jmp Wri_in           ;转Wri_in,写入更新数据
 Digit: sub bx,1             ;个位数地址减1,得Tim对应十位数地址
        mov ah,cs:7ec3h[bx]  ;从Tim取出该十位数,统存ah
        sub ah,30h           ;脱去ASCII码,得纯十位数
Wri_in: mov si,cx            ;及时取出相除结果
        and si,00ffh         ;得时钟单元地址之地址
        mov cl,4             ;移位值
        shl ah,cl            ;将该十位数置于高4位
        or  ah,al            ;高4位和低4位合成BCD码
        mov al,cs:7ebbh[si]  ;从Adr读取时钟单元地址
        out 70h,al           ;把地址写入
        mov al,ah            ;取出更新数据的BCD码
        out 71h,al           ;把该BCD码写入
        jmp H_key            ;继续键入

  Over: mov ah,01h           ;7、相关恢复及结束;01号子程序
        mov cx,1213h         ;光标形式
        int 10h              ;复原隐藏光标
        sub di,di            ;清0,除去着色标识
        ret

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;辅助程序
;① 名称:Ornament (辅助程序)
;   任务:清屏、装饰界面(制符号图案)
;   参数:(ah)=颜色属性,(al)=装饰符号,(bx)=装饰起点,(cx)=循环次数
;         (dx)='cl'清屏,否则装饰其他符号,(di)=“装饰宽度”
;   返回:无
Ornament:
        push ax
        push si
        sub si,si          ;置0,存放行内寻址增量
        cmp dx,'cl'        ;有“清屏”信息否
        jne Ors            ;无,执行其它装饰功能
        mov bx,0           ;有,从0开始“清屏”
        mov cx,2000        ;循环次数置为25*80
        mov al,' '         ;清屏“擦头”
        mov ah,7           ;不设为0,避免“黑屏”
        mov di,158         ;“清屏宽度”
   Ors: mov es:[bx][si],ax ;显示需装饰字符
        cmp si,di          ;与“装饰宽度”比较
        jb Or_ok           ;小于,则继续行内寻址
        sub si,si          ;否则,换行,寻址增量置0
        add bx,160         ;基址加1行
        jmp go_cyc         ;转去循环
 Or_ok: add si,2           ;寻址增量2
go_cyc: loop Ors           ;loop循环
        pop si
        pop ax
        ret

; ② 名称:Show_String (辅助程序)
;    任务:显示字符串 ,着色时钟“光标处字符”
;    参数:(bl)=字符颜色属性,(bh)=页号,(dl)=列号
;          (dh)=行号,cs:si指向字符串,'$'=结束标识
;          (di)='CC',表示“光标处字符”的标记
;    返回:无
Show_String:
        push cx            ;入栈保护
        mov cs:[7ed8h],dl  ;将光标值保存于Tim[23]
        cmp di,'CC'        ;有无'CC'
        jne sh_str         ;无,直接显示该字符串
        mov dl,31          ;有,重置光标值
s_sr_s: mov bl,cs:[7ed7h]  ;从Tim[22]读取颜色值
        cmp dl,cs:[7ed8h]  ;光标当前值与保存值比较
        jne sh_str         ;不等,则直接显示该字符
        mov bl,01011111b   ;等,则重置颜色属性
sh_str: mov al,cs:[si]     ;读取字符
        inc si             ;寻址增1;(si)有时跨行传递,故不入栈
        cmp al,'$'         ;是否读到本行结束标识
        je sh_str_over     ;是,转结束
        mov ah,2           ;否,显示字符;置光标
        int 10h            ;调用int 10h
        mov ah,9           ;显示字符
        mov cx,1           ;字符重复显示1次
        int 10h            ;调用int 10h
        inc dl             ;字符列号增1
        jmp s_sr_s         ;继续读写
sh_str_over:
        mov dl,cs:[7ed8h]  ;恢复光标值
        pop cx             ;出栈恢复
        ret

; ③ 名称:Interface (辅助程序)
;    任务:为Clock子程序、Set clock子程序提供界面装饰
;    思路:清屏—>“贴”矩形面—>“擦掉”内部—>“分隔条”—>“贴”字符串
;    参数:(al)=33h,制作Clock界面;(al)=34h,制作Set clock序界面
;    返回:无
Interface:
        cmp al,34h         ;选项为'3'或'4'
        je  set_4
        mov si,7e59h       ;选项3,读取“Clock”首址
        mov bp,7e69h       ;读取操作提示首址
        mov dx,001dh       ;暂存操作提示列号空缺配数0、列号29,
        push dx            ;列号入栈备用
        jmp mak_fa
set_4:  mov si,7e5fh       ;选项4,读取“Set clock”首址
        mov bp,7e82h       ;读取第一条操作提示首址
        mov dx,1f17h       ;暂存操作提示2、1的列号31、23
        push dx            ;列号入栈备用
mak_fa: mov dx,'cl'        ;制作界面;清屏入口参数
        call Ornament      ;“擦干净”屏幕
        mov dx,0           ;置0,使Ornament功能非清屏
        mov ah,cs:[7ed7h]  ;从Tim[22]读取颜色属性值
        mov al,'%'         ;“贴上”的符号
        mov bx,1154        ;“贴”符号的起点位置160*7+34
        mov di,90          ;“装饰宽度”,从0起算占92个字节
        mov cx,506         ;“粘贴”符号所需循环次数46*11
        call Ornament      ;形成“矩形面”
        mov al,' '         ;“擦头”
        mov bx,1314        ;“擦掉”的起点位置160*8+34
        mov di,90          ;“擦掉”宽度
        mov cx,414         ;“擦掉”次数46*9
        call Ornament      ;制成两条祥云图案“分隔条”
        mov bl,cs:[7ed7h]  ;从Tim[22]读取颜色属性值
        mov bh,0           ;页号
        mov dx,030bh       ;行号3,列号11
        call Show_String   ;“贴上”界面名称
        pop cx             ;列号出栈
        mov si,bp          ;取出操作提示首址
        mov dh,20          ;行号
        mov dl,cl          ;列号
ca_shw: call Show_String   ;“贴上”操作提示
        cmp si,7ea7h       ;是否寻到 Set clock 操作提示2首址
        jne over_face      ;否,则已完成提示语读写,转结束
        mov dh,22          ;Set clock 操作提示2行号
        mov dl,ch          ;Set clock 操作提示2列号
        jmp ca_shw
over_face:
        ret

; ④ 名称:Time (辅助程序)
;    任务:1、从CMOS读取时间信息,以“年/月/日 时:分:秒”格式存于Tim数据区
;          2、显示时钟字符形式
;    参数:无
;    返回:无
Time:   sub bx,bx
        sub bp,bp
Time_s: mov al,cs:[bx].7ebbh             ;1、从Adr取出时钟单元地址
        out 70h,al                       ;将地址传到地址端口70h
        in  al,71h                       ;取出时钟十位及个位“混合数”
        mov word ptr cs:[bp].7ec3h,3030h ;清'0',除旧待新
        or  cs:[bp].7ec4h,al             ;将“混合数”分存Tim[bp].3
        and byte ptr cs:[bp].7ec4h,3fh   ;将分存者纯化为(30h + 个位)
        sub ah,ah                        ;置0
        add ax,ax                        ;得(ax)×2 ;分离“混合数”
        add ax,ax                        ;得(ax)×4,继续分离
        add ax,ax                        ;得(ax)×8,继续分离
        add ax,ax                        ;“混合数”分离,ah得纯十位数
        add cs:[bp].7ec3h,ah             ;传十位数到Tim[bp].2得ASCII码
        inc bx                           ;单元寻址增1
        add bp,3                         ;存储寻址增3
        cmp bx,6                         ;是否读完6个单元
        jb  Time_s                       ;未读完,继续

        mov bl,cs:[7ed7h]                ;2、从Tim[22]取颜色
        mov bh,0                         ;页号
        mov dx,0c1fh                     ;行号12;列号31
        mov si,7ec1h                     ;从Tim[0]读取Clock
        call Show_String                 ;“贴上”时钟字符
        ret

; ⑤ 名称:Change_Color (辅助程序)
;    任务:设置屏幕前景色
;    参数:(al)=颜色属性
;    返回:无
Change_Color:
        mov bx,1                         ;颜色属性寻址初始化为1
        mov cx,2000                      ;循环次数25*80
   Ccs: and byte ptr es:[bx],11111000b   ;前景抹“黑”待新,背景依旧
        or es:[bx],al                    ;显示颜色属性新值
        add bx,2
        loop Ccs
        ret

code ends
end
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
三、原版课设2
assume cs:code   
code segment   

        mov ax,cs                    ;设置es   
        mov es,ax   
        mov bx,offset Boot           ;es:bx指向将写入磁盘的数据   
                                       
        mov al,4                     ;扇区数量,用debug另算得   
        mov ch,0                     ;磁道号   
        mov cl,1                     ;扇区号   
        mov dl,0                     ;驱动器号,软盘A   
        mov dh,0                     ;磁头号   
        mov ah,3                     ;3号子程序,写入扇区   
        int 13h                      ;int 13h中断例程;成功则(ah)=0   

        mov ax,4c00h                 ;返回  
        int 21h   

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  

Boot:           
        jmp short Boot_b             ;首址:7c00h,本指令占2个字节   
          
        dw 7e00h,0                   ;首址:7c02h = 7c00h + 2h    
                                      
Boot_b: mov ax,cs                    ;设置ds   
        mov ds,ax   
        mov ax,0                     ;设置es  
        mov es,ax   
        mov bx,7e00h                 ;es:bx指向接收扇区数据的内存区   
                           
        mov al,3                     ;扇区数量   
        mov ch,0                     ;磁道号   
        mov cl,2                     ;扇区号   
        mov dl,0                     ;驱动器号,软盘A   
        mov dh,0                     ;磁头号   
        mov ah,2                     ;2号子程序,读取扇区数据   
        int 13h                      ;int 13h中断例程   
                                                   
        jmp dword ptr ds:[7c02h]     ;将cs:ip指向0:7e00   
                                    
        db 510-($-Boot) dup(0)       ;填充扇区空余部分    
        dw 0aa55h                    ;置引导标志于本扇区最后两字节   

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   

 Main:     
        jmp near ptr Run           ;  首址:7e00h,本指令占3个字节   
    
dw  0,0ffffh        ;<ⅰ> 程序数据区  首址:7e03h = 7e00h + 3h     
dw  7c00h,0          ;存储0:7c00地址  首址:7e07h = 7e03h + 4h   
        
db 'Home page','$'         ;界面名称  首址:7e0bh = 7e07h + 4h   
db '1) Reset pc','$'     ;重启计算机  首址:7e15h = 7e0bh + ah     
db '2) Start system','$';引导现有操作系统  首址:7e21h =  7e15h + ch     
db '3) Clock','$'      ;进入时钟程序  首址:7e31h = 7e21h + 10h     
db '4) Set clock','$'      ;设置时间  首址:7e3ah = 7e31h + 9h 
db 'Type 1 to 4.','$'      ;操作提示  首址:7e47h = 7e3ah + dh 
db 'Choice: ','$'      ;选项输入位置  首址:7e54h = 7e47h + dh   

db 9,0,0,8,0,0,7,0,0,4,0,0,2,0,0,0,0,0;Adr:时钟单元地址表   
                                   ;  首址:7e5dh = 7e54h + 9h    
db '2000/00/00 00:00:00','$',0,1,7,0; Tim :记录时钟等,详如下:  
                                   ;  首址:7e6fh = 7e5dh + 12h   
;Tim[0~18]时钟字符;Tim[19]='$',结束标识   
;Tim[20]压下F1、Esc次数,初值0;Tim[21]初值1,为非F1态,置0为F1态;   
;Tim[22]为颜色值,初始化为7;Tim[23]为光标位置值,初始化为0。   

db 0  ;Csk——字符栈  已不用,但保留  首址:7e87h = 7e6fh + 18h   
db 0                    ;top——栈顶  首址:7e88h = 7e87h + 1h   

db 33,36,39,42,45,48  ;cp1:可输入光标位置1,十位数    
                                   ;  首址:7e89h = 7e88h + 1h   
db 34,37,40,43,46,49  ;cp2:可输入光标位置2,个位数    
                                   ;  首址:7e8fh = 7e89h + 6h   
db 9 ,8 ,7 ,4 ,2 ,0   ;cun:时钟单元端口地址           
                                   ;  首址:7e95h = 7e8fh + 6h   

db 'You can press F1 or Esc.','$'  ;  Clock 操作提示     
                                   ;  首址:7e9bh = 7e95h + 6h   
db 'You can press -> , <- ,type 0 to 9 .','$' ; Set clock 操作提示1 
                                   ;  首址:7eb4h = 7e9bh + 19h   
db 'Press Enter or Esc.','$'       ;  Set clock 操作提示2    
                                   ;  首址:7ed9h = 7eb4h + 25h     
db 'Clock','$'             ;界面名称  首址:7eedh = 7ed9h + 14h   
db 'Set clock','$'         ;界面名称  首址:7ef3h = 7eedh + 6h     
                                   ;  尾址:7efch = 7ef3h + (10-1)h   

Run:
        mov bx,cs         ;<ⅱ> 程序代码区;设置ds   
        mov ds,bx                                
        mov bx,0b800h     ;设置es   
        mov es,bx
 
        mov dx,'cl'       ;设置清屏入口参数
        call Ornament     ;调用装饰美化程序——清屏
        mov si,7e0bh      ;读取字符串“Home page”首址   
        mov bl,7          ;显示为黑底白字
        mov bh,0          ;第0页
        mov dh,6          ;第6行
Home_s: mov dl,20         ;第20列
        cmp dh,8          ;当前行号与预设第二行行号比较
        jb ca_s_s         ;当前为首行,则不调整列号
        mov dl,32         ;从第二行开始,字符串显示于屏幕中部   
ca_s_s: call show_string  ;字符串显示   
        cmp dh,20         ;比较当前行号与最后一行行号   
        je My_type        ;相等,则已完成字符串显示,跳出循环 
        cmp dh,14         ;比较是否完成选项读写
        jne next          ;未完,继续
        add dh,4          ;完成,则增设一个空行
        jmp Home_s        ;转去显示下一行字符串
  next: add dh,2          ;不等,则行号增2,同时产生空行间隔
        jmp Home_s        ;转去显示下一行字符串

My_type:mov ah,0          ;设置0号子程序
        int 16h           ;用int 16h读取键入的选项序号
        cmp al,34h        ;读取值与4号选项序号的ASCII码作比较
        je ca_S_ck        ;相等,则转去执行 4) Set clock
        cmp al,33h        ;读取值与3号选项序号的ASCII码作比较
        je Clock          ;相等,则转去执行 3) Clock
        cmp al,32h        ;读取值与2号选项序号的ASCII码作比较 
        je c001_csip_7c00 ;相等,则转去执行 2) Start system 
        cmp al,31h        ;读取值与1号选项序号的ASCII码作比较 
        je csip_ffff      ;相等,则转去执行 1) Reset pc 
        jmp My_type       ;读取值与所有选项均不匹配,则转去重新键入新值 

ca_S_ck:call Set_clock    ;转到“4) Set clock”进行处理
        jmp near ptr Run  ;完成处理后,返回主界面

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
;功能选项子程序 

;1) Reset pc

    csip_ffff: jmp dword ptr ds:[7e03h]   ;将cs:ip指向ffff:0  

;2) Start system

    c001_csip_7c00: 

        mov ax,0 
        mov es,ax
        mov bx,7c00h       ;es:bx指向接收扇区读入数据的内存区 
          
        mov al,1           ;读取扇区数   
        mov ch,0           ;磁道号   
        mov cl,1           ;扇区号   
        mov dl,80h         ;驱动器号,C盘   
        mov dh,0           ;磁头号   
        mov ah,2           ;2号子程序,读取扇区数据   
        int 13h            ;int 13h中断例程   

jmp dword ptr ds:[7e07h]   ;将cs:ip指向0:7c00,从系统课设2退出   

;3) 名称:Clock   
;   任务:动态显示时钟,按下F1变色,按下Esc返回   
;   参数:无   
;   返回:无   
Clock:   
        push ax            ;1、入栈保存   
        push bx   
        push cx   
        push dx   
           
        call Interface     ;2、“贴上”边框、界面名称、操作提示   

Cok_s:  call Time          ;3、显示Clock的字符形式   
        mov ah,01          ;设置01号子程序   
        mov cx,2000h       ;设置光标形式   
        int 10h            ;用int 10h,使光标隐藏   
                                 
        in al,60h          ;4、动态时钟、变色及停止动态显示;读取键盘输入   
        cmp al,1h          ;判断从60h端口传出的信息,是否为Esc键扫描码   
        je Out_cyc         ;是,则退出循环,停止动态显示   
        cmp al,3bh         ;判断从60h端口传出的信息,是否有F1键扫描码   
        je Cg_col          ;是,则转到Cg_col,去实现按下F1键变色   
        mov ah,1           ;否,则设置nonF1(非F1)态,值为1   
        mov cs:[7e84h],ah  ;设置Tim[21]值,标记当前循环为nonF1态   
        jmp Cok_s          ;转到Cok_s,开始新一轮循环,产生动态效果  
Cg_col: mov ah,cs:[7e84h]            ;取Tim[21]值,其值非F1态为1,F1态为0  
        mov byte ptr cs:[7e84h],0    ;Tim[21]置0,作当前循环为F1态的标记  
        add cs:[7e83h],ah            ;与Tim[20]相加,使按1次F1,记录增1次  
        mov al,cs:[7e83h]            ;取出按下F1的次数                   
        mov ah,0                     ;置0,得16位被除数   
        mov bl,8                     ;除数值为8   
        div bl                       ;相除,除数为8位   
        mov al,ah                    ;取余数,其变幅为0~7   
        cmp al,0                     ;判断值是否为0   
        jne Su_col                   ;不为0,转Su_col  
        mov al,4                     ;为0,调整0(黑)为4(红),使变幅为7色   
Su_col: or al,00001000b              ;调整为具有高亮的颜色属性   
        call Change_color            ;调用变色辅助程序,实现受控变色    
        mov cs:[7e85h],al            ;将颜色属性值转存Tim[22]   
        jmp Cok_s                    ;转到Cok_s,开始新一轮循环,产生动态效果
          
Out_cyc:add byte ptr cs:[7e83h],1    ;5、清空缓冲区;加1次Esc,得键入次数总和
        cmp byte ptr cs:[7e83h],15   ;比较缓冲区容量15与键盘输入次数 
        jna Emp_syb                  ;不大于15,则直接转Emp_syb清空缓冲区  
        mov byte ptr cs:[7e83h],15   ;否则置为15  
Emp_syb:mov ah,0                     ;设置0号子程序  
        int 16h                      ;用1nt 16h,清空F1和Esc缓冲区记录  
        dec byte ptr cs:[7e83h]      ;读取1个,则自减1个记录  
        cmp byte ptr cs:[7e83h],0    ;判断是否清空键盘缓冲区  
        ja Emp_syb                   ;大于0,则继续执行清空    
           
        mov ah,01h                   ;6、执行相关复原;设置01号子程序    
        mov cx,1213h                 ;设置光标形式   
        int 10h                      ;用int 10h,使隐藏光标复原   
        mov al,7h                    ;设置颜色属性为白色   
        call Change_color            ;调用辅助程序,复原颜色   
        mov byte ptr cs:[7e85h],7h   ;复原记于Tim[22]的颜色属性值   
          
        pop dx                       ;7、结束;出栈恢复   
        pop cx 
        pop bx  
        pop ax  
        jmp near ptr Run             ;返回主界面   

; 4) 名称:Set_clock   
;    任务:显示“一点红尘戏黑白”时钟设置界面,设置时钟并返回主界面   
;    参数:无   
;    返回:无   
Set_clock:    
        push bx              ;1、开始;入栈保护   
        push dx   
        push di   
        push si   
                                              
        call Interface       ;2、“贴上”边框、界面名称、操作提示   
                           
Stc_s:  call Time            ;3、设置光标字符颜色;调用时钟备查  
        mov ah,01            ;设置01号子程序    
        mov cx,2000h         ;设置光标形式    
        int 10h              ;用int 10h,使光标隐藏     
        mov bh,0             ;第0页    
        mov dh,12            ;行号    
        mov dl,31            ;列号,光标位置初始化为不可输入处    
Sh_Cur: mov di,'CC'          ;设置“光标处字符”的标记'CC'    
        mov si,7e6fh         ;使ds:si指向将输出的时间字符串Tim首址    
        call Show_string     ;调用Show_string,着色“光标处字符”    
                         
ca_Res: call Reset           ;4、移光标、改时钟,显重设及退出;调Reset    
        cmp ah,1ch           ;判断是否读到“Enter”键的扫描码    
        je Stc_s             ;读到,则转去查看时钟重设结果    
        cmp ah,1h            ;判断是否读到“Esc”键的扫描码    
        je Cursor_Ok         ;读到,则转结束    
        cmp ah,4dh           ;判断是否读到“→”的扫描码    
        jne Curs_L           ;未读到“→”,则转Curs_L    
        inc dl               ;读到,则光标位置值自增1,使其右移1    
        jmp Sh_Cur           ;转到Sh_Cur,使新光标处字符着色    
Curs_L: cmp ah,4bh           ;判断是否读到“←”的扫描码    
        jne ca_Res           ;未读到,转ca_Res,待键入    
        dec dl               ;读到,则光标位置值自减1,使其左移1    
        jmp short Sh_Cur     ;转到Sh_Cur,使新光标处字符着色    

Cursor_Ok:   
        mov ah,01h           ;5、相关恢复及结束;设置01号子程序     
        mov cx,1213h         ;设置光标形式    
        int 10h              ;用int 10h,使隐藏光标复原     
        pop si               ;出栈恢复    
        pop di    
        pop dx    
        pop bx    
        ret    
                              
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   
;辅助程序   

;① 名称:Ornament (辅助程序)                   
;   任务:清屏、装饰美化界面(制作矩形框)   
;   参数:(ah)=颜色属性,(al)=装饰符号   
;         (bx)=装饰首址,(cx)=循环次数   
;         (dx)='cl'则清屏,否则装饰其他符号,(di)=“装饰宽度”   
;   返回:无   
Ornament:                          
        push ax   
        push bx   
        push cx   
        push di   
        push si     
          
        sub si,si           ;置0,用于存放行内寻址增量   
        cmp dx,'cl'         ;与“清屏”信息的值相比较   
        jne Ors             ;不等,则去执行其它装饰功能  
        mov bx,0            ;等,则“清屏”;基址初始化为0  
        mov cx,2000         ;循环次数置为25*80   
        mov al,' '          ;设置清屏“擦头”   
        mov ah,7            ;颜色值不设为0,避免“黑屏”   
        mov di,158          ;设置“清屏宽度”   
   Ors: mov es:[bx][si],ax  ;将装饰字符传到显示缓冲区   
        cmp si,di           ;与“装饰宽度”比较   
        jb Or_ok            ;小于,则继续行内寻址   
        sub si,si           ;否则,换行,寻址增量置0   
        add bx,160          ;基址加1行   
        jmp go_cyc          ;转去循环  
 Or_ok: add si,2            ;寻址增量2  
go_cyc: loop Ors            ;loop循环  
                                                                         
        pop si   
        pop di   
        pop cx   
        pop bx   
        pop ax   
        ret          
                                                         
; ② 名称:Show_string (辅助程序)           
;    任务:显示字符串 ,着色“光标处字符”             
;    参数:(bl)=字符颜色属性,(bh)=页号,(dl)=列号    
;          (dh)=行号,cs:si指向字符串,'$'=字符串结束标识   
;    返回:无   
Show_string:   
        push ax   
        push cx   
        push dx   
          
        mov cs:[7e86h],dl  ;将光标值保存于Tim[23]   
        cmp di,'CC'        ;判断是否存在“光标处字符”的标记'CC'   
        jne sh_str         ;不存在该标记,则转去直接显示该字符串   
        mov dl,31          ;存在该标记,则重置光标值   
s_sr_s: mov bl,cs:[7e85h]  ;从Tim[22]读取字符颜色值   
        cmp dl,cs:[7e86h]  ;比较当前光标值与之前保存的光标值   
        jne sh_str         ;不等,则直接转去显示该字符   
        mov bl,01011111b   ;等,则重置颜色属性   
sh_str: mov al,cs:[si]     ;读取字符   
        inc si             ;寻址增1;(si)有时要跨行传递,故si不入栈保存   
        cmp al,'$'         ;判断是否读到本行字符串的结束标识   
        je sh_str_over     ;读到则转结束                                   
        mov ah,2           ;否则,进行显示操作;2号子程序——置光标   
        int 10h            ;调用int 10h   
        mov ah,9           ;9号子程序——显示字符   
        mov cx,1           ;字符重复显示1次   
        int 10h            ;调用int 10h   
        inc dl             ;显示位置的列增1   
        jmp short s_sr_s   ;继续读写下一字符   
                                                  
sh_str_over:   
        pop dx   
        pop cx   
        pop ax   
        ret   
                    
; ③ 名称:Interface (辅助程序)   
;    任务:为Clock子程序、Set clock子程序提供界面装饰显示   
;    思路:清屏—>“贴”矩形面—>“擦掉”内部—>“矩形框”—>“贴上”字符串
;    参数:(al)=33h,表示执行Clock子程序界面制作   
;          (al)=34h,表示执行Set clock子程序界面制作   
;    返回:无   
Interface:           
        push ax             ;入栈保存   
        push bx   
        push cx   
        push dx   
        push bp   
        push si   
          
        cmp al,34h         ;判断选项为'3'或'4'  
        je  set_m   
        mov al,'.'         ;为选项3,设置需“贴上”的符号   
        mov si,7eedh       ;读取界面名称“Clock”首址   
        mov bp,7e9bh       ;读取操作提示首址   
        mov dl,29          ;暂存(第一条)操作提示列号   
        mov dh,0           ;置0,作为此处列号空缺的配数   
        push dx            ;列号入栈保存备用   
        jmp mak_fa  
set_m:  mov al,'/'         ;为选项4,设置需“贴上”的符号   
        mov si,7ef3h       ;读取界面名称“Set clock”首址   
        mov bp,7eb4h       ;读取第一条操作提示首址   
        mov dl,23          ;暂存第一条操作提示列号   
        mov dh,31          ;暂存第二条操作提示列号   
        push dx            ;列号入栈保存备用   
mak_fa: mov dx,'cl'        ;制作界面;设置清屏入口参数   
        call Ornament      ;调用装饰美化程序,“擦干净”屏幕   
        mov dx,0           ;置0   
        mov ah,cs:[7e85h]  ;设置颜色属性,从数据区Tim[22]取值   
        mov bx,1154        ;设置显示屏“贴上”符号的首个位置160*7+34   
        mov di,90          ;设置“装饰宽度”,从0起算占92个字节   
        mov cx,506         ;“粘贴”符号所需循环次数46*11   
        call Ornament      ;“贴上”一个由所选符号组成的“矩形面”   
        mov al,' '         ;设置' ',去“擦掉”“矩形面”内部符号   
        mov bx,1316        ;设置“擦掉”的首位置160*8+36   
        mov di,86          ;设置“擦掉”宽度,从0起算   
        mov cx,396         ;设置“擦掉”所需循环次数44*9   
        call Ornament      ;“擦掉”后,制成一个由所选符号组成的“矩形框”   
        mov bl,cs:[7e85h]  ;设置颜色属性,从数据区Tim[22]取值   
        mov bh,0           ;页号   
        mov dh,4           ;行号   
        mov dl,11          ;列号   
        call show_string   ;调用show_string,“贴上”界面名称   
        pop cx             ;列号出栈   
        mov dh,20          ;行号——第一条操作提示   
        mov dl,cl          ;列号——第一条操作提示   
        mov si,bp          ;取出操作提示首址   
ca_shw: call show_string   ;调用show_string,“贴上”操作提示    
        cmp si,7ed9h       ;判断是否寻到 Set clock 操作提示2首址 
        jne over_face      ;否,则读到且已完成 Clock 提示语显示,转结束 
        mov dh,22          ;行号—— Set clock 操作提示2   
        mov dl,ch          ;列号—— Set clock 操作提示2 
        jmp ca_shw            
                                                
over_face:    
        pop si             ;出栈恢复    
        pop bp   
        pop dx   
        pop cx   
        pop bx   
        pop ax                
        ret   
            
; ④ 名称:Time (辅助程序)   
;    任务:1、从CMOS读取时间信息,以“年/月/日 时:分:秒”格式存于Tim数据区   
;          2、在指定位置显示时钟的字符形式   
;    参数:无   
;    返回:无   
Time:   
        push ax 
        push bx 
        push dx 
 
        sub bx,bx 
Time_s: mov ax,cs:[bx].7e5dh                 ;从数据区Adr取出地址,存于ax 
        out 70h,al                           ;将该单元地址传到地址端口70h 
        in  al,71h                           ;取出BCD时钟“毛数”
        mov word ptr cs:[bx].7e71h,3030h     ;清'0',除旧待新
        or  cs:[bx].7e72h,al                 ;将“毛数”分存Tim[bx].3 
        and byte ptr cs:[bx].7e72h,00111111b ;将分存者纯化为(30h + 个位)
        add ax,ax                            ;得到(ax)×2 ;分化al中“毛数”
        add ax,ax                            ;得到(ax)×4 
        add ax,ax                            ;得到(ax)×8 
        add ax,ax                            ;终使“毛数”分开,ah得纯十位数 
        add cs:[bx].7e71h,ah                 ;传十位数到Tim[bx].2得其ASCII码
        add bx,3                             ;寻址增3个字节 
        cmp bx,18                            ;判断是否读完6个单元的时钟信息 
        jb  Time_s                           ;未读完,则继续 

        mov bl,cs:[7e85h]                    ;设置颜色属性,从Tim[22]取值 
        mov bh,0                             ;页号 
        mov dh,12                            ;行号
        mov dl,31                            ;列号
        mov si,7e6fh                         ;从Tim[0]读取Clock字符形式首址
        call show_string                     ;“贴上”时钟的字符形式 
          
        pop dx 
        pop bx 
        pop ax
        ret
                                                
; ⑤ 名称:Change_color (辅助程序)   
;    任务:设置屏幕前景色   
;    参数:(al)=颜色属性   
;    返回:无               
Change_color:   
        push bx   
        push cx   
          
        mov bx,1                             ;颜色属性初始化为1   
        mov cx,2000                          ;清屏循环次数25*80   
   Ccs: and byte ptr es:[bx],11111000b       ;前景抹“黑”待新,背景依旧   
        or es:[bx],al                        ;显示颜色属性新值   
        add bx,2   
        loop Ccs   
          
        pop cx   
        pop bx   
        ret   
                               
; ⑥ 名称:Charstack (辅助程序——字符栈)     
;    任务:作有键盘输入数字标记,并显示该数字     
;    参数:(al)=键入数字     
;    返回:无     
Charstack:      
        push dx  
        push di  

        inc byte ptr cs:[7e88h]       ;栈顶top值增1,作有数字键入标记  
        mov di,160*12                 ;计算12个整行的字节数    
        add dl,dl                     ;1个字符占2字节,(dl)=当前光标位置     
        mov dh,0                      ;置0,使dx的高8位为0     
        add di,dx                     ;相加得首字符显示位置,存于di     
        mov es:[di],al                ;显示读取的数字  

        pop di  
        pop dx  
        ret  

; ⑦ 名称:Reset (辅助程序)   
;    任务:1、判断光标所在位置的可输入性  
;          2、将光标所在位置的时钟数据重新设置 
;    参数:(dl)=光标位置值  
;    返回:(ah)=“→”,“←”,“Esc”,“Enter”的扫描码   
Reset:   
        push bx                       ;1、入栈保护和数据设置  
        push cx   
        push di   
        sub bx,bx                     ;置0,寻址数据区Tim 
        sub di,di                     ;置0,寻址数据区cp1、cp2及cun    
        mov cx,4                      ;赋值,移4位   
        mov byte ptr cs:[7e88h],0     ;栈顶top置0   
                                          
Curs:                                 ;2、对光标位置可输入性进行判断、标记   
        cmp dl,cs:[di].7e89h          ;判断光标是否在数据区(cp1)十位数处  
        je M_t_dg                     ;是,则转到 M_t_dg   
        cmp dl,cs:[di].7e8fh          ;判断光标是否在数据区(cp2)个位数处  
        je M_dig                      ;是,则转到 M_dig   
        inc di                        ;否,寻址自增1   
        cmp di,5                      ;判断是否读完所有可输入位置   
        ja Handle                     ;读完,跳出循环,结束位置性质的判读   
        jmp Curs                      ;未读完,则重复上述操作   
M_t_dg: mov ch,'T'                    ;制作十位数位置标识,存于ch   
        jmp Handle                    ;转到Handle,继续处理   
 M_dig: mov ch,'D'                    ;制作个位数位置标识,存于ch   
                                          
Handle:                               ;3、判读、处理控制信息,读、显更新数据 
        mov ah,0                      ;0号子程序   
        int 16h                       ;int 16h中断,读取键盘输入
        cmp ah,4dh                    ;判断是否读到“→”的扫描码   
        je Updata                     ;是,则转到Updata处理   
        cmp ah,4bh                    ;判断是否读到“←”的扫描码   
        je Updata                     ;是,则转到Updata处理   
        cmp ah,1h                     ;判断是否读到退出键“Esc”   
        je Updata                     ;是,则转到Updata处理   
        cmp ah,1ch                    ;判断是否读到确认键“Enter”   
        je Updata                     ;是,则转到Updata处理   
        cmp ch,0                      ;判断光标所在位置是否可输入   
        je Handle                     ;为0,则光标不在可输入位置,待键入   
        cmp al,30h                    ;与数字最小值'0'比较   
        jb Handle                     ;小于'0',则输入非数字,待键入   
        cmp al,39h                    ;与数字最大值'9'比较   
        ja Handle                     ;大于'9',则输入非数字,待键入   
        mov bh,0                      ;置0   
        mov bl,dl                     ;光标偏移地址转存bx     
        sub bx,31                     ;减光标首列位置,得Tim上该数对应位置 
        mov cs:[bx].7e6fh,al          ;键入的数字同时转存Tim[bx],备用
        call charstack                ;调用字符栈,处理当前读到的数字    
        jmp Handle                    ;重复上述操作    

Updata:                               ;4、更新时钟数据,转存有关控制信息  
        push ax                       ;保存ah中键盘输入的控制信息    
        cmp byte ptr cs:[7e88h],0     ;判断top为0否,即是否有数字键入    
        je Reset_ok                   ;为0,则无数字键入,转结束 
        mov al,cs:[bx].7e6fh          ;否,则从Tim[bx]读取键入数字  
        and al,00001111b              ;脱去读取数的ASCII码  
        cmp ch,'D'                    ;判断寄存器ch中是否为个位数标识'D' 
        je Digit                      ;是,则转Digit,按个位数处理该(al) 
        mov ah,al                     ;否,则ah统存十位数,让al统存个位数 
        mov al,cs:7e6fh[bx].1         ;十位数地址加1,即从Tim取对应个位数 
        sub al,30h                    ;脱去其ASCII码,得低4位的纯个位数 
        jmp Wri_in                    ;转到Wri_in,去将更新数据写入 
 Digit: sub bx,1                      ;个位数地址减1,即得Tim对应十位数地址 
        mov ah,cs:7e6fh[bx]           ;从Tim中取出相对应的十位数,统存ah 
        sub ah,30h                    ;脱去其ASCII码,得纯十位数
Wri_in: shl ah,cl                     ;左移4位,将该十位数置于高4位 
        or  ah,al                     ;高4位和低4位合成更新数据的BCD码 
        mov al,cs:7e95h[di]           ;从数据区(cun)读取需更新时钟单元地址 
        out 70h,al                    ;用out指令把该地址从70h端口写入 
        mov al,ah                     ;从ah中取出更新数据的BCD码 
        out 71h,al                    ;把该BCD码,用out指令从71h端口写入 
                                          
Reset_ok:                             ;5、结束   
        pop ax                        ;键盘输入的控制信息出栈,作为返回参数
        pop di                        ;还原数据   
        pop cx   
        pop bx   
        ret   
          
        db 1536-($-Main) dup(0)       ;填充3个扇区所空余的空间   
              
code ends   
end
评论次数(9)  |  浏览次数(1263)  |  类型(汇编作业) |  收藏此文  | 

[  游客   发表于  2014-03-09 18:01  ]

没搞错吧,课程2才351b

[  游客   发表于  2014-04-13 00:46  ]

16位现在只有教学意义,看一眼就好。

[  游客   发表于  2014-07-09 17:55  ]

不懂-1

[  游客   发表于  2014-07-12 10:49  ]

也看不懂[bp-2]

[  hky987654321   发表于  2014-07-29 11:43  ]

-1就是FFh。用-1兼济了ffff:0和简洁的数据分隔这二者的需要。
[bp-2],是因为刚进入4)Set clock时,bp地址对应的内存值为9,9,-1,8,8,-1,7,7,-1,4,4,-1,2,2,-1,0,0中的第一个9,而程序用右移键“→”移动光斑至年/月/日 时:分:秒的十位数或个位数时,bp随光斑“多”循环了“2次”,其数值也相应增加了2,所以要[bp-2]才能获取正确的值。

[  游客   发表于  2014-07-30 10:54  ]

懂了。

[  游客   发表于  2014-08-02 21:42  ]

为什么多次按F1后,按下“→”键会出现光斑落在年份的百位数上?

[  hky987654321   发表于  2014-08-09 11:12  ]

是的,按压F1的次数 >=15 ,有“按下“→”键会出现光斑落在年份的百位数上”的现象。
这与缓冲区只有15个的存储量,以及首尾两指针的环状队列数据结构有关。

[  游客   发表于  2014-08-31 00:14  ]

为啥简版的int 13h之后不用 jmp 也行。

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码