《汇编语言》- 读书笔记 - 第16章-实验16 编写包含多个功能子程序的中断例程

本文主要是介绍《汇编语言》- 读书笔记 - 第16章-实验16 编写包含多个功能子程序的中断例程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《汇编语言》- 读书笔记 - 第16章-实验16 编写包含多个功能子程序的中断例程

  • 需求
  • 代码
    • int 7ch 中断例程(安装程序)
    • 分析
      • ORG(Origin)
  • 调用
    • 1. 清屏
    • 2. 设置前景色;
    • 3. 设置背景色;
    • 4. 向上滚动一行。
  • 扩展实现

需求

安装一个新的 int 7ch 中断例程,为显示输出提供如下功能子程序。

功能1. 清屏;
2. 设置前景色;
3. 设置背景色;
4. 向上滚动一行。
参数 ahah 寄存器传递功能号0 表示清屏,1 表示设置前景色,2 表示设置背景色, 3 表示向上滚动一行;
参数 alal 传送颜色值(al){ 0,1,2,3,4,5,6,7 }
用于12号功能

代码

int 7ch 中断例程(安装程序)

assume cs:code
code segmentstart: ; ---------------- 安装(复制数据) ----------------mov ax,csmov ds,axmov si,offset i7ch		;设置 ds:si 指向源地址mov ax,0mov es,axmov di,200h				;设置 es:di 指向目的地址mov cx,offset i7chend -offset i7ch	;设置 cx为传输长度cld					;设置传输方向为正。movsb中si,di递增rep movsb			;重复复制数据次数由 cx 控制; ---------------- 安装(复制数据) ----------------; ----------------- 设置中断向量 -----------------mov ax,0mov es,ax						; 段地址 0cli								; 临时屏蔽中断mov word ptr es:[7ch*4],200h	; 设置【中断处理程序】的:偏移地址mov word ptr es:[7ch*4+2],0		; 设置【中断处理程序】的:段地址sti								; 恢复中断响应; ----------------- 设置中断向量 -----------------mov ax,4c00hint 21h; =======================================================
; --------------------- 中断处理程序 --------------------
; 设置显示效果
; -------------------------------------------------------
; -------------------------------------------------------org 200h ; ORG 指定下面代码从一个特定地址开始编译i7ch:	; =======================================================	; ------------------- 子程序 setscreen  -----------------; 设置显示效果; -------------------------------------------------------; 参数: ah	功能号:0 表示清屏,1 表示设置前景色,2 表示设置背景色, 3 表示向上滚动一行;; 参数: al	颜色值。用于12号功能; 返回:; -------------------------------------------------------setscreen:jmp short set;;		 0:21D 0:238 0:256 0:278			table dw sub1, sub2, sub3, sub4		; d 0:202 209set:push bx			; 备份寄存器cmp ah,3		; 判断功能号是否大于3ja sretmov bl,ahmov bh,0add bx,bx		; 根据 ah 中的功能号计算对应子程序在 table 表中的偏移call word ptr table[bx];sret:	pop bx			; 还原寄存器iret			; 返回; -------------------- 子程序 setscreen -----------------; =======================================================; =======================================================	; ---------------------- 子程序 sub1 --------------------; 清屏:; 将显存中当前屏幕中的字符设为空格符; -------------------------------------------------------; 参数:; 返回:; -------------------------------------------------------sub1:push bx			; 备份寄存器push cxpush esmov bx,0b800hmov es,bxmov bx,0mov cx,2000sub1s:	mov byte ptr es:[bx],' '	; 当前屏全设为空格add bx,2loop sub1spop es			; 备份寄存器pop cxpop	bxret				; 返回; ---------------------- 子程序 sub1 --------------------; =======================================================; =======================================================	; ---------------------- 子程序 sub2 --------------------; 设置前景色:设置当前屏幕中所有奇列的第012位(前景色); -------------------------------------------------------; 参数:; 返回:; -------------------------------------------------------sub2:push bx			; 备份寄存器push cxpush esmov bx,0b800hmov es,bxmov bx,1						; 设置字符属性从 1 开始mov cx,2000sub2s:	and byte ptr es:[bx],11111000b	; 清空前景色 012or es:[bx],al					; 应用 al 传来的颜色值add bx,2loop sub2spop es			; 备份寄存器pop cxpop	bxret				; 返回; ---------------------- 子程序 sub2 --------------------; =======================================================; =======================================================	; ---------------------- 子程序 sub3 --------------------; 设置背景色:设置当前屏幕中所有奇列的第456位(背景色); -------------------------------------------------------; 参数:; 返回:; -------------------------------------------------------sub3:push bx			; 备份寄存器push cxpush esmov cl,4shl al,cl		mov bx,0b800hmov es,bxmov bx,1						; 设置字符属性从 1 开始mov cx,2000sub3s:	and byte ptr es:[bx],10001111b	; 清空 4 ~ 6or es:[bx],al					; 应用 al 传来的颜色值add bx,2loop sub3spop es			; 备份寄存器pop cxpop	bxret				; 返回; ---------------------- 子程序 sub3 --------------------; =======================================================; =======================================================	; ---------------------- 子程序 sub4 --------------------; 向上滚动一行:依次将第 n+1 行的内容复制到第n行处;最后一行为空。; -------------------------------------------------------; 参数:; 返回:; -------------------------------------------------------sub4:push cx			; 备份寄存器push sipush dipush espush dsmov si,0b800hmov es,simov ds,simov si,160		; ds:si 指向第 n+1 行mov di,0		; es:di 指向第 n 行cldmov cx,24		; 共复制 24 行sub4s:	push cxmov cx,160rep movsb		; 复制pop cxloop sub4smov cx,80mov si,0sub4s1:mov	byte ptr [160*24+si],' 'add si,2loop sub4s1pop ds			; 备份寄存器pop espop	dipop	sipop	cxret				; 返回; ---------------------- 子程序 sub4 --------------------; =======================================================i7chend:	nop
; --------------------- 中断处理程序 --------------------
; =======================================================
code ends
end start

