奥普瓯江 发表于 2019-4-12 01:46:22

实验 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:59

很棒!看得出非常认真!

奥普瓯江 发表于 2019-4-12 11:42:48

小甲鱼 发表于 2019-4-12 03:53
很棒!看得出非常认真!

谢谢,建立该网站,继续努力,争取每天都有进步
页: [1]
查看完整版本: 实验 16 编写包含多个功能子程序的中断例程