《汇编语言》- 读书笔记 - 第17章-使用 BIOS 进行键盘输入和磁盘读写

《汇编语言》- 读书笔记 - 第17章-使用 BIOS 进行键盘输入和磁盘读写

  • 17.1 int9 中断例程对键盘输入的处理
    • 键盘缓冲区
  • 17.2 使用 int 16h 中断例程读取键盘缓冲区
    • 编程
    • 检测点 17.1
  • 17.3 字符串的输入
    • 编程:字符串输入程序
      • 需求
      • 分析
        • 处理过程
        • 子程序
        • 完整代码
  • 17.4 应用 int 13h 中断例程对磁盘进行读写
    • 3.5 英寸 1.44兆 软盘
    • INT 13H 直接磁盘服务 Direct Disk Service
      • 功能 02H 读扇区
      • 功能 03H 写扇区
    • 编程:将当前屏幕的内容保存在磁盘上
  • 实验 17 编写包含多个功能子程序的中断例程
  • 课程设计 2

17.1 int9 中断例程对键盘输入的处理

键盘缓冲区

CPU响应中断
保存上下文
跳转至 INT 9H 中断服务例程
A
shift + A
按下 左 shift
清除中断请求
恢复上下文
返回至主程序
松开 左 shift
清除中断请求
恢复上下文
返回至主程序
清除中断请求
恢复上下文
返回至主程序
清除中断请求
恢复上下文
返回至主程序
开始
用户按下键
触发中断 INT 9H
60h 端口 读取扫描码
检测状态字节
扫描码 1EhASCII码 61h
扫描码 1EhASCII码 41h
[ 0040:17]第1位置 1
结束
[ 0040:17]第1位置 0
存储到缓冲区
高位= 扫描码,低位= ASCII码
[ 1E61]
存储到缓冲区
高位= 扫描码,低位= ASCII码
[ 1E41]

输入: A、B、C、D、E、Shift_A、A

  • 写入顺序从左➡️右
-123456789ABCDEF
写入前
输入A1E61
输入B1E613062
输入C1E6130622E62
输入D1E6130622E622064
输入E1E6130622E6220641265
输入Shift_A1E6130622E62206412651E41
输入A1E6130622E62206412651E411E61

17.2 使用 int 16h 中断例程读取键盘缓冲区

从键盘缓冲区中读取一个键盘输入,并且将其从缓冲区中删除:

mov ah,0
int 16h

结果: (ah)=扫描码,(al)=ASCII 码。

-读取字符ahal123456789ABCDEF
读取前1E6130622E62206412651E411E61
执行1次A1E6130622E62206412651E411E61
执行2次B30622E62206412651E411E61
执行3次C2E62206412651E411E61
执行4次D206412651E411E61
执行5次E12651E411E61
执行6次Shift_A1E411E61
执行7次A1E61

从上面我们可以看出,int 16h 中断例程的0号功能,进行如下的工作。

  1. 检测键盘缓冲区中是否有数据;
  2. 没有则继续做第1步;
  3. 读取缓冲区第一个字单元中的键盘输入;
  4. 将读取的扫描码送入 ah,ASCII码送入 al;
  5. 将已读取的键盘输入从缓冲区中删除。

BIOS 的 int 9中断例程int l6h中断例程 配合工作。
按键触发 int 9向键盘缓冲区中写入,
应用程序调用 int 16h从缓冲区中读出。

编程

r 设置字符为红色,按 g 设置字符为绿色,按 b 设置字符为蓝色。

assume cs:code
code segment
 start: mov ah,0
		int 16h
		
		mov ah,1
		cmp al,'r'
		je red
		cmp al,'g'
		je green
		cmp al,'b'
		je blue
		jmp short sret
	
   red: shl ah,1
 green: shl ah,1
	
  blue: mov bx,0b800h
		mov es,bx
		mov bx,1
		mov cx,2000
	 s:	and byte ptr es:[bx],11111000b
		or es:[bx],ah
		add bx,2
		loop s
		
  sret: mov ax,4c00h
		int 21h	