分析

本实验的主要练习的是使用直接定址表存四个子程序的入口地址。

其它部分之前都有现成代码可以复用:

  1. 核心业务 屏幕设置部分第16章 16.4 已经实现可以直接用。
  2. 安装中断例程 参考 第13章-实验13
  3. 子程序调用 参考 第11章-实验11 编写子程序

在这里插入图片描述

ORG(Origin)

在x86汇编语言中,ORG指令的全称是Origin,它指示汇编程序从指定地址开始放置汇编指令生成的机器码。在Intel 8086及后续的x86架构中,ORG作为伪指令使用,用于设置汇编源代码中下一条指令的地址标记。

  • 数据标号 table 的地址错误问题
    7ch 中断例程安装时 table 记录的安装程序中它所处的偏移位置
    中断例程 直正调用时 call word ptr table[bx] table[bx] 取值肯定是错的。
    所以这里可以用 org 指定程序的起始地址。

ORG在以下场景中需要用到ORG指令:

  1. 确定程序起始执行地址,如设置引导扇区地址。
  2. 大型项目模块化编程时,给不同模块分配独立的内存地址空间。
  3. 插入或修改代码时,精确调整新代码在内存中的位置。

总的来说,ORG用于在汇编过程中控制代码在内存中的布局和定位。

调用

1. 清屏

assume cs:code
code segmentstart: mov ah,0int 7chmov ax,4c00hint 21h
code ends
end start

在这里插入图片描述

2. 设置前景色;

assume cs:code
code segmentstart: mov ah,1mov al,3int 7chmov ax,4c00hint 21h
code ends
end start

在这里插入图片描述

3. 设置背景色;

assume cs:code
code segmentstart: mov ah,2mov al,6int 7chmov ax,4c00hint 21h
code ends
end start

在这里插入图片描述

4. 向上滚动一行。

assume cs:code
code segmentstart: mov ah,3int 7chmov ax,4c00hint 21h
code ends
end start

在这里插入图片描述

扩展实现

重写 int 09h 例程,实现热键设置屏幕:

