汇编语言的中断服务的中断服务程序是什么?
发布网友
发布时间:2022-04-30 10:11
我来回答
共5个回答
热心网友
时间:2022-06-20 23:32
嗯,我猜你问的是PC的,不是单片机
一、汇编语言的中断分以下几种:
1.BIOS中断,这是固化到BIOS程序中的,每次开机BIOS会自动加载到指定内存
2.186下的DOS中断,在DOS系统被加载后,系统会延用BIOS的中断向量,并向里面添加一些新的向量,这些功能便是DOS系统自带的中断服务程序
3.286及以上的系统中断,PC会进入保护模式,在OS被加载后,中断由IDT控制,这一机制类似于中断向量表,只不过中断向量换成了选择子。这样的中断机制对不同型号的CPU有略微的差别,这里不细说了,我自己也没全弄明白。
二、中断实现的方式(8086下的普通中断)
听说过“优先级编码器”没?——如果同时有两个信号被接收,会指定某一个信号的优先级高,先执行它。中断就是类似的处理方法。
当CPU获取到某一高操作优先级的信号时(比如时钟,每固定时间就会触发一次;比如键盘响应,用户希望通过Ctrl+C来退出任何正在执行的DOS程序),CPU会将当前正在执行的程序挂起来,转而去处理该信号(类似于Call,但略有不同,你看的书应该会讲到)。
处理中断时,系统会将其解释为一个标号,比如int 9h、int 21h等等。这个标号是一个序号,在内存某处存放着连续的一个表格,这个标号便是表格中的“行号”,只不过,每一行是两列,包括了该中断的处理程序的段基址和偏移量。中断向量表是从0000:0000开始的,每4字节为一个表项。中断标号x4就是对应的中断向量表项所存的地址,高地址是基地址,低地址是偏移。
这么说不知道你懂不懂。。。
反正总结一下你的问题吧,中断服务程序是加载到内存中的,它在加载前可能是存在BIOS芯片上,也可能是存在硬盘里的;中断向量表里只能写上中断处理程序的入口地址,要知道每个表项只有4字节;具体的中断服务程序,我不信你学汇编的书上不讲,我大概讲一下:CPU的INTR引脚获得了中断信号,得到了标号,比方说是5号,中断向量表项为0000:000A,读取这个内存,得到中断程序入口地址比方说是AAAA:BBBB,那么它会将当前的CS/IP、Flags寄存器入栈,然后转到AAAA:BBBB处去执行一直到iret指令返回原任务(或许该中断结束了这个任务,就不会返回了)。
至于保护模式的中断,相信你暂时还没遇到。到后面还有操控8259A芯片来实现高级中断的,这个就不是一般需要学的了。
热心网友
时间:2022-06-20 23:33
中断服务程序是写在单片机的内存中的,而内存中的中断向量表就是指中断服务程序的入口地址,一旦有中断源产生中断了,那么程序就会根据中断向量表跳到相应的中断服务程序执行,中断执行完成后再返回到进入中断前的程序处继续执行。
中断服务程序:处理器处理“急件”,可理解为是一种服务,是通过执行事先编好的某个特定的程序来完成的,这种处理“急件”的程序被称为——中断服务程序。
当*处理器正在处理内部数据时,外界发生了紧急情况,要求CPU暂停当前的工作转去处理这个紧急事件。处理完毕后,再回到原来被中断的地址,继续原来的工作,这样的过程称为中断。实现这一功能的部件称为中断系统,申请CPU中断的请求源称为中断源,单片机的中断系统一般允许多个中断源,当多个中断源同时向CPU请求中断时,就存在一个中断优先权的问题。通常根据中断源的优先级别,优先处理最紧急事件的中断请求源,即最先响应级别最高的中断请求。追问我对单片机还不了解,是不是像显卡芯片,bios芯片之类的都属于单片机?
热心网友
时间:2022-06-20 23:33
这有一篇,我在十年前写的,原发表在电脑报上。楼主最好按着做一下,什么都明白了。
BIOS中断浅析
首先,我们介绍一下中断。中断大致可以分为四种类型:
中断类型 中断号 处理器 0--4h
硬件 8--F,70--77h
软件大部分为int形式,例外:
1)1Dh,1Eh,46h返回在ROM中驻留的硬件参数表格
2)20--3Fh用于DOS
3)5,10--1A,1D--1F,40,41,43,46h用于BIOS
用户 60--67,F1--FF
上表仅是一个粗略的说明,随着中断的发展,一些原先保留的中断也有了确定的定义。现在所讲的BIOS中断意指中断0--1Fh。
中断程序的执行过程简单说来,即中断程序在中断向量表中查到中断地址后,保存现场,跳到中断地址执行程序,结束后再恢复现场继续执行中断前的程序。我们调用中断就与调用一个c程序一样方便。
BIOS固化于ROM中,是其他软件与硬件传递信息的桥梁。以应用的角度看,它的各个中断程序是我们最感兴趣的。早在DOS时代,就有不少关于BIOS的介绍,那么到了Windows纵横天下的时候,BIOS又有了什么变化和发展呢?下面我们将BIOS中断程序按编程的复杂度由简单到复杂度选择进行分析。
。
(一)准备工作
一)开机后,BIOS中断程序驻留于内存F0000--FFFFF处,我们可先用DEBUG.EXE 将这内存的内容复制成一个文件。例如:
C:/>debug.exe
-rbx
BX 0000
:1
-n bios.dat
-w f000:0
Writing 10000 bytes
-q
然后,我们再将内存0:0 --0:700处的内容复制下来。此处主要有中断向量表,所用到的BIOS数据区和DOS数据区。为了方便查看,以文本形式保存。例如:先编写一个批处理文件C.bat,其内容为:
@echo d 0:0 700 >temp
@echo q>>temp
type temp|debug.exe >bios.txt
将C.bat执行后,得到一个bios.txt文件。
二)熟悉DEBUG.EXE和PCTOOLS5.0 的用法。它们都是很老的软件了,但对付BIOS 还是绰绰有余的(当然还有例外,下文将要讲到)。
三)准备一本汇编方面的书籍。上面一般附有BIOS 中断。虽然不太全,但可以作为参考。如清华大学计算机系教材《IBM-PC汇编语言程序设计》。
四)那就是你必须具有相当熟练的汇编语言的知识,以及对硬件要有一定的了解,如对8259A,8042 等计算机用到的硬件的端口要有比较清楚的认识,最少也得有一本这方面的参考书,如我们就参考过《PC系列机系统开发与应用》,《微型计算机原理与汇编语言》等十几本书籍。
(二)纵览全局
查看bios.txt ,地址0:0-0:700为中断0-1FH入口地址,如下图:
0000:0000 9E 0F C9 00 65 04 70 00-16 00 A4 08 65 04 70 00 ....e.p.....e.p.
0000:0010 65 04 70 00 54 FF 00 F0-E2 47 00 F0 C8 E6 00 F0 e.p.T....G......
0000:0020 00 00 00 CC 28 00 A4 08-6F EF 00 F0 6F EF 00 F0 ....(...o...o...
0000:0030 6F EF 00 F0 6F EF 00 F0-9A 00 A4 08 65 04 70 00 o...o.......e.p.
0000:0040 05 00 75 CC 4D F8 00 F0-41 F8 00 F0 E7 25 53 FD ..u.M...A....%S.
0000:0050 39 E7 00 F0 40 02 13 02-2D 04 70 00 28 0A 5C 02 9...@...-.p.(.\.
0000:0060 A4 E7 00 F0 2F 00 65 09-6E FE 00 F0 04 06 5C 02 ..../.e.n.....\.
0000:0070 1D 00 00 CC A4 F0 00 F0-22 05 00 00 19 4E 00 C0 ........"....N..
但其中有些地址已经被DOS 修改了。我们可打开bios.dat 查看原来的地址,用PCTOOLS 打开bios.dat,按F2 ,键入127 ,在相对扇区 127 处,偏移E3-122 的地方查到原来的地址。我们以大众MVP3主板(VP3-586B-WB77)上的 AWARD BIOS(日期:98年7月20日)(注:以下都将以此BIOS为例)为例看一看,如下图:
F000:FEE0 00 0F AA C8 E6 C8 E6 C3-E2 C8 E6 C8 E6 54 FF E2 .............T..
F000:FEF0 47 C8 E6 A5 FE 87 E9 6F-EF 6F EF 6F EF 6F EF 57 G......o.o.o.o.W
F000:FF00 EF 6F EF 65 F0 4D F8 41-F8 59 EC 39 E7 59 F8 2E .o.e.M.A.Y.9.Y..
F000:FF10 E8 D2 EF A4 E7 F2 E6 6E-FE 53 FF 53 FF A4 F0 C7 .......n.S.S....
F000:FF20 EF 00 00 5E BB F3 EC 6F-EF 6F EF 6F EF FC F0 6F ...^...o.o.o...o
可以看到,确实与0:700处的地址有差别。在127 扇区的结尾处,可看到BIOS 的日期及机子型号,如:
F000:FFF0 CD 19 E0 00 F0 30 37 2F-32 30 2F 39 38 00 FC AA .....07/20/98...
如果你用PCTOOLS 查看各扇区,还可发现一些在CMOS SETUP设置时遇到的提示信息,如:
F000:0660 00 07 02 16 0B 39 0F 02-05 19 0D 53 41 56 45 20 .....9.....SAVE
F000:0670 74 6F 20 43 4D 4F 53 20-61 6E 64 20 45 58 49 54 to CMOS and EXIT
F000:0680 20 28 59 2F 4E 29 3F 20-00 07 02 16 0B 39 0F 02 (Y/N)? .....9..
F000:0690 05 1A 0D 51 75 69 74 20-57 69 74 68 6F 75 74 20 ...Quit Without
F000:06A0 53 61 76 69 6E 67 20 28-59 2F 4E 29 3F 20 00 07 Saving (Y/N)? ..
(三)最简单的中断程序
为了提高自信心,我们先来看一看最简单的中断程序是怎样的。
INT 1B,1CH为提供给用户的软中断,即用户如果不对它们进行修改,则它们是仅有一条IRET指令的程序。
INT 12H功能为检查基本内存容量。程序为
PUSH DS
MOV AX,40
MOV DS,AX
MOV AX,[13]
POP DS
IRET
查看地址0:413H的内容,为280H,即十进制的640K,这说明基本内存为640K。
INT 0,1,3,4,7H 程序为:
E6C8:PUSH DS
PUSH AX
PUAH CX
MOV AX,40
MOV DS,AX
JMP EFBD
EFBD:MOV AH,FF
MOV [6B],AH
POP CX
POP AX
POP DS
IRET
程序仅仅在地址0:46B处填入FF字节。我们知道,单步与断点两中断由DEBUG.EXE接管和修改的,而其他则由DOS接管。故现在查看一下0:46B,已经不是FF了。
INT 11H的程序为:
JMP EE81
EE81:PUSH DS
MOV AX,40
MOV DS,AX
XOR EAX,EAX
MOV AX,[10]
POP DS
IRET
其中地址0:410H字为设备安装标志,意义为
低字节:7,6位:软驱数量(00:1台;01:2台;10:3台;11:4台)
5,4位:显示模式(01:40*25彩色;10:80*25彩色;11:80*25单色;00:上述以外)
3,2位:无意义
1位:安装协处理器为1
0位:安装软驱为1
高字节:15,14位:并行口打印机数
13位:无意义
13位:安装游戏适配器为1
11-9位:串行口数
8位:保留
显然,这些中断并没有做很多工作。你是不是没想过BIOS程序也有如此简单呢:
(四)比较简单的中断程序
在这一节,我们将介绍INT 5H以及INT 8H。
INT 5H为打印屏幕中断,其编程思路很简单。程序先做好一些初始化工作,如检查屏幕打印状态 ,以及通过INT 17H 检查打印机是否忙碌或纸尽。处理好以上过程后,就开始打印了。打印调用了INT 17H,每调用一次打印一个字符。程序设计了一个二重循环,内循环判断是否换行,外循环判断是否打印结束。就与一对FOR语句嵌套一样。
总的说来,这个程序并无多少可看之处。不过,我们认为程序中开,关中断指令设置的巧极了,它们的位置恰好保护了应该不被中断执行的程序段,具有一些"互斥"意味。此外,打印时还对一些特殊字符进行了过滤,以空格代之打印。
下面,介绍一下INT 8H--定时器中断程序。这里,我们感兴趣的是程序中涉及到了时间。那么,它又是如何解决"千年虫"的问题的?原来,程序设置了一个子过程,它将年代的高两位取出,判断是否为"19XX ",如果不是,则可认为是"20XX"年了;如果是,又取出年代的高两位,判断是否小于"80",如小于,认为到了2000 年,则将年代的高两位标志改为"20",如大于或等于,则认为仍在20世纪。
此外,该程序中还对CMOS 的70,71 端口进行了操作,操作中使用了两条相邻的跳转指令JCXZ进行延时,以确保对端口的操作准确无误。程序的末尾,对8259A主片的20 端口进行了操作。指令为
MOV AL,20
OUT 20,AL
当用8259A来实现中断服务程序结束时(返回指令IRET 前),必须给8259A 送一条EOI命令(即AL第五位为 1)。8259A收到这条命令后,将中断服务寄存器ISR中的相应位清零,然后才可为其他同优先级的中断源服务。
这个中断程序,完成了两个基本功能:计时和管理软磁盘驱动器的启动时间。每调用一次此中断,时间就增加"一秒"(实际约为55毫秒),当小时标志为18H时,还要判断"秒"标志是否到了B0H,这是为了弥补其计时方法引起的误差所采取的措施。程序在修改“计时器”后,还调用了INT 1CH ,紧接着又调用了两个仅包含一条IRET指令的子过程。这有什么作用呢?似乎给我们提供了修改此中断的好方法。
总之,INT 8H是一个比较有意思的中断。由于程序不长,仅70 余行,有兴趣的读者不妨将之反编译,完整的读一下。
(五)INT 18H --一个暗伏圈套的中断
当我们对BIOS进行反编译的时候,常常会碰到诸如DB 0F,DB 66等的语句,那么,程序中出现这些语句又是什么意思呢?先前我们并没有很在意这些语句,仅仅简单的认为它们是在修改BIOS中留下的无用语句(这可是一个可怕的错误)。然而,事实告诉我们,这里隐藏着一个小秘密。让我们先来看一看这个程序。
程序首先设置了屏幕显示格式,然后调用了子过程(CALL EDA8)一次。如果我们以U F000:EDA8翻译它们,则会显示如下语句。
EDA8:PUSH CX
PUSH BX
PUSH DS
PUSH CS
POP DS;DS=F000
XCHG BX,BX
NOP
EDB0:LODSB ;DS:SI=“PRESS A KEY TO REROOT ”,0D 0A 00...
OR AL,AL
EDB3:DB 0F
TEST AL,[DI]
ADD AH,CH
XOR AX,EB00
HLT
EDBC:POP DS
POP BX
POP CX
RET
而主程序为:
E7A4:MOV AX,40
MOV DS,AX
XOR AH,AH
MOV AL,[49]
INT 10
MOV SI,EA70
CALL EDA8 ;显示“PRESS A KEY TO REBOOT”
XOR AH,AH
INT 16 ;等待按下任一键
MOV WORD PTR [72],1234;跳过存储器测试
JMP F470;跳向自检
如果你试读一下,会发现简直莫名其妙,子过程没法读懂。问题出在那呢?我们曾经为此费劲脑筋,直到有一次,我们尝试着运行这个程序,才发现运行的过程与表面的显示有所不同。最终的结论是,DEBUG给我们开了一个大玩笑----DEBUG不认得这是一条高级指令!!!子过程EDB0处的DB 0F开始之处为一条高级指令。大家可以参阅INTEL奔腾机的用户参考手册,它其实是JZ指令。真实的子过程为:
EDA8:PUSH CX
PUSH BX
PUSH DS
PUSH CS
POP DS
XCHG BX,BX
NOP
EDB0:LODSB
OR AL,AL
JZ EDBC
CALL EDEF
JMP EDB0
EDEF:PUSH AX
PUSH BX
MOV AH,0E
MOV BX,3 ;背景为黑色
INT 10 ;显示当前字符
POP BX
POP AX
RET
由于进行了JZ判断,所以程序进行了一个循环,从而显示了一个提示重新启动的字符串--PRESS A KEY TO REBOOT。当然,如果你在WINDOWS下运行这个程序,将会得到一个“程序异常结束”的警告,你可以将WINDOWS切换到MS_DOS模式下,执行这个程序将会重启计算机。大家可以验证一下。
我们从这个程序得到什么启示呢?
1.不要被表面的现象所迷惑,不要想当然。
2.要有扎实的基础知识,只有这样才能发现错误,改正错误。
3.要多实践,不可死背书本。
热心网友
时间:2022-06-20 23:34
通俗地讲,中断服务程序就是当中断发生时,你想要完成的事情,这个程序可以存放在任务内存(Memorry)中。我们仅需要知道其首地址,通常将其首地址存放于特定(由相应的处理器确定)的内存地址中,这个地址就是中断向量,在中断向量中一般只有一条跳转指令,如JMP xxx;后面的xxx就是存放中断服务程序的首地址,你明白了吗?呵呵。追问任务内存是什么不懂?以8086cpu为例,任务内存是位于内存还是其他芯片上?
热心网友
时间:2022-06-20 23:34
中断服务程序,处理器处理“急件”,可理解为是一种服务,是通过执行事先编好的某个特定的程序来完成的,这种处理“急件”的程序被称为——中断服务程序。
中断处理过程:
(1)保护被中断进程现场。为了在中断处理结束后能够使进程准确地返回到中断点,系统必须保存当前处理机程序状态字PSW和程序计数器PC等的值。
(2)分析中断原因,转去执行相应的中断处理程序。在多个中断请求同时发生时,处理优先级最高的中断源发出的中断请求。
(3)恢复被中断进程的现场,CPU继续执行原来被中断的进程。