《汇编语言》- 读书笔记 - 第13章-int 指令

news/2024/7/27 11:04:44

《汇编语言》- 读书笔记 - 第13章-int 指令

  • 13.1 int 指令
  • 13.2 编写供应用程序调用的中断例程
    • 中断例程:求一 word 型数据的平方
      • 主程序
      • 中断处理程序
      • 执行效果
    • 中断例程:将一个全是字母,以0结尾的字符串,转化为大写
      • 主程序
      • 中断处理程序
      • 执行效果
  • 13.3 对 int、iret 和栈的深入理解
      • 主程序
      • 中断处理程序
      • 分析
      • 执行效果
  • 检测点 13.1
  • 13.4 BIOS 和 DOS 所提供的中断例程
  • 13.5 BIOS 和 DOS 中断例程的安装过程
    • BIOS中断例程的安装:
    • DOS中断例程的安装:
  • 13.6 BIOS 中断例程应用
    • 功能 02H 设置光标位置
    • 功能 09H 在光标位置显示字符
  • 13.7 DOS 中断例程应用(INT 21H)
    • 功能 4CH:返回码方式的终止进程
    • 功能 09H:输出一个字符串到标准输出设备上
  • 实验 13 编写、应用中断例程
  • 参考资料

13.1 int 指令

int n 指令的功能是:引发 n 号中断过程,从而执行 n号中断处理程序
系统将一些具有一定功能的子程序,以中断处理程序的方式提供给应用程序调用。
我们在编程的时候,可以用 int 指令调用这些子程序。
当然,也可以自己编写些中断处理程序供别人使用。
以后,我们可以将中断处理程序简称为中断例程

13.2 编写供应用程序调用的中断例程

中断例程:求一 word 型数据的平方

问题一编写、安装中断 7ch 的中断例程。
功能求一 word 型数据的平方。
参数(ax)=要计算的数据。
返回dxax 中存放结果的高 16 位和低 16 位。
应用举例求 2*3456^2 = 16C8000h = 23,887,872

主程序

assume cs:code
code segmentstart:	mov ax,3456		; (ax)=3456int 7ch			; 调用中断 7ch 的中断例程,计算ax中的数据的平方; dx:ax 存放结果,将结果乘以2add ax,ax		; 先加低位adc dx,dx		; 再加高位(这里用了进位加法); 23887872mov ax,4c00hint 21h
code ends
end start

中断处理程序

assume cs:code
code segmentstart:	; ====================== 安装 ====================	; ------------------- 复制数据 -------------------mov ax,csmov ds,axmov si,offset sqr	;设置 ds:si 指向源地址mov ax,0mov es,axmov di,200h			;设置 es:di 指向目的地址mov cx,offset sqrend-offset sqr	;设置 cx为传输长度cld					;设置传输方向为正。movsb中si,di递增rep movsb			;重复复制数据次数由 cx 控制; ------------------- 复制数据 -------------------; ----------------- 设置中断向量 -----------------mov ax,0mov es,ax						; 段地址 0mov word ptr es:[7ch*4],200h	; 设置【中断处理程序】的:偏移地址mov word ptr es:[7ch*4+2],0		; 设置【中断处理程序】的:段地址; ----------------- 设置中断向量 -----------------; ====================== 安装 ====================	mov ax, 4c00H		; 退出int 21H; =======================================================	
; --------------------- 中断处理程序 --------------------
; ax 的平方
; -------------------------------------------------------
; 参数:ax			要计算的数据。
; 返回:dx、ax 		中存放结果的高 16 位和低 16 位。
; -------------------------------------------------------sqr:	mul ax			; ax * ax 结果 dx=16位,ax=16位iret 			; 返回原程序。 pop IP, pop CS, popfsqrend:	nop
; --------------------- 中断处理程序 --------------------
; =======================================================
code ends
end start
  • 安装功能跟之前都是一样的,只是改下值就行了。
  • 中断处理程序也很简单就是一个乘法就返回了。

执行效果

在这里插入图片描述

中断例程:将一个全是字母,以0结尾的字符串,转化为大写

问题二编写、安装中断 7ch 的中断例程。
功能将一个全是字母,以0结尾的字符串,转化为大写。
参数ds:si指向字符串的首地址。
应用举例data 段中的字符串转化为大写

主程序

assume cs:code
data segmentdb 'conversation',0
data endscode segmentstart:	mov ax,datamov ds,axmov si,0int 7ch		mov ax,4c00hint 21h
code ends
end start

中断处理程序

