鱼C论坛

 找回密码
 立即注册
查看: 1961|回复: 2

[汇编作业] 实验 16 编写包含多个功能子程序的中断例程

[复制链接]
发表于 2019-4-12 01:46:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 奥普瓯江 于 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:[7ch * 4 ], 0200h
                mov word ptr es:[7ch * 4 + 2], 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:[di], ' '
                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:[di + 1], bl
                add di, 2
                loop item2
                
                jmp short end_ok
                
;设置背景色
item3:
                mov byte ptr es:[di + 1], 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:[di], ' '
                add di, 2
                loop good
                
                jmp short end_ok
;错误信息提示
item5:        
                mov al, byte ptr cs:[si + 202h]
                cmp al, 0
                je item5_2
                mov byte ptr es:[di + 1620], al
                mov byte ptr es:[di + 1620 + 1], bl
                inc si
                add di, 2
                
                jmp short item5
item5_2:
                jmp  end_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:[7ch * 4 ], 0200h
                mov word ptr es:[7ch * 4 + 2], 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:[bx + 202h]
                
                pop di
                pop cx
                pop es
                pop ds
                pop bx
                pop ax
                iret
                
;清屏
item1:    ;在我的系统中他的地址是0000:0235
                mov byte ptr es:[di], ' '
                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:[di + 1], 2
                add di, 2
                loop item2
                ret
                
;设置背景色
item3:                ;他的地址0000:0254
                mov byte ptr es:[di + 1], 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:[di], ' '
                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:[7ch * 4 ], 0200h
                mov word ptr es:[7ch * 4 + 2], 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[bx]
                
                pop di
                pop cx
                pop es
                pop ds
                pop bx
                pop ax
                iret
                
;清屏
item1:
                mov byte ptr es:[di], ' '
                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:[di + 1], 2
                add di, 2
                loop item2
                ret
                
;设置背景色
item3:                
                mov byte ptr es:[di + 1], 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:[di], ' '
                add di, 2
                loop good
                ret
end_1:
                nop

code ends
end start
                

《使用直接定址表遇到的问题》
这篇文章里介绍了为什么失败的原因
https://blog.csdn.net/grantxx/ar ... utm_source=jiancool

评分

参与人数 1荣誉 +2 鱼币 +3 贡献 +3 收起 理由
小甲鱼 + 2 + 3 + 3 无条件支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-4-12 03:53:59 | 显示全部楼层
很棒!看得出非常认真!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-4-12 11:42:48 | 显示全部楼层
小甲鱼 发表于 2019-4-12 03:53
很棒!看得出非常认真!

谢谢,建立该网站,继续努力,争取每天都有进步
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-5 17:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表