int指令
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;} th{border: 1px solid gray; padding: 4px; background-color: #DDD;} td{border: 1px solid gray; padding: 4px;} tr:nth-child(2n){background-color: #f8f8f8;}
1、取中断类型码 n; 2、标志寄存器入栈,IF=0,TF=0; 3、CS、IP 入栈; 4、(IP)=(n*4),(CS)=(n*4+2) |
assume cs:code
code segment
start: mov ax , 0b800h
mov es , ax
mov bx , 72ch
mov byte ptr es:[bx] , '!' ; 输出显示区第12行显示一个字符 !
mov byte ptr es:[bx+1] , 2
int 0 ; 调用 0 号中断
code ends
end start
程序执行到 int 0 就去调用0号中断,0号中断的中断服务程序在前面被改写了 |
编写供应用程序调用的中断例程
编写、安装中断 7ch 的中断例程,功能:求一 word 型数据的平方 1、编写实现求平方功能的程序;
2、安装程序,我们将其安装在 0:200 处;
3、设置中断向量表,将程序的入口地址保存在 7ch 表项中,使其成为中断 7ch 的中断例程;
|
编写、安装中断 7ch 的中断例程,功能:将一个全是字母,以 0 结尾的字符串,转化为大写
|
assume cs:code
code segment
start: mov ax , cs
mov ds , ax
mov si , offset sqr
mov ax , 0
mov es , ax
mov di , 200h
mov cx , offset sqrend - offset sqr
cld
rep movsb
mov ax , 0
mov es , ax
mov word ptr es:[7ch*4] , 200h
mov word ptr es:[7ch*4+2] , 0
mov ax , 4c00h
int 21h
sqr: mul ax
iret ; 相当于 pop IP pop CS popf
sqrend: nop
code ends
end start
|
assume cs:code
code segment
start: mov ax , cs
mov ds , ax
mov si , offset capital
mov ax , 0
mov es , ax
mov di , 200h
mov cx , offset capitalend - offset capital
cld
rep movsb
mov ax , 0
mov es , ax
mov word ptr es:[7ch*4] , 200h
mov word ptr es:[7ch*4+2] , 0
int 7ch
mov ax , 4c00h ; 如果中断程序中有这段程序这里就可以不加,如果中断程序中是iret,这里就要加上;
int 21h ; 不然无法返回dos输入命令,这里和中断程序都加上这段也可以
capital: jmp short change
db 'conversation' , 0
change: mov ax , cs
mov ds , ax
mov si , 202h
mov ax , 0b800h
mov es , ax
mov di , 7c6h ; 具体在显示缓冲区的显示位置偏移
s: mov cl , [si]
mov ch , 0
jcxz return
and byte ptr [si] , 11011111b
mov cl , [si]
mov es:[di] , cl
mov byte ptr es:[di+1] , 2
inc si
add di , 2
jmp short s
return: iret ; 这里要写上中断返回或者 mov ax , 4c00h int 21h 返回dos,不然执行后程序无法输入,因为执行完中断CS:IP接着向下去执行了;
capitalend: nop
code ends
end start
|
这段程序重新安装7ch处的中断程序,在以后执行7ch中断的时候执行这段程序
assume cs:code
code segment
start: mov ax , cs
mov ds , ax
mov si , offset capital
mov ax , 0
mov es , ax
mov di , 200h
mov cx , offset capitalend - offset capital
cld
rep movsb
mov ax , 0
mov es , ax
mov word ptr es:[7ch*4] , 200h
mov word ptr es:[7ch*4+2] , 0
mov ax , 4c00h
int 21h
capital: push ds ; 中断用到的寄存器,要先进栈保存,保持中断后的一致性
push si
change:mov cl , [si]
mov ch , 0
jcxz ok
and byte ptr [si] , 11011111b
inc si
jmp short change
ok: pop si
pop ds
iret
capitalend: nop
code ends
end start
|
测试代码
assume cs:code
data segment
db 'conversation' , 0
data ends
code segment
start: mov ax , data
mov ds , ax
mov si , 0
int 7ch ; 执行这个中断,会把数据段的字符串改成大写
mov ax , 4c00h
int 21h
code ends
end start
|
重写 7ch 中断,实现 loop 跳转 | 测试代码 |
assume cs:code
code segment
start: mov ax , cs
mov ds , ax
mov si , offset lp
mov ax , 0
mov es , ax
mov di , 200h
mov cx , offset lpend - offset lp
cld
rep movsb
mov ax , 0
mov es , ax
mov word ptr es:[7ch*4] , 200h
mov word ptr es:[7ch*4+2] , 0
mov ax , 4c00h
int 21h
lp: push bp ; 下面要用到bp,所以这里先保存进入中断前的bp
mov bp , sp
; 不能直接对sp修改,会导致程序崩溃,所以要访问栈中数据只能用这种方式
dec cx
jcxz lpret
add [bp+2] , bx ; bp的值是sp的,所以[bp+2]得到的是ss:sp+2,也就是中断压栈的ip的值,为int 7ch下一条指令(nop)的位移,+bx ->IP偏移到标号 s ;
; 如果寄存器相对寻址 寄存器是bp的话,段寄存器就是ss
lpret: pop bp ; 恢复bp
iret ; 中断返回,恢复CS:IP
lpend: nop
code ends
end start
|
assume cs:code
code segment
start: mov ax , 0b800h
mov es , ax
mov di , 160*12
mov bx , offset s - offset se ; 这个负偏移中断要用到来修改ip的值指向标号s:
mov cx , 80
s: mov byte ptr es:[di] , '!' ; 循环打印 !
mov byte ptr es:[di+1] , 2 ; 设置颜色为绿色
add di , 2
int 7ch ; 设置7ch中断例程序,实现 loop s 功能
se: nop
mov ax , 4c00h
int 21h
code ends
end start
为了模拟loop,中断就要能 dec cx , 如果(cx)≠0,转到标号s处执行,否则向下执行。这里的bx就是来记录这个负位移,中断靠这个实现向上转移; 发生中断的时候,最后进栈的是CS、IP,这个CS就是标号s的段地址,IP就是中断下一条指令的偏移;可以在中断例程中修改这个值实现 loop s 的功能。
中断程序中,用bp来保存栈顶sp,进栈后+2就得到中断最后进栈的IP,与bx相加就是s的偏移
|
BIOS 和 DOS 中断例程的安装过程
BIOS 和 DOS 提供的中断例程在装到内存中的过程: 1、开始后,CPU 一加电,初始化(CS)=0FFFFh,(IP)=0,自动从 FFFF:0 单元开始执行程序。FFFF:0 处有一条跳转指令,CPU执行该指令后,转去执行 BIOS 中的硬件系统检测和初始化程序。 2、初始化程序将建立 BIOS 所支持的中断向量,即将 BIOS 提供的中断例程的入口地址登记在中断向量表中。对于 BIOS 所提供的中断例程,只需将入口地址登记在中断向量表中即可,因为它们是固化到 ROM 中的程序,一直在内存中存在。 3、硬件系统检测和初始化完成后,调用 int 19h 进行操作系统的引导。从此将计算机交由操作系统控制。 4、DOS 启动后,除完成其他工作外,还将它所提供的中断例程装入内存,并建立相应的中断向量。 |
Shadow RAM也称为“影子”内存。它是为了提高系统效率而采用的一种专门技术。 Shadow RAM所使用的物理芯片仍然是CMOS DRAM(动态随机存取存储器)芯片。Shadow RAM 占据了系统主存的一部分地址空间。其编址范围为C0000~FFFFF,即为1MB主存中的 768KB~1024KB区域。这个区域通常也称为内存保留区,用户程序不能直接访问。 Shadow RAM的功能是用来存放各种ROM BIOS的内容。或者说Shadow RAM中的内容是ROM BIOS的拷贝。因此也把它称为ROM Shadow(即Shadow RAM的内容是ROM BIOS的“影 子”)。 在机器上电时,将自动地把系统BIOS、显示BIOS及其它适配器的BIOS装载到Shadow RAM 的指定区域中。由于Shadow RAM的物理编址与对应的ROM相同,所以当需要访问BIOS时, 只需访问Shadow RAM即可,而不必再访问ROM。 通常访问ROM的时间在200ns左右,而访问DRAM的时间小于100ns(最新的DRAM芯片访问时 间为60ns左右或者更小)。 |
// int 10h 中断例程的设置光标位置功能。 mov ah , 2 ; 置光标 mov bh , 0 ; 第0页 mov dh , 5 ; dh 中放行号 mov dl , 12 ; dl 中放列号 int 10h 10h 号中断的2号设置光标位置功能不会自动偏移光标,所以必须每次dl+1 |
// int 10h 中断例程的光标位置显示字符功能 mov ah , 9 ; 光标位置开始显示字符 mov al , 'a' ; 字符 mov bh , 0 ; 第0页 mov bl , 7 ; 颜色属性 mov cx , 3 ;字符重复个数 int 10h |
(ah)=2表示调用第10h号中断例程的2号子程序,功能为设置光标位置,可以提供光标所在行号(80*25字符模式下:0~24)、列号(80*25字符模式下:0~79),和页号作为参数。 (bh)=0,(dh)=5,(dl)=12,设置光标到第0页,第5行,第12列 bh中的页号的含义:内存地址空间中,B8000h~BFFFFh 共32K的空间,为80*25彩色字符模式的显示缓冲区。一屏的内容在显示缓冲区中共占 4000 个字节。 显示缓冲区为8页,每页4K,显示器可以显示任意一页的内容,显示第0页的内容就是显示B8000~B8F9F中的4000个字节的内容将出现在显示器 |
(ah)=9 表示调用第 10h 号中断例程的9号子程序,功能为在光标位置显示字符,可以提供要显示的字符、颜色属性、页号、字符重复个数作为参数。 |
;编程:在屏幕的第12行40列显示3个红底高亮闪烁绿色的'a' assume cs:code
code segment
mov ah , 2
mov bh , 0
mov dh , 12
mov dl , 40
int 10h
mov ah , 9
mov al , 'a'
mov bh , 0
mov bl , 11001010b
mov cx , 3
int 10h
mov ax , 4c00h
int 21h
code ends
end
|
效果是aaa一直在闪烁,事先设置好光标,中断执行完后光标转到下一行,link的l那,可以写东西覆盖 |
int 21h 中断例程的 4ch 号功能是程序返回功能 mov ah , 4ch ; 程序返回 mov al , 0 ; 返回值 int 21h (ah)=4ch 表示调用第 21h 号中断例程的 4ch 号子程序,功能为程序返回,可以提供返回值作为参数。 int 21h 中断例程有在光标位置显示字符串的功能: | 在屏幕中间显示字符串 "Welcome to masm!" assume cs:code
data segment
db 'Welcome to masm!' , '$' ; 汇编中字符串还是单个字符用"或者'围起来都一样
; db "Welcome to masm!" , '$'
data ends
code segment
start: mov ah , 2 ; 设置光标位置
mov bh , 0
mov dh , 12
mov dl , 32
int 10h
mov ax , data
mov ds , ax
mov dx , 0 ; 设置待显示字符串位置,这个中断中要用dx来存放偏移
mov ah , 9 ; 功能号9显示字符串
; mov bl , 11001010b ;21h中不能设置颜色了都
int 21h
mov ax , 4c00h ; 调用4ch号功能,返回值0
int 21h
code ends
end start
如果要显示的字符串较长,它会自动转到下一行开头处继续显示,如果到达显示也最后一行,它还能自动上卷一行。 |
int指令的更多相关文章
- 汇编学习笔记(11)int指令和端口
格式 int指令也是一种内中断指令,int指令的格式为int n,n是中断类型码.也就是说,使用int指令可以调用任意的中断例程,例如我们可以显示的调用0号中断例程,还记得在汇编学习笔记(10)中我们 ...
- [汇编学习笔记][第十三章int指令]
第十三章int指令 13.1 int指令 格式: int n, n 为中断类型码 可以用int指令调用任何一个中断的中断处理程序(简称中断例程). 13.4 BIOS和DOS 所提供的中断例程 BIO ...
- int指令(软件中断指令)
INT(软件中断指令)是CALL指令的一种特殊形式.call指令调用调用的子程序是用户程序的一部分,而INT指令调用的操作系统提供的子程序或者其他特殊的子程序. 中断服务子程序和标准过程的最大区别是 ...
- 汇编入门学习笔记 (十二)—— int指令、port
疯狂的暑假学习之 汇编入门学习笔记 (十二)-- int指令.port 參考: <汇编语言> 王爽 第13.14章 一.int指令 1. int指令引发的中断 int n指令,相当于引 ...
- 关于int指令
1.关于int指令 格式:int n n为中断类型码: 作用: 调用n号中断程序: 指令“int n”的执行过程: 1]获取中断类型码n 2]标志寄存器入栈,IF. ...
- int指令理解
以下是王爽老师的<汇编语言>中第十五章中的一段程序代码,其功能是增加9号中断的功能,当按下Esc键时屏幕中显示的字母改变颜色 assume cs:codesg,ss:stack,ds:da ...
- int 指令
int n 也就是中断操作->根据中断类型码来查找中断向量表(中断向量表在0-3ffh这个内存空间) 调用int n 也就操作了下面的步骤 1)取中断类型码n: 2)标志寄存器入栈,IF=0,T ...
- 学习linux内核时常碰到的汇编指令(1)
转载:http://blog.sina.com.cn/s/blog_4be6adec01007xvg.html 80X86 汇编指令符号大全 +.-.*./∶算术运算符. &∶宏处理操作符. ...
- 汇编-13.0-int指令
1.int指令 int指令的格式为:int n,n为中断类型码,它的功能是引发中断过程. 执行int n指令,相当于引发一个中断号为n的中断过程. (1).取中断类型码n: (2).标志寄存器入栈,I ...
随机推荐
- class java.awt.HeadlessException : No X11 DISPLAY variable was set, but this program performed an operation which requires it.
今天上午打印回单功能发布到测试环境,报了: class java.awt.HeadlessException : No X11 DISPLAY variable was set, but this p ...
- Java实现贪吃蛇游戏【代码】
花了两个下午写了一个贪吃蛇小游戏,本人想写这游戏很长时间了.作为以前诺基亚手机上的经典游戏,贪吃蛇和俄罗斯方块一样,都曾经在我们的童年给我们带来了很多乐趣.世间万物斗转星移,诺基亚曾经作为手机业的龙头 ...
- Windows上最大传输单元MTU值的查看和设置
最近使用ssh工具在VPN环境下连接一个生产环境的Linux主机的时候,发现经常出现输入命令后卡死的情况.最开始以为是Linux主机的问题,问了一些老同事之后发现原来是我自己电脑的最大传输单元MTU和 ...
- 第七章:Python基础のXML操作和面向对象(一)
本課主題 XML介绍与操作实战 shutil 模块介绍与操作实战 subprocess 模块介绍与操作实战 初探面向对象与操作实战 本周作业 XML介绍和操作实战 對於浏览器返回的字符串有以下幾種: ...
- ArcGis连接oracle失败:ORA-6413:连接未打开
问题: 通过ARCMap 添加Oracle数据库连接时提示,ORA-6413:连接未打开. 运行环境: ArcGis 10.2 Oracle 10g 解决方法: 通过上网查找解决方法,网友说" ...
- PE文件详解(七)
本文转载自小甲鱼PE文件讲解系列原文传送门 这次主要说明导出表,导出表一般记录着文件中函数的地址等相关信息,供其他程序调用,常见的.exe文件中一般不存在导出表,导出表更多的是存在于dll文件中.一般 ...
- equals和hashcode重写的问题
public static void main(String[] args) { Set<Test> set = new HashSet<>(); Test t1 = new ...
- poj1830:开关问题
链接:http://poj.org/problem?id=1830 某天“佐理慧学姐”突然来问了我这道题. 诶,窝只会线性基,但是好像搞不了方案数啊…… 啃题解吧. woc!线性代数哦,就是那种我不会 ...
- 记忆化搜索 dp学习~2
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1331 Function Run Fun Time Limit: 2000/1000 MS (Java/ ...
- Codeforces__Raising Bacteria
题目传送门:Raising Bacteria //问题描述:一个盒子里面放一个细菌在一天可以增生两个细菌. 现在已知盒子里面细菌的个数,问你最初放多少个细菌可以增生盒子里面的细菌数量 //输入:盒子中 ...