您的位置:首页 > 其它

int 0x13 中断理解

2015-11-21 13:57 148 查看


int 0x13中断向量所指向的中断服务程序实质上就是磁盘服务程序。


用途:将指定扇区的代码加载到内存的指定位置。

因此,在使用int 0x13中断时要将参数传递给服务程序:
例如:将指定扇区和加载的内存位置传递给服务程序


传递参数的方式:通过几个通用寄存器实现

oad_setup:	mov	dx,#0x0000		! drive 0, head 0	mov	cx,#0x0002		! sector 2, track 0	mov	bx,#0x0200		! address = 512, in INITSEG	mov	ax,#0x0200+SETUPLEN	! service 2, nr of sectors	int	0x13			! read it	jnc	ok_load_setup		! ok - continue	mov	dx,#0x0000	mov	ax,#0x0000		! reset the diskette	int	0x13	j	load_setu

INT
13H这类软件中断指令,功能上是带有现场状态保存和断点地址保存的无条件转移指令。

执行这条指令时,它做这几件事:
1. 将CPU内的标志寄存器内容压入堆栈,用来保存断点的现场状态。
2. 将断点的地址(CS和IP寄存器的当前值)压入堆栈保存,以保存返回所需的断点地址。
3. 按中断号取得中断向量,并无条件跳转到中断向量所指向的目标地址。
此后,CPU就进入中断服务程序去运行它的程序了。而中断服务程序最后会有一条IRET中断返回指令,通过它恢复现场返回断点,程序继续执行INT 指令后面的程序指令。

关于你的两个疑问:
(1)CPU转去执行了BIOS中的相应指令,说得没错。
内存并不只指RAM内存条,ROM也是内存的一部分。
在DOS下,RAM只占用1M地址空间的前640KB,还有384KB系统保留的地址,其中的一部分就是给ROM用的。
ROM中的BIOS程序,是CPU可以直接执行的程序指令。
你电脑开机时,CPU最初执行的POST自检程序,也是在ROM中的。
而ROM中的BIOS(基本输入输出系统)本来就是让电脑在工作中随时调用的功能性子程序的合集。

BIOS中断INT 0x13中,

ah=0x02,即为读磁盘扇区到内存,利用这二号服务即可读入setup模块。

调用此功能将从磁盘上把一个或更多的扇区内容读进存贮器。因为这是一个
低级功能,在一个操作中读取的全部扇区必须在同一条磁道上(磁头号和磁道号
相同)。BIOS不能自动地从一条磁道末尾切换到另一条磁道开始,因此用户必须
把跨多条磁道的读操作分为若干条单磁道读操作。

入口参数:
AH=02H 指明调用读扇区功能。
AL 置要读的扇区数目,不允许使用读磁道末端以外的数值,也不允许使该寄存器为0。

CH 磁道号的低8位数。

CL
低5位放入所读起始扇区号,位7-6表示磁道号的高2位。cl=开始扇区(位0—5),磁道号高二位(位6—7)

DL
需要进行读操作的驱动器号。dl=驱动器号(若是硬盘则要置位7)

DH 所读磁盘的磁头号。dh=磁头号

es:Bx—>指向数据缓冲区
  ES:BX 读出数据的缓冲区地址。

若出错则CF示志置位

返回参数:
如果CF=1,AX中存放出错状态。读出后的数据在ES:BX区域依次排列

BOOTSEG
equ 0x07c0 ;boot.bin 被bios加载到0x7c00内存处

SYSSEG equ 0x1000 ;kernel先被加载到0x10000,再移动到0x0处

SYSLEN equ 17 ;内核最多占用17个扇区 17*512字节

KERNEL_CS equ 0x08 ;内核代码段选择符

start:

     jmp 0x07c0:go ;这条指令将cs寄存器设为0x07c0,便于寻址

go:

     mov ax,cs

     mov ds,ax

     mov es,ax

     mov ss,ax

     mov sp,0x400 ;开辟栈空间逻辑地址0x400-0x200用作栈空间,0x200-0x00用于存放boot.bin

上面的代码先用一个jmp跳转指令将cs寄存器的内容置为0x07c0,并同步给ds,es,ss.这是为了便于后面寻址,这样后面用label(比如load_kernel作为偏移地址时就是实际的物理地址,因为这段程序被加载到0x7c00处,就相当于cs*16 + label = 0x7c00 + label偏移).然后sp赋值为0x400,由于这段程序本身占一个扇区0x200,所以栈空间可用为0x200.

load_kernel:

     mov dx,0x0000 ;DH is head,DL is driver  

     mov cx,0x0002; CL 6,7位是磁道号高2位.位5~0是起始扇区号(从1开始)

     mov ax,SYSSEG

     mov es,ax ;读入缓冲区基址0x1000
 

     xor bx,bx

     mov ax,0x200 + SYSLEN ;AH-读扇区功能号(2);AL-需要读的扇区数(17,即第一柱面除去第1个扇区(是boot.s),剩余的17个扇区是kernel.bin)

     int 0x13

     jnc load_ok; 如果有错误, CF位会被置位

load_fail: jmp load_fail ;死循环

、、、

load_setup:
mov dx,#0x0000 !驱动器0,磁头0;
mov cx,#0x0002 !扇区2,磁道0;
mov bx,#0x0200 !此时es已置为0x9000,则指向地址0x9200;
mov ax,#0x0200+SETUPLEN !置为服务二,读入SETUPLEN=4个扇区;
int 0x13 !中断13;
jnc ok_load_setup !判断是否成功;
mov dx,#0x0000 !未成功,复位磁盘;
mov ax,#0x0000 
int 0x13
j load_setup !继续读;
ok_load_setup:

INT 13H,AH=03H 写扇区

说明:

调用此功能将从磁盘上把一个或更多的扇区内容写入驱动器。因为这

是一个低级功能,在一个写入操作中的全部扇区必须在同一条磁道上(磁

头号和磁道号相同)。BIOS不能自动地从一条磁道末尾切换到另一条磁道

开始,因此用户必须把跨多条磁道的写操作分为若干条单磁道写操作。

入口参数:
AH=03H 指明调用写扇区功能。

AL 置要写的扇区数目
,不允许使用超出磁道末端以外的数值,

也不允许使该寄存器为0。
DL 需要进行写操作的驱动器号。

DH 所写磁盘的磁头号。

CH 磁道号的低8位数。

CL 低5位放入所读起始扇区号,位7-6表示磁道号的高2位

ES:BX 放置写入数据的存贮区地址。

返回参数:

如果CF=1,AX中存放出错状态。

详情请参见磁盘错误状态返回码一文。

示例:
C_SEG SEGMENT PUBLIC

ASSUME CS:C_SEG,DS:C_SEG

ORG 100H

START: JMP WRITE

BUFFER DB 512 DUP(0FFH)

WRITE: PUSH CS

POP ES

MOV BX, OFFSET BUFFER

MOV AX, 0301H

MOV CX, 0001H

MOV DX, 0000H

INT 13H

;写入软盘A, 0面0道1扇区

;把此扇区数据全部置为0FFH

JC ERROR

……

ERROR: ……

C_SEG ENDS

END START
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: