int 9 中断例程
;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。;在显示的过程中,按下“ESC”键后,改变显示的颜色。
assume cs:code,ss:stack,ds:data
data segment
db 0,0,0,0
data ends
stack segment
db 128 dup(0)
stack ends
code segment
start: mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,128
mov ax,0
mov es,ax ;中断向量表的段地址为0
push es: ;将原来 int 9 中断例程的指令的
pop ds: ;ip保存到ds:,cs保存到ds:单元中
push es:
pop ds:
mov word ptr es:,offset int9
mov word ptr es:,cs ;设置新的中断例程
mov ax,0b800h
mov es,ax
mov si,160*12+40*2
mov ah,'a'
s: mov es:,ah
call delay
inc ah
cmp ah,'z'
jna s
mov ax,0 ;中断例程的入口地址恢复为
mov es,ax ;原来的入口地址
push ds:
pop es:
push ds:
pop es:
mov ax,4c00h
int 21h
delay: push ax
push dx
mov dx,1000h
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
cmp dx,0ff0h
jne s1
pop dx
pop ax
ret
;--------以下为新的 int 9 中断例程--------------------
int9: push ax
push bx
push es
push si
in al,60h ;从60h端口读入数据
pushf
pop bx
pushf
and bx,1111110011111111b
push bx
popf
call dword ptr ds: ;对int指令进行模拟,调用原来的int 9中断例程
cmp al,1
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es: ;属性增加1,改变颜色
int9ret: pop si
pop es
pop bx
pop ax
iret
code ends
end start
如图,程序在 mov word ptr ,0ffset int9 位置处发生了错误,此后无法执行任何内容,呈死机状态。 1.不要用debug单步调试,我复制书上的答案也不能用debug单步调试
2.程序延时太短
;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。
;在显示的过程中,按下“ESC”键后,改变显示的颜色。
assume cs:code,ss:stack,ds:data
data segment
db 0,0,0,0
data ends
stack segment
db 128 dup(0)
stack ends
code segment
start: mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,128
mov ax,0
mov es,ax ;中断向量表的段地址为0
push es: ;将原来 int 9 中断例程的指令的
pop ds: ;ip保存到ds:,cs保存到ds:单元中
push es:
pop ds:
mov word ptr es:,offset int9
mov word ptr es:,cs ;设置新的中断例程
mov ax,0b800h
mov es,ax
mov si,160*12+40*2
mov ah,'a'
s: mov es:,ah
call delay
inc ah
cmp ah,'z'
jna s
mov ax,0 ;中断例程的入口地址恢复为
mov es,ax ;原来的入口地址
push ds:
pop es:
push ds:
pop es:
mov ax,4c00h
int 21h
delay: push ax
push dx
mov dx,1000h
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
;cmp dx,0ff0h
cmp dx,0
jne s1
pop dx
pop ax
ret
;--------以下为新的 int 9 中断例程--------------------
int9: push ax
push bx
push es
push si
in al,60h ;从60h端口读入数据
pushf
pop bx
pushf
and bx,1111110011111111b
push bx
popf
call dword ptr ds: ;对int指令进行模拟,调用原来的int 9中断例程
cmp al,1
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es: ;属性增加1,改变颜色
int9ret: pop si
pop es
pop bx
pop ax
iret
code ends
end start 人造人 发表于 2017-2-7 22:25
1.不要用debug单步调试,我复制书上的答案也不能用debug单步调试
2.程序延时太短
那程序万一出错了,不能单步调试,看源程序又看不出来,那怎么办啊 Cy86183570 发表于 2017-2-8 11:40
那程序万一出错了,不能单步调试,看源程序又看不出来,那怎么办啊
这个我也没有什么好的办法,因为这个程序比较特殊,此程序正好使用了键盘中断 人造人 发表于 2017-2-8 11:43
这个我也没有什么好的办法,因为这个程序比较特殊,此程序正好使用了键盘中断
正头疼中,好像程序无法装入中断向量表中,调试也没办法调试,看程序又没什么问题,汇编可真是麻烦啊! Cy86183570 发表于 2017-2-8 12:58
正头疼中,好像程序无法装入中断向量表中,调试也没办法调试,看程序又没什么问题,汇编可真是麻烦啊!
你这个程序没有什么问题呀
就是延时有点少
试试这个
;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。
;在显示的过程中,按下“ESC”键后,改变显示的颜色。
assume cs:code,ss:stack,ds:data
data segment
db 0,0,0,0
data ends
stack segment
db 128 dup(0)
stack ends
code segment
start: mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,128
mov ax,0
mov es,ax ;中断向量表的段地址为0
push es: ;将原来 int 9 中断例程的指令的
pop ds: ;ip保存到ds:,cs保存到ds:单元中
push es:
pop ds:
mov word ptr es:,offset int9
mov word ptr es:,cs ;设置新的中断例程
mov ax,0b800h
mov es,ax
mov si,160*12+40*2
mov ah,'a'
s: mov es:,ah
call delay
inc ah
cmp ah,'z'
jna s
mov ax,0 ;中断例程的入口地址恢复为
mov es,ax ;原来的入口地址
push ds:
pop es:
push ds:
pop es:
mov ax,4c00h
int 21h
delay: push ax
push dx
mov dx,1000h
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
;cmp dx,0ff0h
cmp dx,0
jne s1
pop dx
pop ax
ret
;--------以下为新的 int 9 中断例程--------------------
int9: push ax
push bx
push es
push si
in al,60h ;从60h端口读入数据
pushf
pop bx
pushf
and bx,1111110011111111b
push bx
popf
call dword ptr ds: ;对int指令进行模拟,调用原来的int 9中断例程
cmp al,1
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es: ;属性增加1,改变颜色
int9ret: pop si
pop es
pop bx
pop ax
iret
code ends
end start 人造人 发表于 2017-2-8 13:25
你这个程序没有什么问题呀
就是延时有点少
试试这个
程序可以运行的,可是我把int 9中断例程的存放位置更改了,就运行不了了,大神,帮我看看;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。
;在显示的过程中,按下“ESC”键后,改变显示的颜色。
assume cs:code,ss:stack,ds:data
data segment
db 0,0,0,0
data ends
stack segment
db 128 dup(0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,128
mov ax,0
mov es,ax ;中断向量表的段地址为0
push es: ;将原来 int 9 中断例程的指令的
pop es:
push es: ;ip保存到0:200,cs保存到0:202
pop es:
mov ax,cs ;将新int 9中断例程的入口地址
mov ds,ax
mov si,offset int9
mov di,204h
mov cx,offset int9end - offset int9
cld
rep movsb
cli ;将IF置0,屏蔽其他可屏蔽的中断
mov word ptr es:,204h ;设置新的中断例程
mov word ptr es:,0
sti ;恢复IF置1
mov ax,0b800h
mov es,ax
mov ah,'a'
s: mov es:,ah
call delay
inc ah
cmp ah,'z'
jna s
mov ax,0 ;中断例程的入口地址恢复为
mov es,ax ;原来的入口地址
push es:
pop es:
push es:
pop es:
mov ax,4c00h
int 21h
delay: push ax
push dx
mov dx,1000h
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
cmp dx,0ff0h
jne s1
pop dx
pop ax
ret
;--------以下为新的 int 9 中断例程--------------------
int9: push ax
push bx
push es
in al,60h ;从60h端口读入数据
pushf
pop bx
pushf
and bx,1111110011111111b
push bx
popf
call dword ptr es: ;对int指令进行模拟,调用原来的int 9中断例程
cmp al,1+80h
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es: ;属性增加1,改变颜色
int9ret: pop es
pop bx
pop ax
iret
int9end: nop
code ends
end start Cy86183570 发表于 2017-2-8 13:49
程序可以运行的,可是我把int 9中断例程的存放位置更改了,就运行不了了,大神,帮我看看
;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。
;在显示的过程中,按下“ESC”键后,改变显示的颜色。
assume cs:code,ss:stack,ds:data
data segment
db 0,0,0,0
data ends
stack segment
db 128 dup(0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,128
mov ax,0
mov es,ax ;中断向量表的段地址为0
push es: ;将原来 int 9 中断例程的指令的
pop es:
push es: ;ip保存到0:200,cs保存到0:202
pop es:
mov ax,cs ;将新int 9中断例程的入口地址
mov ds,ax
mov si,offset int9
mov di,204h
mov cx,offset int9end - offset int9
cld
rep movsb
cli ;将IF置0,屏蔽其他可屏蔽的中断
mov word ptr es:,204h ;设置新的中断例程
mov word ptr es:,0
sti ;恢复IF置1
mov ax,0b800h
mov es,ax
mov ah,'a'
s: mov es:,ah
call delay
inc ah
cmp ah,'z'
jna s
mov ax,0 ;中断例程的入口地址恢复为
mov es,ax ;原来的入口地址
push es:
pop es:
push es:
pop es:
mov ax,4c00h
int 21h
delay: push ax
push dx
mov dx,1000h
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
;cmp dx,0ff0h
cmp dx, 0 ; 都说了,你的延时太短
jne s1
pop dx
pop ax
ret
;--------以下为新的 int 9 中断例程--------------------
int9: push ax
push bx
push es
;这里
mov ax, 0
mov es, ax
in al,60h ;从60h端口读入数据
pushf
;pop bx
pushf
pop bx ;这里
and bx,1111110011111111b
push bx
popf
call dword ptr es: ;对int指令进行模拟,调用原来的int 9中断例程
cmp al,1+80h
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es: ;属性增加1,改变颜色
int9ret: pop es
pop bx
pop ax
iret
int9end: nop
code ends
end start 人造人 发表于 2017-2-8 14:25
后来我明白不是程序的问题,你说延时短,真没有问题,我不知道我电脑怎么回事,原来我设置的延时是跟视频里一样很长的,可惜只怪我电脑反映不过来,所以才设置短的,之后都没有问题,直到我改了int 9 中断例程的存储位置,也就是放到了0:204单元才显示不出来,我之后又重看了遍视频,寻找了一些以前别人的程序,才知道不是程序的问题,是必须在DOS实装模式下才能显示出来。抱歉了,费那么大劲,都是我自己没仔细看视频的锅。 Cy86183570 发表于 2017-2-8 14:44
后来我明白不是程序的问题,你说延时短,真没有问题,我不知道我电脑怎么回事,原来我设置的延时是跟视频 ...
实模式?
下面gif如何解释
人造人 发表于 2017-2-8 15:38
实模式?
下面gif如何解释
不是啦,没改int 9程序的存储地址,我也能显示出来的 Cy86183570 发表于 2017-2-8 16:07
不是啦,没改int 9程序的存储地址,我也能显示出来的
不明白你在说什么,不过问题解决了进行
^_^
页:
[1]