assume cs:code
code segmentstart:	; ====================== 安装 ====================	; ------------------- 复制数据 -------------------mov ax,csmov ds,axmov si,offset capital	;设置 ds:si 指向源地址mov ax,0mov es,axmov di,200h				;设置 es:di 指向目的地址mov cx,offset capitalend-offset capital	;设置 cx为传输长度cld					;设置传输方向为正。movsb中si,di递增rep movsb			;重复复制数据次数由 cx 控制; ---------------- 安装(复制数据) ----------------; ----------------- 设置中断向量 -----------------mov ax,0mov es,ax						; 段地址 0mov word ptr es:[7ch*4],200h	; 设置【中断处理程序】的:偏移地址mov word ptr es:[7ch*4+2],0		; 设置【中断处理程序】的:段地址; ----------------- 设置中断向量 -----------------; ====================== 安装 ====================mov ax, 4c00H		; 退出int 21H; =======================================================
; --------------------- 中断处理程序 --------------------
; 将一个全是字母,以0结尾的字符串,转化为大写。
; -------------------------------------------------------
; 参数:ds:si	指向字符串的首地址。
; -------------------------------------------------------capital:	push cx			; 备份寄存器push sichange:	mov cl,[si]		; 取字符mov ch,0		; 高位不参与计算,置 0 jcxz ok			; 如果取到 0 跳到 ok 循环结束and byte ptr [si],11011111b	; 否则:字符转大写inc si			; si++ 指向下一字符jmp short change; 跳到开头继续循环ok:	pop si			; 还原寄存器pop cxiret 			; 返回原程序。 pop IP, pop CS, popfcapitalend:	nop
; --------------------- 中断处理程序 --------------------
; =======================================================
code ends
end start

没什么新知识点,都是之前学过的:安装、遍历字符串、字符转大写。

执行效果

在这里插入图片描述

13.3 对 int、iret 和栈的深入理解

