关闭

int 0x13 中断理解

1744人阅读 评论(0) 收藏 举报
分类:

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



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:250378次
    • 积分:6071
    • 等级:
    • 排名:第4695名
    • 原创:292篇
    • 转载:536篇
    • 译文:1篇
    • 评论:73条
    最新评论