汇编语言(王爽)-实验16
实验 16 编写包含多个功能子程序的中断例程
安装一个新的 int 7ch 中断例程,为显示输出提供如下功能子程序:
- 清屏。
- 设置前景色
- 设置背景色
- 向上滚动一行
入口参数说明:
- 用 ah 寄存器传递功能号:0 表示清屏,1 表示设置前景色,2 表示设置背景色,3 向上滚动一行
- 对于 2、3 号功能,用 al 传递颜色值,(al)∈ {0, 1, 2, 3, 4, 5, 6, 7}。
前提条件 (基础知识)
要完成这个实验要了解 jmp 和 call 那两章。比方说 call 是让 IP 寄存器加上一个 offset 还是直接把内存单元的内容作为 IP。了解这一点之后就可以了。
假设我们的中断例程只有一个子程序
这个实验的难点在于怎么正确找到我们子程序的入口,也就是当我们把我们写的中断例程安装到 0:200h 之后怎么才能找到我们的子程序。
书里面说过,所有用到标号的地方,那个标号代表的是地址(p94),再进一步来说其实就是那个标号对应的 IP 寄存器的内容。
所以在 functions 这个标号里面用到的 clear 的意思是 clear 在 code 这个段里面 IP 是多少。
int7c 放在段的开头,安装程序放在后面。汇编器编译代码之后我们的 clear + 200h 相当于 offset clear + 200h。
这里的意思不是说编译器做了 clear 替换成 offset clear,而是我们的 clear 所代表的 IP 恰好就是我们的 offset clear。
对于普通的程序,我们运行的时候第一条指令的 (IP)= 0。安装之后我们把它拷贝到了 0:200h。相当于起点从 0 变成了 200h,
所以要定位到 clear 需要用 clear + 200h。
我们的程序安装之后放在 0:200h 的那个地方,我们用 call word ptr [addr] 的意思是吧 [addr] 的内容作为 IP。
我们要找 clear + 200h,要从 0:200h 那个地方找。当中断例程执行时 (CS) = 0,我们的索引应该是 [200h + offset functions + 功能号 * 2]
程序的设计思想是进入中断例程之后跳转到 dispatch,来决定调用哪一个 function。
assume cs:code code segment int7c: jmp short dispatch functions: dw clear + 200h dispatch: call word ptr cs:functions[0+200H] ; 书的p273,当中断例程执行时 (CS) = 0 iret clear: push ax push es push cx push di mov ax,0b800h mov es,ax mov cx,80*24 mov di,0 clear_fill: mov byte ptr es:[di],' ' add di,2 loop clear_fill pop di pop cx pop es pop ax ret endOfInt7c: nop start: ; install mov ax,0 mov es,ax mov ax,cs mov ds,ax mov si,offset int7c mov di,200H mov cx,offset endOfInt7c - offset int7c cld rep movsb ; setup 7ch * 4 and 7ch * 4 + 2 mov word ptr es:[7ch * 4],200H mov word ptr es:[7ch * 4 + 2],0H ; test int 7ch ; return mov ax,4c00h int 21h code ends end start
完整的程序
子程序的实现参考书上的,对于效果不是特别理想。但是重点在于实现中断子程序的功能。
assume cs:code code segment int7c: jmp short dispatch functions: dw clear + 200h, setFrontColor + 200h, setBackgroundColor + 200h, scroll + 200h dispatch: push bx sub bx,bx mov bl,ah add bx,bx call word ptr cs:functions[bx+200H] pop bx iret clear: push ax push es push cx push di mov ax,0b800h mov es,ax mov cx,80*24 mov di,0 clear_fill: mov byte ptr es:[di],' ' add di,2 loop clear_fill pop di pop cx pop es pop ax ret setFrontColor: push bx push cx push es mov bx,0b800h mov es,bx mov bx,1 mov cx,2000 setFrontColor_loop: and byte ptr es:[bx],11111000b or es:[bx],al add bx,2 loop setFrontColor_loop pop es pop cx pop bx ret setBackgroundColor: push ax push bx push cx push es mov bx,0b800h mov es,bx mov cl,4 shl al,cl mov bx,1 mov cx,2000 setBackgroundColor_loop: and byte ptr es:[bx],10001111b or es:[bx],al add bx,2 loop setBackgroundColor_loop pop es pop cx pop bx pop ax ret scroll: push bx push cx push si push di push es push ds mov bx,0b800h mov es,bx mov ds,bx mov si,160 mov di,0 cld mov cx,24 scroll_loop: push cx mov cx,160 rep movsb pop cx loop scroll_loop ; clear_last_line mov cx,80 mov si,0 scroll_clear_loop: mov byte ptr [160*24+si],' ' add si,2 loop scroll_clear_loop pop ds pop es pop di pop si pop cx pop bx ret endOfInt7c: nop start: ; install mov ax,0 mov es,ax mov ax,cs mov ds,ax mov si,offset int7c mov di,200H mov cx,offset endOfInt7c - offset int7c cld rep movsb ; setup 7ch * 4 and 7ch * 4 + 2 mov word ptr es:[7ch * 4],200H mov word ptr es:[7ch * 4 + 2],0H mov ah,3 mov al,2 ; test int 7ch ; return mov ax,4c00h int 21h code ends end start
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