问题用 7ch 中断例程完成 loop 指令的功能 (模拟 loop s
参数bx 存 s 到 se 之间的位移
cx 循环次数
返回
应用举例在屏幕中间显示80个“!”

主程序

assume cs:code
code segmentstart:	mov ax,0b800hmov es,axmov di,160*12				; 从第16向第一个字符开始(正好一行80个字符)mov bx,offset s-offset se	; 参数:se到s的【位移】= -9mov cx,80					; 参数:循环80; ES: 当前偏移量 000Eh = 23 + (-9) = 14s:	mov byte ptr es:[di],'!'	; add di,2int 7ch						; 实现 loop s 效果se:	nop							; 当前偏移量 0017h = 23mov ax,4c00hint 21h
code ends
end start

在这里插入图片描述

  1. sse 共 9 个字节。把它存进 bx,传给中断处理程序,
    在中断处理程序中我们就是利用它来算出 s 偏移量,来实现循环的。
  2. 从上面的截图可以看出 mov byte ptr es:[di],'!' 这一句被反编译成了两句。
    2.1. 先是 ES: 看上去是设置默认数据段的意思 。
    2.2. 因为第二句中 MOV BYIE PIR [DI],21 中没有写段地址,只写了 [DI]

中断处理程序

assume cs:code
code segmentstart:	; ---------------- 安装(复制数据) ----------------mov ax,csmov ds,axmov si,offset lp		;设置 ds:si 指向源地址mov ax,0mov es,axmov di,200h				;设置 es:di 指向目的地址mov cx,offset lpend-offset lp	;设置 cx为传输长度cld					;设置传输方向为正。movsb中si,di递增rep movsb			;重复复制数据次数由 cx 控制; ---------------- 安装(复制数据) ----------------; ----------------- 设置中断向量 -----------------mov ax,0mov es,ax						; 段地址 0mov word ptr es:[7ch*4],200h	; 设置【中断处理程序】的:偏移地址mov word ptr es:[7ch*4+2],0		; 设置【中断处理程序】的:段地址; ----------------- 设置中断向量 -----------------mov ax, 4c00H		; 退出int 21H				; 触发33号中断; =======================================================
; --------------------- 中断处理程序 --------------------
; 模拟 loop s 效果
; -------------------------------------------------------
; 参数:bx		下一句指令到 s 之间的位移
; 参数:cx-1	循环次数
; -------------------------------------------------------lp:	push bp			; 备份寄存器mov bp,sp		; 取栈顶所指的内存位置dec cx			; 计数 cx = cx-1jcxz lpret		; cx 为 0 就跳出循环add [bp+2],bx	; 分析:1lpret:	pop bp			; 还原寄存器iret 			; 分析:2 【重点】lpend:	nop
; --------------------- 中断处理程序 --------------------
; =======================================================
code ends
end start

分析

  • 分析1. 上面我们从 sp 拿到了栈顶内存地址存到 bp
    这里我们就直接修改这段内存中的偏移量了。当前栈中:[bp, ip, cs, flags]
    注意:这时的 bp 是栈顶,跟栈中备份的那个bp值可不是同一个东西了
    所以修改时使用的是 [bp+2] 指向中断前备份的 IP
  • 分析2. iret 是用来返回原程序,继续执行的。它会从栈中恢复中断前保存的寄存器状态,还原了CS:IP 就能实现继续执行中断前的下一条指令了。
pop IP
pop CS
popf

这里是本节的重点了:欺骗善良无知的iret

  1. 在中断触发前,IP 指向了标号 se 处。(在主程序中我已经计算出了ses之间的偏移)
  2. 中断过程中,会备份当前寄存器:pushf, push cs, push ip
  3. 中断处理程序中:我们在 add [bp+2],bx ; 分析:1 这句修改了栈中备份的IP的值。
    所以iret恢复后其实指向了标号 s,这也就实现了跳回去重新执行的效果。

执行效果

在这里插入图片描述

检测点 13.1

《汇编语言》- 读书笔记 - 检测点 13.1

13.4 BIOS 和 DOS 所提供的中断例程

  1. BIOS(基本输入输出系统)存储在系统板ROM中,包含以下内容:
    • 硬件系统检测初始化程序
    • 外部中断内部中断的中断例程
    • 用于对硬件设备进行I/O操作的中断例程
    • 其他与硬件系统相关的中断例程
  2. DOS操作系统同样提供了中断例程,这些例程是操作系统程序员提供的编程接口
  3. BIOS和DOS提供的中断例程包括许多子程序,它们实现了常见的编程功能。
  4. 程序员可以通过int指令直接调用:BIOSDOS中断例程来完成特定任务。
  5. 硬件设备相关DOS中断例程通常会进一步调用BIOS的中断例程以执行底层硬件操作。

13.5 BIOS 和 DOS 中断例程的安装过程

在8086架构的早期个人计算机系统中,BIOS和DOS中断例程的安装过程并非由用户程序直接执行安装,而是内置于系统的初始化过程中。以下是一个简化的概述:

BIOS中断例程的安装:

  1. 开机后,CPU 一加电,自动从FFFF:0000H地址处开始执行ROM中的代码(即BIOS)。
    (这个位置存放着一条跳转指令,它会跳转到ROM中的实际BIOS启动代码区域。)
  2. BIOS首先进行硬件自检(POST, Power-On Self-Test),检测和初始化硬件设备。
  3. BIOS建立中断向量表,将自身的中断处理程序入口地址填入到中断向量表对应的内存位置。
    (只需要有登记入口地址,因为中断处理程序本身已固化在BIOS的ROM中。)

DOS中断例程的安装:

  1. 硬件自检和初始化完成后,调用 int 19h 进行操作系统的引导。
    1.1. 在BIOSint 19h 中断做出响应时,它首先从硬盘的第一个扇区(即主引导记录MBR)读取512字节的数据到内存特定位置(如0x7C00)。
    1.2. MBR中的前446字节通常是机器码构成的操作系统引导程序(Boot Loader),该引导程序接着会被CPU执行。
    1.3. 引导程序的任务是找到并加载实际的操作系统,例如MS-DOS或更现代的操作系统的核心文件,并将控制权转交给操作系统。
  2. 当DOS启动时,它会接管控制权,并且根据需要重定向某些中断向量,以便调用自己的中断例程来处理特定的服务请求。
  3. DOS通常会保留一部分中断向量用于调用原始的BIOS服务,同时提供额外的中断服务例程以支持文件操作、磁盘读写等功能。

总之,在8086环境下,BIOS和DOS中断例程的安装是指在系统启动阶段由固件操作系统自动完成中断向量表的填充和设置,而不是程序员手动安装的过程。

《汇编语言》- 读书笔记 - 检测点 13.2.

13.6 BIOS 中断例程应用

功能 02H 设置光标位置

INT 10H显示服务 Video Service
功能02H设置光标位置
参数AH=调用 02H 号子程序
BH=显示页码
DH=行(Y坐标)
DL=列(X坐标)
返回
assume cs:code
code segmentstart:	mov ah,2	; 设置光标位置mov bh,0	; 显示页码,第0页mov dh,5	; dh 中放行号mov dl,12	; dl 中放列号int 10hok:	mov ax,4c00hint 21h
code ends
end start

在这里插入图片描述

功能 09H 在光标位置显示字符

INT 10H显示服务 Video Service
功能09H在当前光标处按指定属性显示字符
参数AH=功能号 09H
AL=字符内容
BH=显示页码
BL=颜色属性
CX=字符重复个数
返回
assume cs:code
code segmentstart:	mov ah,2			; 设置光标位置mov bh,0			; 显示页码,第0页mov dh,5			; dh 中放行号mov dl,12			; dl 中放列号int 10hmov ah,9			; 在光标位置显示字符mov al,'a'			; 字符内容mov bl,11001010b	; 颜色属性mov bh,0			; 显示页码mov cx,20			; 字符重复个数int 10hok:	mov ax,4c00hint 21h
code ends
end start

在这里插入图片描述

13.7 DOS 中断例程应用(INT 21H)

在8086架构下,int 21hDOS操作系统为应用程序提供的一种系统API
通过调用int 21h并设置不同的AH寄存器值,程序员可以请求执行多种操作,如:文件操作、设备I/O、内存管理等。
这些中断服务例程相当于DOS系统的函数库,使得应用程序能够与操作系统进行交互和访问底层资源。

功能 4CH:返回码方式的终止进程

INT 21HDOS 中断例程
功能 4CH终止程序的执行,并可返回一个代码
参数AH=功能号 4CH
AL=返回值
返回
mov ah,4ch		; 调用 4ch 号功能
mov al,00h		; 返回值
int 21h

功能 09H:输出一个字符串到标准输出设备上

INT 21HDOS 中断例程
功能09H输出一个字符串到标准输出设备上。待显示的字符串以$作为其结束标志
参数AH=功能号09H
DS:DX=待输出字符的地址
返回
assume cs:code
data segmentdb 'Welcome to masm','$'
data endscode segmentstart:	mov ah,2			; 设置光标位置mov bh,0			;0页显示mov dh,5			; dh 中放行号mov dl,12			; dl 中放列号int 10hmov ax,datamov ds,axmov dx,0			;ds:dx指向字符串的首地址 data:0mov ah,9int 21hok:	mov ax,4c00hint 21h
code ends
end start

在这里插入图片描述

实验 13 编写、应用中断例程

《汇编语言》- 读书笔记 - 第13章-实验13编写、应用中断例程

参考资料

DOS 中断参考手册


http://www.mrgr.cn/p/03886866

相关文章

【C++】C++的四种强制类型转换

1、C语言中的类型转换 在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型转换…

mysql,for循环执行sql

遇到一个问题,我需要模拟上百万数据来优化sql,线上数据down不下来,测试库又没有,写代码执行要么慢要么就是sql语句太长。 于是,直接用mysql自带的功能去实现! 简单而简单 mysql可以for循环?没…

Docker技术概论(4):Docker CLI 基本用法解析

Docker技术概论(4) Docker CLI 基本用法解析 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:http…

Spring AI上架

Spring AI 来了 Spring AI 是 AI 工程师的一个应用框架,它提供了一个友好的 API 和开发 AI 应用的抽象,旨在简化 AI 应用的开发工序。 提供对常见模型的接入能力,目前已经上架 https://start.spring.io/,提供大家测试访问。(请注意虽然已经上架 start.spring.io,但目前还…

文件基础和文件fd

文章目录 预备知识C语言的文件接口系统调用文件fd 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通俗易懂,风趣幽默,忍不住分享一下给大家。 点击跳转到网站。 预备知识 我们平时说文件就是说文件里…

cyi青少年CTF擂台挑战赛 2024 #Round 1 wp

cyi青少年CTF擂台挑战赛 2024 #Round 1 wpWEB EasyMD5 靶机真不敢恭维 一个文件上传界面,得上传pdf传两个pdfhttps://www.cnblogs.com/wysngblogs/p/15905398.html 这篇文章看到md5碰撞,找到个工具fastcoll_v1.0.0.5 https://www.win.tue.nl/hashclash/后续写的wp,flag可能…

Gitlab Runner自动推送Docker映像

接上文,增加两个stage 最简单的推送,其实是在docker build后边带上--push的开关即可。 但是不经过测试就上传,Docker仓库里很快会堆满垃圾。 所以我们设计新增两个场景,经过测试之后才push映像去仓库。 stages:- build-docker-image- test- push-image variables:PAY_IMAGE…

黑马JavaWeb课程中安装vue脚手架出现的问题

1 安装node.js 要想前端工程化,必须安装node.js,前端工程化的环境。 在成功安装node.js后, 修改全局包安装路径为Node.js安装目录, 修改npm镜像源为淘宝镜像源,这里出现第一个问题,视频中给的淘宝镜像为&…

python实现常见一元随机变量的概率分布

一. 随机变量 随机变量是一个从样本空间 Ω \Omega Ω到实数空间 R R R的函数,比如随机变量 X X X可以表示投骰子的点数。随机变量一般可以分为两类: 离散型随机变量:随机变量的取值为有限个。连续型随机变量:随机变量的取值是连…

关于Windows 10的兼容模式,看这篇文章就够了

这篇文章解释了如何使用Windows兼容模式在Windows 10上完美地运行旧版本的Windows程序。 如何更改Windows 10兼容模式设置 如果疑难解答没有完成任务,并且你知道该程序以前使用过哪个版本的Windows,则可以手动更改Windows 10兼容模式的设置&#xff1a…

Spring-自动配置

自动配置流程细节梳理: 1、导入starter-web:导入了web开发场景1、场景启动器导入了相关场景的所有依赖:starter-json、starter-tomcat、springmvc 2、每个场景启动器都引入了一个spring-boot-starter,核心场景启动器。(上面三个也有) 3、核心场景启动器引入了spring-boot-a…

[回归指标]R2、PCC(Pearson’s r )

R2相关系数 R2相关系数很熟悉了,就不具体解释了。 皮尔逊相关系数(PCC) 皮尔逊相关系数是研究变量之间线性相关程度的量,R方和PCC是不同的指标。R方衡量x和y的接近程度,PCC衡量的是x和y的变化趋势是否相同。R方是不…

《TCP/IP详解 卷一》第9章 广播和组播

目录 9.1 引言 9.2 广播 9.2.1 使用广播地址 9.2.2 发送广播数据报 9.3 组播 9.3.1 将组播IP地址转换为组播MAC地址 9.3.2 例子 9.3.3 发送组播数据报 9.3.4 接收组播数据报 9.3.5 主机地址过滤 9.4 IGMP协议和MLD协议 9.4.1 组成员的IGMP和MLD处理 9.4.2 组播路由…

Gitlab Runner自动制作C#网站项目的Docker映像

概述 代码签入Gitlab后,Gitlab Runner自动执行docker build,构建网站应用的Docker映像。 在Visual Studio 2022中创建解决方案在Gitlab中创建项目 这一步省略。 签入源代码到Gitlab为项目添加Dockerfile在解决方案根目录下创建“.gitlab-ci.yml” stages:- build-docker-imag…

Docker容器(3)单容器管理

一、单容器 1.1概念简介 Docker三个重要概念: 仓库(Repository); 镜像(Image); 容器(Container). *Docker的三个重要概念是仓库(Repository)、镜像(Image)和容器(Container)**。具体如下: **镜像(Image)**:Docker镜像是创建容器的基础,它类似…

LabVIEW非接触式电阻抗层析成像系统

LabVIEW非接触式电阻抗层析成像系统 非接触式电阻抗层析成像(NEIT)技术以其无辐射、非接触、响应速度快的特点,为实时监测提供了新的解决方案。基于LabVIEW的电阻抗层析成像系统,实现了数据的在线采集及实时成像,提高…

工作感受月记(2024年03月)

2024年03月01日 周五下午班,自己手中事情多了起来了。 今日工作事项: 1/ 一个aks 中应用连接redis案例,为什么会出现间歇性的连接到redis的public ip地址呢? 2/ key vault案例,客户从aws上连接azure服务。应该是她们内网环境没有打通引起的。 3/ 自己另外做了什么事情呢? …

FRM模型十二:极值理论

目录 极值理论介绍GEVPOT 代码实现 极值理论介绍 在风险管理中,将事件分为高频高损、高频低损、低频高损、低频低损。其中低频高损是一种非常棘手的损失事件,常出现在市场大跌、金融体系崩溃、金融危机以及自然灾害等事件中。 由于很难给极端事件一个准…

《哈利波特》1-7册全集高清PDF

《哈利波特》简介 《哈利波特》这个系列的图书自1997年在英国问世以来,迄今在全世界已发行超过四亿多册,创造了出版史上的奇迹,全套共7册,分别是:《Harry Potter and the Philosopher’s Stone 哈利波特与魔法石》、《Harry Potter and the Chamber of Secrets 哈利波特与…

【Vue3】自定义 Vue3 插件(全局实现页面加载动画)

// main.ts import { createApp } from vue import App from ./App.vue import Loading from "./components/Loading/index.ts";const app createApp(App) type Lod {show: () > void,hide: () > void } //编写ts loading 声明文件放置报错 和 智能提示 decl…