- [mywiil] 我没用书上的入栈出栈写,就是先看看不用书上的方法能做出来否? ============== 不错 09/19 09:24
- [njutyangxiao] 谢谢你的指导 09/18 17:00
- [younggay] 嗯,应该说理解的没问题。 09/18 15:41
- [njutyangxiao] 检测点16.1的题目是中是这样定义的: a dw 1,2,3,4,5,6,7,8 b dd 09/16 11:23
- [njutyangxiao] 嗯,谢谢指导 09/16 11:22
- [wsrf] assume伪指令指定了段中标号与相应段寄存器的联系。 09/16 09:46
- [wsrf] 没有问题,不过源代码中 a db 1,2,3,4,5,6,7,8 b dw 0 怎么 09/16 09:43
- [njutyangxiao] 谢谢,keep moving! 09/16 09:06
- [njutyangxiao] 谢谢你的指导 09/16 09:05
- [njutyangxiao] 谢谢你的指导 09/16 09:05
[2009-09-17 14:07] 16实验
编写包含多个功能子程序的中断例程
安装一个新的int 7ch中断例程,为显示输出提供如下功能子程序:
(1)清屏
(2)设置前景色
(3)设置背景色
(4)向上滚动一行
入口参数说明:
(1)用ah寄存器传递功能号:0表示清屏,1表示设置前景色,2表示设置背景色,3表示向上滚动一行;
(2)对于2、3号功能,用al传送颜色值,(al)取值范围为[0,1,2,3,4,5,6,7]
分析:对于本实验,第一点是:各个子程序的编写,这并不难,参考书上很轻松就能搞定。第二点是:设置int 7ch的中断向量表项是关键,刚开始我也发现是调用时子程序的地址不对,但是还是没得解决。上论坛看过之后,采取了程序中这种比较简单的方法。具体的在程序中有分析。第三点就是编写测试程序。这点受到了sirius的思路指引。
具体源代码如下:
assume cs:codesg,ds:datasg
datasg segment
fun_table dw funShowA, funClrSc, funChFgC, funChBgC, funRoOnL, funExitP, inpFunNu, inpColNu,errInpFu,errInpCo, space
funShowA db '0 Show character A','$'
funClrSc db '1 Clear Screen','$'
funChFgC db '2 Change Foreground Color','$'
funChBgC db '3 Change Background Color','$'
funRoOnL db '4 Roll Up One Line','$'
funExitP db '5 Exit Program','$'
inpFunNu db 'Input Function Number:[0,1,2,3,4,5]:','$'
inpColNu db 'Input Color Attribute:[0,1,2,3,4,5,6,7]:','$'
errInpFu db 'Error!Input Function Number Range:[0,1,2,3,4]','$'
errInpCo db 'Error!Input Color Attribute Range:[0,1,2,3,4,5,6,7]','$'
space db ' ','$'
row db 5,6,7,8,9,10,12,13,14,15
datasg ends
stacksg segment
db 128 dup (0)
stacksg ends
codesg segment
;;;;;;;;;;;以下是int 7ch中断程序;;;;;;;;;;;;;;;;;;;;;;
setscreen:
jmp short set
table dw showchar,clearscreen, setForeground, setBackground ,scrolloneline
set:
push bx
cmp ah,4
ja setret ;判断所输入的功能号,大于4就是非法输入
cmp ah,0
jb setret ;判断所输入的功能号,小于零也是非法输入
mov bl,ah
mov bh,0
add bx,bx;因为table定义的是字型数据,所以要把bx的值乘以2,才是其对应的子程序的入口地址
call word ptr table[bx];调用相应的子程序
setret:
pop bx
iret
;此子程序是显示满屏的字母'A'
showchar:
push ax
push bx
push cx
push es
mov ax,0b800h
mov es,ax
mov bx,0
mov cx,2000;在第0页上显示满屏的'A',循环2000次
lp_showchar:
mov byte ptr es:[bx],41h;显示'A'
add bx,2
loop lp_showchar
pop es
pop cx
pop bx
pop ax
ret
;清屏
clearscreen:
push ax
push bx
push cx
push es
mov ax,0b800h
mov es,ax
mov bx,0
mov cx,2000
lp_clrscr:
mov byte ptr es:[bx],20h;清屏的关键就是在偶地址位上填充空格
add bx,2
loop lp_clrscr
pop es
pop cx
pop bx
pop ax
ret
;设置前景色,
setForeground:
push ax
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,1;因为奇数地址位存放的是显示颜色属性字节,所以偏移地址bx从1开始
mov cx,2000
lp_setFG:
and byte ptr es:[bx],11111000b;这一步骤很关键,因为与前景色有关的颜色属性字节位
;是0,1,2三位,所以我要保留之前颜色属性的其他位不变,把这三位清零
or byte ptr es:[bx],al ;接着是用要设置的前景色的颜色属性值与原来的颜色属性值逻辑或后,就更改了前景颜色属性值
add bx,2
loop lp_setFG
pop es
pop cx
pop bx
pop ax
ret
;设置背景色
setBackground:
push ax
push bx
push cx
push es
mov cx,0
mov cl,4
shl al,cl
mov bx,0b800h
mov es,bx
mov bx,1
mov cx,2000
lp_setBG:
and byte ptr es:[bx],10001111b;道理同设置前景色,与设置背景色有关的是颜色属性值字节位是4,5,6三位,
;所以也要保留之前颜色属性值的其它位不变,把此三位清零
or byte ptr es:[bx],al;接着是用要设置的前景颜色属性值与原来的颜色属性值逻辑或后,就更改了背景颜色属性值
add bx,2
loop lp_setBG
pop es
pop cx
pop bx
pop ax
ret
;向上滚动一行
scrolloneline:
push ax
push bx
push cx
push es
push ds
push si
push di
mov bx,0b800h
mov es,bx
mov ds,bx;因为要做的事是:依次把第n+1行的内容复制到第n行;然后最后一行清空,而目的段地址都是0b800h
mov si,160;因为ds:[si]是数据源,所以设置初始值是你为0,即n+1为1。即初始是把第二行的复制到第一行,
;而一行的大小是160B。所以si初始值是160
mov di,0;es:[di]就是目的地址了。而目的是要把第n+1行的内容复制到第n行。所以di的值为0
cld
mov cx,24
lp_copyOL:
push cx
mov cx,160
rep movsb
add bx,2
pop cx
loop lp_copyOL
mov cx,80
mov si,0
lp_setSpace:
mov byte ptr [160*24+si],20h
add si,2
loop lp_setSpace;把最后一行清空
pop di
pop si
pop ds
pop es
pop cx
pop bx
pop ax
ret
setend:nop
;;;;;;;;;;;到这里中断程序结束了;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;以下是主程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
mov ax,stacksg
mov ss,ax
mov sp,128
;;;;;复制 int 7ch 的中断程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,cs
mov ds,ax
mov si,offset setscreen
mov ax,0
mov es,ax
mov di,200h
mov cx,offset setend - offset setscreen
cld
rep movsb
;;;;;;;;复制 int 7ch 的中断程序结束;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;设置int 7ch的中断向量表项;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,0
mov es,ax
mov word ptr es:[7ch*4],0h
mov word ptr es:[7ch*4+2],20h;这里的设置很关键,把中断程序拷贝到了0000:0200h开始处。
;原本设置cs=0000,而ip=0200h的。但是调用中断例程后ip的值是0,所以为了设置ip的值是0
;就只有设置cs=0020h了,因为0000:0200h和0020:0000h所表示的地址是一样的,都是00200h。但是
;通过这样设置之后,可以使得ip的值是0,以便能找到中断程序的子程序
;;;;;;;设置int 7ch的中断向量表结束束;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;以下的程序是测试程序,它提供了一个图形化的界面,用户输入相应的功能测试上面的中端程序的相关功能;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,datasg
mov ds,ax
;循环输出菜单
menu:
mov bx,offset fun_table;把在datasg段定义的菜单信息的首地址给bx
mov si,offset row ;把在datasg段定义的行信息的首地址给si
mov cx,7;循环7次的目的是输出菜单的功能信息和提示信息。但是错误信息不要输出
print_menu:
call showstr ;调用此子程序输出菜单信息
inc si;
add bx,2;
loop print_menu
mov ah,0
int 16h ;因为int 16h的功能是从键盘读取一个字符。入口参数是把0送给ah。
;出口参数是al中的内容是字符码,ah中的内容是扫描码。
;所以调用int 16h的0号子程序读取从键盘输入入的字符
cmp al,'0'
je show_char_A;0就是显示满屏的字母A
cmp al,'1'
je clear_screen;1是清屏
cmp al,'2'
je change_color ;2改变前景色
cmp al,'3'
je change_color ;3改变背景色
cmp al,'4'
je roll_up_oneline ;4屏幕向上滚动一行
cmp al,'5'
je exit_program ;退出程序
;如果范围不在0到5之间就说嘛输入有错误,应该提示功能号输入误的信息
mov si,offset row+7 ;row+7也就是在13行显示错误信息
mov bx,offset fun_table+10h ;fun_table+10h存放的是功能号输入错误的信息
call showstr;调用输出字符子程序输出错误信息
call delay
mov si,offset row+7
mov bx,offset fun_table+14h;等待用户重新输入之前要把错误信息清除,而fun_table+14h存放的就是清屏要用到的空格符
call showstr;清除错误信息
jmp menu;一直循环直到用户输入5退出程序
;调用int 7ch的0号功能显示满屏的字母A
show_char_A:
mov ah,0
int 7ch
call delay
jmp menu
;调用int 7ch的1号功能清屏
clear_screen:
mov ah,1;
int 7ch
call delay
jmp menu
;调用int 7ch的4号功能屏幕向上滚动一行
roll_up_oneline:
mov ah,4
int 7ch
call delay
jmp menu
;调用int 7ch的5号功能退出程序
exit_program:
mov ax,4c00h
int 21h
;这里是判断是设置前景色或者背景色
change_color:
mov dl,al;al里是用户输入的功能号,不是2就是3
loop_color_attri:
mov si,offset row+8
mov bx,offset fun_table+14 ;在row+8也就是第14行显示提示颜色属性值的信息
;(fun_table+14中存放提示颜色属性值输入的信息字符串的偏移地址)
call showstr;输出提示输入颜色属性值的信息
mov ah,0
int 16h;调用16h的0号功能获得用户的输入
mov ah,'0'
mov cx,8
;判段颜色属性值的正确性,它的范围只能是0到7
test_color:
cmp al,ah
je setFG_or_setBG;如果输入是合理的就跳转到setFG_or_setBG处判断是设置前景色还是设置背景色
add ah,1
loop test_color;这里循环8次,检查输入的颜色属性值是否合理
;如果循环进行完之后没有跳转到setFG_or_setBG,就说明颜色属性值输入有错,需提示错误信息
mov si,offset row+9
mov bx,offset fun_table+18
call showstr;同理显示颜色属性输入错误的信息
call delay
mov si,offset row+9
mov bx,offset fun_table+20
call showstr;把颜色提示信息清空
jmp loop_color_attri;一直循环到用户输入正确的颜色属性值
setFG_or_setBG:
mov si,offset row+8
mov bx,offset fun_table+20
call showstr;拿到合适的颜色属性之后要把提示输入颜色属性值的信息清除
cmp dl,'3'
je set_bg_color ;判断如果是3号功能就是设置背景色
;调用int 7ch的2号功能设置前景色
set_fg_color:
mov ah,2
int 7ch
jmp menu
;调用int 7ch的3号功能设置背景色景色
set_bg_color:
mov ah,3
int 7ch
jmp menu
;;;;;;;显示字符串的子程序;;;;;;;;;;;;;;;;;;;;;
showstr:
push bx
push dx
push ax
push si
mov bh,0 ;显示在第0页
mov dh,ds:[si] ;行号
mov dl,20 ;列号
mov ah,2 ;要调用int 10h的2号子程序
int 10h;调用了int 10h的2号子程序对光标进行定位
mov dx,ds:[bx];设置ds:dx指向要显示的字符串的首地址
mov ah,9
int 21h ;调用int 21h的第9号子程序显示字符串
pop si
pop ax
pop dx
pop bx
ret
;;;;;;;显示字符串的子程序的结束;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;这里是延时程序的开始;;;;;;;;;;;;;;;;;;;;;;
delay:
push ax
push dx
mov dx,2000h
mov ax,0
loop_delay:
sub ax,1
sbb dx,0
cmp ax,0
jne loop_delay
cmp dx,0
jne loop_delay
pop dx
pop ax
ret
;;;;;;;;;这里是延时程序的结束;;;;;;;;;;;;;;;;;;;;;;
mov ax,4c00h
int 21h
codesg ends
end start
安装一个新的int 7ch中断例程,为显示输出提供如下功能子程序:
(1)清屏
(2)设置前景色
(3)设置背景色
(4)向上滚动一行
入口参数说明:
(1)用ah寄存器传递功能号:0表示清屏,1表示设置前景色,2表示设置背景色,3表示向上滚动一行;
(2)对于2、3号功能,用al传送颜色值,(al)取值范围为[0,1,2,3,4,5,6,7]
分析:对于本实验,第一点是:各个子程序的编写,这并不难,参考书上很轻松就能搞定。第二点是:设置int 7ch的中断向量表项是关键,刚开始我也发现是调用时子程序的地址不对,但是还是没得解决。上论坛看过之后,采取了程序中这种比较简单的方法。具体的在程序中有分析。第三点就是编写测试程序。这点受到了sirius的思路指引。
具体源代码如下:
assume cs:codesg,ds:datasg
datasg segment
fun_table dw funShowA, funClrSc, funChFgC, funChBgC, funRoOnL, funExitP, inpFunNu, inpColNu,errInpFu,errInpCo, space
funShowA db '0 Show character A','$'
funClrSc db '1 Clear Screen','$'
funChFgC db '2 Change Foreground Color','$'
funChBgC db '3 Change Background Color','$'
funRoOnL db '4 Roll Up One Line','$'
funExitP db '5 Exit Program','$'
inpFunNu db 'Input Function Number:[0,1,2,3,4,5]:','$'
inpColNu db 'Input Color Attribute:[0,1,2,3,4,5,6,7]:','$'
errInpFu db 'Error!Input Function Number Range:[0,1,2,3,4]','$'
errInpCo db 'Error!Input Color Attribute Range:[0,1,2,3,4,5,6,7]','$'
space db ' ','$'
row db 5,6,7,8,9,10,12,13,14,15
datasg ends
stacksg segment
db 128 dup (0)
stacksg ends
codesg segment
;;;;;;;;;;;以下是int 7ch中断程序;;;;;;;;;;;;;;;;;;;;;;
setscreen:
jmp short set
table dw showchar,clearscreen, setForeground, setBackground ,scrolloneline
set:
push bx
cmp ah,4
ja setret ;判断所输入的功能号,大于4就是非法输入
cmp ah,0
jb setret ;判断所输入的功能号,小于零也是非法输入
mov bl,ah
mov bh,0
add bx,bx;因为table定义的是字型数据,所以要把bx的值乘以2,才是其对应的子程序的入口地址
call word ptr table[bx];调用相应的子程序
setret:
pop bx
iret
;此子程序是显示满屏的字母'A'
showchar:
push ax
push bx
push cx
push es
mov ax,0b800h
mov es,ax
mov bx,0
mov cx,2000;在第0页上显示满屏的'A',循环2000次
lp_showchar:
mov byte ptr es:[bx],41h;显示'A'
add bx,2
loop lp_showchar
pop es
pop cx
pop bx
pop ax
ret
;清屏
clearscreen:
push ax
push bx
push cx
push es
mov ax,0b800h
mov es,ax
mov bx,0
mov cx,2000
lp_clrscr:
mov byte ptr es:[bx],20h;清屏的关键就是在偶地址位上填充空格
add bx,2
loop lp_clrscr
pop es
pop cx
pop bx
pop ax
ret
;设置前景色,
setForeground:
push ax
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,1;因为奇数地址位存放的是显示颜色属性字节,所以偏移地址bx从1开始
mov cx,2000
lp_setFG:
and byte ptr es:[bx],11111000b;这一步骤很关键,因为与前景色有关的颜色属性字节位
;是0,1,2三位,所以我要保留之前颜色属性的其他位不变,把这三位清零
or byte ptr es:[bx],al ;接着是用要设置的前景色的颜色属性值与原来的颜色属性值逻辑或后,就更改了前景颜色属性值
add bx,2
loop lp_setFG
pop es
pop cx
pop bx
pop ax
ret
;设置背景色
setBackground:
push ax
push bx
push cx
push es
mov cx,0
mov cl,4
shl al,cl
mov bx,0b800h
mov es,bx
mov bx,1
mov cx,2000
lp_setBG:
and byte ptr es:[bx],10001111b;道理同设置前景色,与设置背景色有关的是颜色属性值字节位是4,5,6三位,
;所以也要保留之前颜色属性值的其它位不变,把此三位清零
or byte ptr es:[bx],al;接着是用要设置的前景颜色属性值与原来的颜色属性值逻辑或后,就更改了背景颜色属性值
add bx,2
loop lp_setBG
pop es
pop cx
pop bx
pop ax
ret
;向上滚动一行
scrolloneline:
push ax
push bx
push cx
push es
push ds
push si
push di
mov bx,0b800h
mov es,bx
mov ds,bx;因为要做的事是:依次把第n+1行的内容复制到第n行;然后最后一行清空,而目的段地址都是0b800h
mov si,160;因为ds:[si]是数据源,所以设置初始值是你为0,即n+1为1。即初始是把第二行的复制到第一行,
;而一行的大小是160B。所以si初始值是160
mov di,0;es:[di]就是目的地址了。而目的是要把第n+1行的内容复制到第n行。所以di的值为0
cld
mov cx,24
lp_copyOL:
push cx
mov cx,160
rep movsb
add bx,2
pop cx
loop lp_copyOL
mov cx,80
mov si,0
lp_setSpace:
mov byte ptr [160*24+si],20h
add si,2
loop lp_setSpace;把最后一行清空
pop di
pop si
pop ds
pop es
pop cx
pop bx
pop ax
ret
setend:nop
;;;;;;;;;;;到这里中断程序结束了;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;以下是主程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
mov ax,stacksg
mov ss,ax
mov sp,128
;;;;;复制 int 7ch 的中断程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,cs
mov ds,ax
mov si,offset setscreen
mov ax,0
mov es,ax
mov di,200h
mov cx,offset setend - offset setscreen
cld
rep movsb
;;;;;;;;复制 int 7ch 的中断程序结束;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;设置int 7ch的中断向量表项;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,0
mov es,ax
mov word ptr es:[7ch*4],0h
mov word ptr es:[7ch*4+2],20h;这里的设置很关键,把中断程序拷贝到了0000:0200h开始处。
;原本设置cs=0000,而ip=0200h的。但是调用中断例程后ip的值是0,所以为了设置ip的值是0
;就只有设置cs=0020h了,因为0000:0200h和0020:0000h所表示的地址是一样的,都是00200h。但是
;通过这样设置之后,可以使得ip的值是0,以便能找到中断程序的子程序
;;;;;;;设置int 7ch的中断向量表结束束;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;以下的程序是测试程序,它提供了一个图形化的界面,用户输入相应的功能测试上面的中端程序的相关功能;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,datasg
mov ds,ax
;循环输出菜单
menu:
mov bx,offset fun_table;把在datasg段定义的菜单信息的首地址给bx
mov si,offset row ;把在datasg段定义的行信息的首地址给si
mov cx,7;循环7次的目的是输出菜单的功能信息和提示信息。但是错误信息不要输出
print_menu:
call showstr ;调用此子程序输出菜单信息
inc si;
add bx,2;
loop print_menu
mov ah,0
int 16h ;因为int 16h的功能是从键盘读取一个字符。入口参数是把0送给ah。
;出口参数是al中的内容是字符码,ah中的内容是扫描码。
;所以调用int 16h的0号子程序读取从键盘输入入的字符
cmp al,'0'
je show_char_A;0就是显示满屏的字母A
cmp al,'1'
je clear_screen;1是清屏
cmp al,'2'
je change_color ;2改变前景色
cmp al,'3'
je change_color ;3改变背景色
cmp al,'4'
je roll_up_oneline ;4屏幕向上滚动一行
cmp al,'5'
je exit_program ;退出程序
;如果范围不在0到5之间就说嘛输入有错误,应该提示功能号输入误的信息
mov si,offset row+7 ;row+7也就是在13行显示错误信息
mov bx,offset fun_table+10h ;fun_table+10h存放的是功能号输入错误的信息
call showstr;调用输出字符子程序输出错误信息
call delay
mov si,offset row+7
mov bx,offset fun_table+14h;等待用户重新输入之前要把错误信息清除,而fun_table+14h存放的就是清屏要用到的空格符
call showstr;清除错误信息
jmp menu;一直循环直到用户输入5退出程序
;调用int 7ch的0号功能显示满屏的字母A
show_char_A:
mov ah,0
int 7ch
call delay
jmp menu
;调用int 7ch的1号功能清屏
clear_screen:
mov ah,1;
int 7ch
call delay
jmp menu
;调用int 7ch的4号功能屏幕向上滚动一行
roll_up_oneline:
mov ah,4
int 7ch
call delay
jmp menu
;调用int 7ch的5号功能退出程序
exit_program:
mov ax,4c00h
int 21h
;这里是判断是设置前景色或者背景色
change_color:
mov dl,al;al里是用户输入的功能号,不是2就是3
loop_color_attri:
mov si,offset row+8
mov bx,offset fun_table+14 ;在row+8也就是第14行显示提示颜色属性值的信息
;(fun_table+14中存放提示颜色属性值输入的信息字符串的偏移地址)
call showstr;输出提示输入颜色属性值的信息
mov ah,0
int 16h;调用16h的0号功能获得用户的输入
mov ah,'0'
mov cx,8
;判段颜色属性值的正确性,它的范围只能是0到7
test_color:
cmp al,ah
je setFG_or_setBG;如果输入是合理的就跳转到setFG_or_setBG处判断是设置前景色还是设置背景色
add ah,1
loop test_color;这里循环8次,检查输入的颜色属性值是否合理
;如果循环进行完之后没有跳转到setFG_or_setBG,就说明颜色属性值输入有错,需提示错误信息
mov si,offset row+9
mov bx,offset fun_table+18
call showstr;同理显示颜色属性输入错误的信息
call delay
mov si,offset row+9
mov bx,offset fun_table+20
call showstr;把颜色提示信息清空
jmp loop_color_attri;一直循环到用户输入正确的颜色属性值
setFG_or_setBG:
mov si,offset row+8
mov bx,offset fun_table+20
call showstr;拿到合适的颜色属性之后要把提示输入颜色属性值的信息清除
cmp dl,'3'
je set_bg_color ;判断如果是3号功能就是设置背景色
;调用int 7ch的2号功能设置前景色
set_fg_color:
mov ah,2
int 7ch
jmp menu
;调用int 7ch的3号功能设置背景色景色
set_bg_color:
mov ah,3
int 7ch
jmp menu
;;;;;;;显示字符串的子程序;;;;;;;;;;;;;;;;;;;;;
showstr:
push bx
push dx
push ax
push si
mov bh,0 ;显示在第0页
mov dh,ds:[si] ;行号
mov dl,20 ;列号
mov ah,2 ;要调用int 10h的2号子程序
int 10h;调用了int 10h的2号子程序对光标进行定位
mov dx,ds:[bx];设置ds:dx指向要显示的字符串的首地址
mov ah,9
int 21h ;调用int 21h的第9号子程序显示字符串
pop si
pop ax
pop dx
pop bx
ret
;;;;;;;显示字符串的子程序的结束;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;这里是延时程序的开始;;;;;;;;;;;;;;;;;;;;;;
delay:
push ax
push dx
mov dx,2000h
mov ax,0
loop_delay:
sub ax,1
sbb dx,0
cmp ax,0
jne loop_delay
cmp dx,0
jne loop_delay
pop dx
pop ax
ret
;;;;;;;;;这里是延时程序的结束;;;;;;;;;;;;;;;;;;;;;;
mov ax,4c00h
int 21h
codesg ends
end start
评论次数(0) |
浏览次数(737) |
类型(汇编作业) |
收藏此文 |