热键F1F2F3F4
功能清屏设置前景色设置背景色向上滚动一行
assume cs:code
stack segmentdb 128 dup(0)
stack endscode segmentstart: mov ax,stack		; 设置栈段和栈顶位置mov ss,axmov sp,128;----------- 打个小补丁。避免重复运行后搞丢 int9 导致输入瘫痪 -----------mov ax,0mov ds,axmov ax,ds:[2B4h]cmp ax,5350h		; 判断 ds:[2B4]=5053 则已安装过(值是调试运行查的)je ok; -------- 安装: 复制中断例程到目标内存 -------mov ax,cs			;设置 ds:si 指向源地址mov ds,axmov si,offset int9mov ax,0			;设置 es:di 指向目的地址mov es,axmov di,2B4h			mov cx,offset int9end-offset int9	;设置 cx为传输长度cld					;设置传输方向为正。movsb中si,di递增rep movsb			;重复复制数据次数由 cx 控制; -------- 安装: 复制中断例程到目标内存 -------; ---------- 备份原 int9 入口到 [0:200~0203] ----------push es:[9*4]pop es:[2B0h]push es:[9*4+2]pop es:[2B0h+2h]; ---------- 备份原 int9 入口到 [0:200~0203] ----------; ---------- 设置中断向量表 ----------cli							; 临时屏蔽中断mov word ptr es:[9*4],2B4h	; 设置的偏移地址mov word ptr es:[9*4+2],0	; 设置的段地址sti							; 恢复中断; ---------- 设置中断向量表 ----------ok:	mov ax,4c00hint 21h; =======================================================	
; --------------------- 子程序 int 9  -------------------
; 调用 F1=清屏; F2=设置前景色; F3=设置背景色; F4=向上滚动一行;
; -------------------------------------------------------
; 参数:; 返回:; -------------------------------------------------------
int9:push ax 		; 备份寄存器push bxpush cxpush esmov ax,0b800hmov es,axin al,60h		;60h端口读取数据; 模拟 int 指令,用 call 调用原 int 9pushf						; 进入中断后 IF、TF已经是0 直接入栈即可call dword ptr cs:[2B0h] 	; 调用原来的 int 9 中断例程cmp al,3Bh		; 判断是 F1je s1cmp al,3Ch		; 判断是 F2je s2		cmp al,3Dh		; 判断是 F3je s3cmp al,3Eh		; 判断是 F4je s4jmp int9rets1:	mov ah,0		; F1=清屏int 7chjmp int9rets2:	mov ax,es:[1]	; F2=设置前景色and al,00000111binc almov ah,1int 7chjmp int9ret	s3:	mov ax,es:[1]	; F3=设置背景色and al,01110000bmov cl,4shr al,clinc aland al,00000111bmov ah,2int 7chjmp int9rets4:	mov ah,3		; F4=向上滚动一行int 7chint9ret:pop es			; 还原寄存器pop cxpop bxpop axiret			; 返回
int9end:nop; --------------------- 子程序 int 9 ------------------
; =======================================================
code ends
end start

在这里插入图片描述

这篇关于《汇编语言》- 读书笔记 - 第16章-实验16 编写包含多个功能子程序的中断例程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/777359

相关文章

苹果macOS 26 Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色

《苹果macOS26Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色》在整体系统设计方面,macOS26采用了全新的玻璃质感视觉风格,应用于Dock栏、应用图标以及桌面小部件等多个界面... 科技媒体 MACRumors 昨日(6 月 13 日)发布博文,报道称在 macOS 26 Tahoe 中

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

MybatisPlus service接口功能介绍

《MybatisPlusservice接口功能介绍》:本文主要介绍MybatisPlusservice接口功能介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录Service接口基本用法进阶用法总结:Lambda方法Service接口基本用法MyBATisP

Java反射实现多属性去重与分组功能

《Java反射实现多属性去重与分组功能》在Java开发中,​​List是一种非常常用的数据结构,通常我们会遇到这样的问题:如何处理​​List​​​中的相同字段?无论是去重还是分组,合理的操作可以提高... 目录一、开发环境与基础组件准备1.环境配置:2. 代码结构说明:二、基础反射工具:BeanUtils

python编写朋克风格的天气查询程序

《python编写朋克风格的天气查询程序》这篇文章主要为大家详细介绍了一个基于Python的桌面应用程序,使用了tkinter库来创建图形用户界面并通过requests库调用Open-MeteoAPI... 目录工具介绍工具使用说明python脚本内容如何运行脚本工具介绍这个天气查询工具是一个基于 Pyt

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

Druid连接池实现自定义数据库密码加解密功能

《Druid连接池实现自定义数据库密码加解密功能》在现代应用开发中,数据安全是至关重要的,本文将介绍如何在​​Druid​​连接池中实现自定义的数据库密码加解密功能,有需要的小伙伴可以参考一下... 目录1. 环境准备2. 密码加密算法的选择3. 自定义 ​​DruidDataSource​​ 的密码解密3

Python函数返回多个值的多种方法小结

《Python函数返回多个值的多种方法小结》在Python中,函数通常用于封装一段代码,使其可以重复调用,有时,我们希望一个函数能够返回多个值,Python提供了几种不同的方法来实现这一点,需要的朋友... 目录一、使用元组(Tuple):二、使用列表(list)三、使用字典(Dictionary)四、 使