实验 16 编写包含多个功能子程序的中断例程
本帖最后由 奥普瓯江 于 2019-4-12 01:46 编辑安装一个新的int 7ch中断例程, 为显示输出提供如下功能子程序。
(1)清屏;
(2)设置前景色
(3)设置背景色
入口参数说明如下。
(1)用ah寄存器传递功能号:0表示清屏,1表示设置前景色, 2表示设置背景色,3表示向上滚动一行;
(2)对于2、3号功能,用al传送颜色值,(al) {0, 1, 2, 3, 4, 5, 6, 7}。
这个是我自己编写的,如果用直接定址表会出现定位不准,因为int 7ch是经过编译后再装载到0000:0200内存中的在内存中他不会在此从新定义储存的地址所以容易出错
assume cs:code
code segment
start:
mov ax, cs
mov ds, ax
mov si, offset input
mov ax, 0h
mov es, ax
mov di, 0200h
mov cx, offset end_1 - offset input
cld
rep movsb
cli
mov word ptr es:, 0200h
mov word ptr es:, 0h
sti
mov ax, 4c00h
int 21h
input:
jmp short input_1
db 'ni shu ru de xin xi you wu', 0
input_1:
push ax
push bx
push ds
push es
push cx
push di
option_1:
mov bh, ah
mov bl, al
mov ax, 0b800h
mov es, ax
mov di, 0
mov si, 0
mov cx, 2000
cmp bh, 0
jna item5
cmp bh, 4
ja item5
cmp bh, 1
je item1
cmp bh, 2
je item2
cmp bh, 3
je item3
cmp bh, 4
je item4
end_ok:
pop di
pop cx
pop es
pop ds
pop bx
pop ax
iret
;清屏
item1:
mov byte ptr es:, ' '
add di, 2
loop item1
mov ah, 2;调整光标位置
mov bh, 0;光标所在第几页 一共有6页
mov dh, 0;光标所在第几行 一页有25行
mov dl, 0;每页有160个字节80个字每个字包含一个数据字节一个属性字节
int 10h ;十号中断
jmp short end_ok
;设置前景色
item2:
mov byte ptr es:, bl
add di, 2
loop item2
jmp short end_ok
;设置背景色
item3:
mov byte ptr es:, bl
add di, 2
loop item3
jmp short end_ok
;向上滚动一行
item4:
mov ds, ax
mov si, 160
cld
rep movsw
mov cx, 160
good:
mov di, 4000 - 160
mov byte ptr es:, ' '
add di, 2
loop good
jmp short end_ok
;错误信息提示
item5:
mov al, byte ptr cs:
cmp al, 0
je item5_2
mov byte ptr es:, al
mov byte ptr es:, bl
inc si
add di, 2
jmp short item5
item5_2:
jmpend_ok
end_1:
nop
code ends
end start
下面是我用《直接定址表》的思路编写的这个程序我这个程序是从1开始输出到4,但是这种方法可能到别的程序中会不好用因为我是直接找的地址在一个一个把他们加到相应的数据段中
assume cs:code
code segment
start:
mov ax, cs
mov ds, ax
mov si, offset input
mov ax, 0h
mov es, ax
mov di, 0200h
mov cx, offset end_1 - offset input
cld
rep movsb
cli
mov word ptr es:, 0200h
mov word ptr es:, 0h
sti
mov ax, 4c00h
int 21h
input:
jmp short option_1
dw item1 + 01d6h , item2 + 01d6h, item3 + 01d6h, item4 + 01e1h, 0;该地址是我用debug找到他在编译的时候相应的地址,加上相应的数据等于他在0000:0200中储存的地址再用call跳转过去
;在masm编译中item标记本身也是有数据的item1=005f、item2=0073、item3=007e、item4=0089
;item1中的数据005fh+01d6h就等于第一个标记的偏移地址0000:0235
option_1:
push ax
push bx
push ds
push es
push cx
push di
mov ah, 2
mul ah
mov ah, 0
sub al, 2
mov bl, al
mov bh, 0
mov ax, 0b800h
mov es, ax
mov di, 0
mov cx, 2000
call word ptr cs:
pop di
pop cx
pop es
pop ds
pop bx
pop ax
iret
;清屏
item1: ;在我的系统中他的地址是0000:0235
mov byte ptr es:, ' '
add di, 2
loop item1
mov ah, 2;调整光标位置
mov bh, 0;光标所在第几页 一共有6页
mov dh, 0;光标所在第几行 一页有25行
mov dl, 0;每页有160个字节80个字每个字包含一个数据字节一个属性字节
int 10h ;十号中断
ret
;设置前景色
item2: ;他的地址0000:0249
mov byte ptr es:, 2
add di, 2
loop item2
ret
;设置背景色
item3: ;他的地址0000:0254
mov byte ptr es:, 01100000b
add di, 2
loop item3
ret
;向上滚动一行
item4: ;他的地址0000:026a
mov ds, ax
mov si, 160
cld
rep movsw
mov cx, 160
good:
mov di, 4000 - 160
mov byte ptr es:, ' '
add di, 2
loop good
ret
end_1:
nop
code ends
end start
下面的代码是我用视频中的思路写出的程序该程序执行不了会产生错误具体原因我会在下面说明
assume cs:code
code segment
start:
mov ax, cs
mov ds, ax
mov si, offset input
mov ax, 0h
mov es, ax
mov di, 0200h
mov cx, offset end_1 - offset input
cld
rep movsb
cli
mov word ptr es:, 0200h
mov word ptr es:, 0h
sti
mov ax, 4c00h
int 21h
input:
jmp short option_1
data dw item1, tem2, item3, item4, 0
;这里会出现一个很大的问题就是这里所记录的地址信息是06.asm经过masm编译的但是我们现在把他储存在了0000:0200这个数据段之后所以现在item1中储存的地址信息应是以
;段地址为0000偏移地址为0200之后的地址,但是他已经被储存在了内存中不会再次经过编译所以执行的时候跳转的地址会出现错误具体原因我会在下面给出解释
option_1:
push ax
push bx
push ds
push es
push cx
push di
mov ah, 2
mul ah
mov ah, 0
sub al, 2
mov bl, al
mov bh, 0
mov ax, 0b800h
mov es, ax
mov di, 0
mov cx, 2000
call word ptr data
pop di
pop cx
pop es
pop ds
pop bx
pop ax
iret
;清屏
item1:
mov byte ptr es:, ' '
add di, 2
loop item1
mov ah, 2;调整光标位置
mov bh, 0;光标所在第几页 一共有6页
mov dh, 0;光标所在第几行 一页有25行
mov dl, 0;每页有160个字节80个字每个字包含一个数据字节一个属性字节
int 10h ;十号中断
ret
;设置前景色
item2:
mov byte ptr es:, 2
add di, 2
loop item2
ret
;设置背景色
item3:
mov byte ptr es:, 01100000b
add di, 2
loop item3
ret
;向上滚动一行
item4:
mov ds, ax
mov si, 160
cld
rep movsw
mov cx, 160
good:
mov di, 4000 - 160
mov byte ptr es:, ' '
add di, 2
loop good
ret
end_1:
nop
code ends
end start
《使用直接定址表遇到的问题》
这篇文章里介绍了为什么失败的原因
https://blog.csdn.net/grantxx/article/details/7673342?utm_source=jiancool 很棒!看得出非常认真! 小甲鱼 发表于 2019-4-12 03:53
很棒!看得出非常认真!
谢谢,建立该网站,继续努力,争取每天都有进步
页:
[1]