code ends
end start
 划  线 ——说 明 ——————————闪烁背景红背景绿背景蓝高亮前景红前景绿前景蓝
mov ah,1设置颜色为 1,对应蓝色00000001
red: shl ah,1左移一位后成为绿色00000010
green: shl ah,1再左移一位后成为红色00000100
  1. 最开始给 ah 默认值是 0000 0001b 蓝色
  2. 如果是按 r 跳到标号red 向下执行到 blue 总共左移2次。成为红色
  3. 如果是按 g 跳到标号green 向下执行到 blue 总共左移1次。成为绿色
  4. 如果是按 b 跳到标号blue 无需左移。直接使用蓝色
rgb
rg

检测点 17.1

《汇编语言》- 读书笔记 - 各章检测点归档 - 检测点 17.1

17.3 字符串的输入

编程:字符串输入程序

需求

  1. 在输入的同时需要显示这个字符串;
  2. 一般在输入回车符后,字符串输入结束;
  3. 能够删除已经输入的字符。

参考命令行输入场景。

分析

处理过程
开始
调用 int 16h
读取键盘输入
字符键
退格
回车
压入字符栈
从字符栈
弹出一个字符
向字符栈
压入 0
显示所有字符
返回
子程序
  • charstack 入栈、出栈和显示
    我们将上图中的几块业务,拆为子程序来实现。
子程序字符栈的入栈、出栈和显示。
参数(ah)=功能号,0=入栈,1=出栈,2=显示
0 号功能(入栈): (al)=入栈的字符
1 号功能(出栈): (al)=返回的字符
2 号功能(显示): (dh)=行、(dl)=列
参数ds:si 指向字符栈空间
  • getstr 获取字符串
    接收字符串输入,判断后调用:入栈、出栈和显示
完整代码
assume cs:code,ds:data

data segment
	mystr db 255 dup(0)	; 声明字符栈
data ends

code segment
 start: mov ax,data			; 设置字符栈所在段地址
		mov ds,ax
		mov ax,offset mystr	; 设置字符栈偏移地址
		mov di,ax
		
		call getstr			; 调用子程序开始字符串输入

	ok:	mov ax,4c00h
		int 21h
	
; =======================================================	
; ------------------- 子程序 -----------------
; 接收字符串输入,判断后调用:入栈、出栈和显示
; -------------------------------------------------------
; 参数:无
; 返回:无
; -------------------------------------------------------
getstr:	
		push ax			; 备份寄存器
getstrs:
		mov ah,0
		int 16h
		cmp al,20h
		jb nochar		; ASCII码小于20h,说明不是字符
		mov ah,0
		call charstack	; 字符入栈
		mov ah,2
		call charstack	; 显示栈中的字符
		jmp getstrs		; 跳开头,重新开始获取输入字符
nochar:
		cmp ah,0eh		; 对比扫描码,如果是【退格键】跳 backspace
		je backspace
		cmp ah,1ch		; 对比扫描码,如果是【Enter】跳 enter
		je enterkey
		jmp getstrs		; 跳开头,重新开始获取输入字符
backspace:
		mov ah,1		; 调用子程序 charstack 的功能1 出栈一个字符
		call charstack
		mov ah,2		; 调用子程序 charstack 的功能2 显示字符串
		call charstack
		jmp getstrs		; 跳开头,重新开始获取输入字符
enterkey:
		mov ah,0		; 调用子程序 charstack 的功能0 入栈一个字符 cs:38
		mov al,0		; 入栈的字符 = 0
		call charstack
		mov ah,2		; 调用子程序 charstack 的功能2 显示字符串
		call charstack
		
		pop ax			; 还原寄存器
		ret
; -------------------- 子程序 -----------------
; =======================================================

; =======================================================	
; ------------------- 子程序 -----------------
; 字符栈的入栈、出栈和显示
; -------------------------------------------------------
; 参数:(ah)=功能号,0=入栈,1=出栈,2=显示
; 		0 号功能(入栈): (al)=入栈的字符
; 		1 号功能(出栈): (al)=返回的字符
; 		2 号功能(显示): (dh)=行、(dl)=; 参数:ds:si 指向字符栈空间
; -------------------------------------------------------
charstack:
		jmp short charstart	; 直接跳过数据块,到代码开关

