- [游客] 为啥简版的int 13h之后不用 jmp 也行。 08/31 00:14
- [hky987654321] 是的,按压F1的次数 >=15 ,有“按下“→”键会出现光斑落在年份的百位数上”的现象。 这与缓冲 08/09 11:12
- [游客] 为什么多次按F1后,按下“→”键会出现光斑落在年份的百位数上? 08/02 21:42
- [游客] 懂了。 07/30 10:54
- [hky987654321] -1就是FFh。用-1兼济了ffff:0和简洁的数据分隔这二者的需要。 [bp-2],是因为刚进入 07/29 11:43
- [游客] 也看不懂[bp-2] 07/12 10:49
- [游客] 不懂-1 07/09 17:55
- [游客] 16位现在只有教学意义,看一眼就好。 04/13 00:46
- [游客] 没搞错吧,课程2才351b 03/09 18:01
- [游客] 没想到实验14只用13条代码! 03/02 15:46
[2013-11-13 17:09] 提交课设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
[ 游客 发表于 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 也行。