汇编语言(王爽)-实验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 之后怎么才能找到我们的子程序。
书里面说过,所有用到标号的地方,那个标号代表的是地址,再进一步来说其实就是那个标号对应的 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
原文地址:https://www.cnblogs.com/fnmain/p/15123105.html
- RMI
- WebService
- 设计模式之策略模式
- 设计模式之状态模式
- PDF.NET数据开发框架实体类操作实例(for PostgreSQL,并且解决自增问题) PDF.NET数据开发框架实体类操作实例(MySQL)
- 设计模式之代理模式
- 续谈ActiveMQ之java如何操作ActiveMQ(springBoot项目)
- 深入理解JVM原理之编译openjdk7
- 初识ActiveMQ
- Kafka集群安装
- 知其所以然之永不遗忘的算法
- ZOOKEEPER集群搭建及测试
- 【Python环境】Scikit-Learn:开源的机器学习Python模块
- 【Python环境】可爱的 Python: 自然语言工具包入门
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 程序员必备技能之markdown写作
- Python列表操作最全面总结
- Python 0基础开发游戏:打地鼠(详细教程)VS code版本
- Python经典编程题:字符串替换
- Python字典操作总结
- 纯代码系列:Python实现验证码图片(PIL库经典用法用法,爬虫12306思路)
- Python正则表达式快速学习
- 如何上传项目到GitHub
- MySQL查询优化-基于EXPLAIN
- Python操作SQLite数据库
- Python多进程及多线程基础
- Python字符串三种格式化输出
- 你需要知道的Python代码规范性检查(pylint和flake8)
- Linux下安装python环境
- 【5】进大厂必须掌握的面试题-Java面试-spring