table	dw	charpush,charpop,charshow	; 子程序入口
top		dw	0							; 字符串长度

charstart:
		push bx			; 备份寄存器
		push dx
		push di
		push es
		
		; 检查 ah 功能号:如果>2退出。否则按索引调用子程序	
		cmp ah,2	
		ja sret
		mov bl,ah
		mov bh,0
		add bx,bx				; table 是 dw 类型,所以是bx*2
		jmp word ptr table[bx]	; 调用子程序
		
charpush:				; 字符入栈
		mov bx,top
		mov [si][bx],al		; al中的字符,存入 ds:[si+bx]
		inc top				; top + 1 对应字符串长度
		jmp sret			; 跳结束

charpop:				; 上一个字符出栈
		cmp top,0			; 如果字符串空了,直接结束
		je sret
		dec top				; top - 1 对应字符串长度
		mov bx,top			
		mov al,[si][bx]		; 从 ds:[si+bx] 取字符存入 al
		jmp sret			; 跳结束
		
charshow:				; 显示字符(算出显示位置)
		mov bx,0b800h		; 设置显存
		mov es,bx
		mov al,160			; 每行160字节,用于计算行偏移
		mov ah,0
		mul dh				; 行偏移 = 每行字节数al * 行数dh
		mov di,ax			; 行偏移存入 di
		add dl,dl			; 列偏移 = 列号dl * 2 
		mov dh,0
		add di,dx			; 显示位置di = 行偏移di + 列偏移dx
		
		mov bx,0			; 字符索引置 0 用作是否打印的判断条件
		
charshows:
		cmp bx,top			; 循环类似于 for(bx=0; bx < top; bx++)
		jne noempty					; bx == top 时 noempty
		mov byte ptr es:[di],' '	; 末尾多打个“空格”
										; 用于覆盖掉被退格的字符
		jmp sret					; 跳结束
		
noempty:				; 字符串非空,就打印出来
		mov al,[si][bx]				; 从 ds:[si+bx] 取字符
		mov es:[di],al				; 显示到 es:[di]
		mov byte ptr es:[di+2],' '	; 每个字符后插入一个空格
										; 开路先锋,刷掉屏幕上原有字符,
										; 让字符串看上去末尾总有个留
		inc bx						; bx 指向下一个字符
		add di,2					; di 指向下一个显示字符的位置
		jmp charshows				; 跳转 charshows 直到所有字符打印完成
		
sret:
		pop es			; 还原寄存器
		pop di
		pop dx
		pop bx
		ret
; -------------------- 子程序 -----------------
; =======================================================
code ends
end start

17.4 应用 int 13h 中断例程对磁盘进行读写

3.5 英寸 1.44兆 软盘

磁道扇区字节大小
280185121440KB ≈ 4.44M

INT 13H 直接磁盘服务 Direct Disk Service

功能 02H 读扇区

功能02H读扇区
入口参数AH02H
参数AL=扇区数(要读多少扇区)
DL=驱动器,00H~7FH 软盘(0=A,1=B);80H~0FFH 硬盘(80h=C,81h=B)
CH=柱面(磁道号)
DH=磁头(面)
CL=扇区
ES:BX =缓冲区的地址(指向接收数据的内存区)
返回操作成功:ah=0; al=读取的扇区数
操作失败:ah=错误代码

功能 03H 写扇区

功能03H写扇区
入口参数AH03H
参数AL=扇区数(要写多少扇区)
DL=驱动器,00H~7FH 软盘(0=A,1=B);80H~0FFH 硬盘(80h=C,81h=B)
CH=柱面(磁道号)
DH=磁头(面)
CL=扇区
ES:BX =缓冲区的地址(指向要写入磁盘的数据)
返回操作成功:ah=0; al=写入的扇区数
操作失败:ah=错误代码

编程:将当前屏幕的内容保存在磁盘上

分析: 1屏的内容占 4000个字节,需要8个扇区,用0面0道的1~8扇区存储显存中的内容。
1.44M软盘(3.5英寸高密度软盘)每个扇区的字节数是512字节。

assume cs:code
code segment
 start: mov ax,0b800h	; es:bx 指向显示缓存第1页
		mov es,ax
		mov bx,0
		
		mov al,8		; 写入的扇区数
		mov dl,0        ; A 盘 
		mov dh,0        ; 磁头
		mOV ch,0		; 磁道号
		mov cl,1		; 扇区号
		mov ah,3        ; 功能03H 写扇区
		int 13h         ; 调用“直接磁盘服务”

	ok:	mov ax,4c00h
		int 21h
code ends
end start

实验 17 编写包含多个功能子程序的中断例程

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

课程设计 2

《汇编语言》- 读书笔记 - 第17章-课程设计 2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/436951.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis-Plus——06,CRUD查

CRUD查 一、普通查询1.1、通过id查询单个用户1.2、通过id查询多个用户1.3、条件查询 通过map封装 二、分页查询2.1、配置分页插件2.2、运行方法 三、通过wrapper条件构造器查询3.1、查询name不为空&#xff0c;email不为空&#xff0c;age大于18的用户3.2、查询nameJone的用户3…

[技术杂谈]解决右键没有vscode打开选项的问题

问题&#xff1a; 点击鼠标右键没有‘使用vscode打开’的选项。 原因&#xff1a; 在安装时没有勾选相关选项 解决办法&#xff1a; 新建一个reg文件写入下面文件&#xff0c;注意替换自己真实Code.exe路径 Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\*\she…

计算机考研❗️这些院校(含985)性价比巨高

✅厦门大学 (985) 不歧视双非&#xff0c;全靠实力&#xff0c;校园环境还贼美 ✅重庆大学 (985) 信息公开透明&#xff0c;复试抽签 ✅北京师范大学 (985) 不歧视本科出身&#xff0c;面试抽签答题。 ✅东南大学 (985) 保护第一志愿&#xff0c;复试抽签 ✅吉林大学 (…

3Dmax中VR渲染太阳光渲染参数怎么设置?渲染100云渲染助力

我们用3Dmax建模时一些场景会用到太阳光&#xff0c;那么渲染参数是如何设置的呢&#xff1f; 我们一起来看看&#xff0c;直接上图 以上就是详细的参数设置&#xff0c;大家可以用做参考&#xff0c;如果本地渲染慢的朋友可以考虑使用云渲染100 机器多&#xff0c;渲染稳定不…

仪酷LabVIEW OD实战(4)——Object Detection+OpenVINO工具包快速实现yolo目标检测

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f384;所属专栏&#xff1a;『仪酷LabVIEW目标检测工具包实战』 &#x1f4d1;上期文章&#xff1a;『仪酷LabVIEW OD实战(3)——Object Detectiononnx工具包快速…

【新版Hi3521DV200处理器性能】

新版Hi3521DV200处理器性能 Hi3521DV200是针对多路高清/超高清&#xff08;1080p/4M/5M/4K&#xff09;DVR产品应用开发的新一代专业SoC芯片。Hi3521DV200集成了ARM Cortex-A7四核处理器和性能强大的神经网络推理引擎&#xff0c;支持多种智能算法应用。同时&#xff0c;Hi352…

微服务之商城系统

一、商城系统建立之前的一些配置 1、nacos Nacos是一个功能丰富的开源平台&#xff0c;用于配置管理、服务发现和注册、健康检查等&#xff0c;帮助构建和管理分布式系统。 在linux上安装nacos容器的命令&#xff1a; docker run --name nacos-standalone -e MODEstandalone …

在centos7系统中如何给docker配置代理

一、需求场景 生产环境私有云中&#xff0c;通常一个集群的机器中只有几台机器可以直接访问公网&#xff0c;其他机器需要通过代理的方式从能访问公网的机器出去&#xff0c;在已经做了如下配置之后&#xff0c;使用docker pull命令已经报错超时timeout&#xff0c;这时可以尝…

python中的defaultdict

collections.defaultdict 是 collections 模块提供的一个有用的类&#xff0c;它是内置字典类 dict 的一个子类。与普通字典一样&#xff0c;可以进行元素的访问、添加、删除等操作。区别在于当访问一个不存在的键时&#xff0c;defaultdict 会返回默认值&#xff0c;而不会引发…

Go程序是如何编译并运行起来的(图文详解)

Go程序是如何编译的 从hello RdrB1te开始 package main import "fmt" func main() { fmt.Println("hello RdrB1te") }不实际编译它&#xff0c;只输出它的编译过程&#xff1a; go build -n简单的编译过程分析&#xff1a; 上面的过程确认了两个…

SpringBoot集成JSP和war包部署到Tomcat

SpringBoot集成JSP 加依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot…

开抖音小店一个月,就摸清楚了电子面单发货,不用担心被查无货源

大家好&#xff0c;我是电商花花。 开抖音小店一个月的时间&#xff0c;就摸清楚了抖音小店的电子面单发货&#xff0c;再也不用担心做无货源模式被平台稽查了。 现在平台的规则越来越严格&#xff0c;很多抖音小店的商家为了避免违规&#xff0c;为了不被平台稽查&#xff0…

传感器在TWS耳机中的应用

一项音频产品使用报告显示&#xff0c;消费者对音频设备中音质差异的认知不断提高&#xff0c;对在设备上获得最佳音频体验的期待也在提升。自适应主动降噪、语音增强、空间音频等是提升TWS耳机用户体验的主要因素&#xff0c;这些技术背后都有运动传感器的身影&#xff0c;包括…

Gartner对未来5年全球信息安全和风险管理市场的预测分析:影响市场的四大因素及对相关产品市场的影响

到 2023 年&#xff0c;信息安全和风险管理市场的最终用户支出将增长至 1850 亿美元&#xff08;现价美元&#xff09;&#xff0c;货币稳定增长率为 13.4%。到2027年&#xff0c;市场规模将达到2870亿美元&#xff0c;按固定汇率计算&#xff0c;2022年至2027年的复合年增长率…

Windows系统搭建VisualSVN并结合内网穿透实现远程访问本地服务

文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 前言 SVN 是 subversion 的缩写&#xff0c;是一个开放源代码的版本控制系统…

【开课】云贝教育2024年3月9日-PostgreSQL中级工程师PGCE认证培训开课啦!

课程介绍 根据学员建议和市场需求,规划和设计了《PostgreSQL CE 认证课程》,本课程以内部原理、实践实战为主&#xff0c;理论与实践相结合。课程包含PG 简介、安装使用、服务管理、体系结构等基础知识。同时结合一线实战案例&#xff0c; 面向 PG 数据库的日常维护管理、服务和…

“色狼”用英语怎么说?柯桥日常英语,成人英语口语学习

最近有粉丝问我"色狼"英文翻译是啥 首先声明不是"colour wolf"哈 关于“色狼”的英文表达有很多 快和C姐一起来看看吧&#xff01; 1.pervert 这个单词的意思是变态、色狼 是对性变态者最直观的描述 He is such a pervert&#xff01; I saw him lo…

相对于 Linux,Windows Server 存在的意义是什么?

相对于 Linux&#xff0c;Windows Server 存在的意义是什么&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Linux 的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给…

即插即用篇 | YOLOv8 引入 NAM 注意力机制 | 《NAM: Normalization-based Attention Module》

论文名称:《NAM: Normalization-based Attention Module》 论文地址:https://arxiv.org/pdf/2111.12419.pdf 代码地址:https://github.com/Christian-lyc/NAM 文章目录 1 原理2 源代码3 添加方式4 模型 yaml 文件template-backbone.yamltemplate-small.yamltemplate-large…

flutter编译后的windows程序缺少msvcp140.dllvcruntime140.dllvcruntime140_1.dll解决办法

//就是很多博文中提到了三剑客 msvcp140.dll vcruntime140.dll vcruntime140_1.dll 1.没有vs环境的不要把生成的debug下的exe发给别人&#xff0c;会出现莫名其妙的问题。缺少各种DLL文件&#xff0c;我这边收集了上面三个的dll下载链接&#xff1a;flutterdll.rar - 蓝奏云 2…
最新文章