0x13 bios - CSDN
  • 直接磁盘服务(Direct Disk Service——INT 13H)00H —磁盘系统复位 0EH —读扇区缓冲区01H —读取磁盘系统状态 0FH —写扇区缓冲区02H —读扇区 10H —读取驱动器状态03H —写扇区 11H —校准驱动器04H...

    直接磁盘服务(Direct Disk Service——INT 13H)

    00H —磁盘系统复位                  0EH —读扇区缓冲区

    01H —读取磁盘系统状态               0FH —写扇区缓冲区

    02H —读扇区                      10H —读取驱动器状态

    03H —写扇区                      11H —校准驱动器

    04H —检验扇区                     12H —控制器RAM诊断

    05H —格式化磁道                   13H —控制器驱动诊断

    06H —格式化坏磁道                  14H —控制器内部诊断

    07H —格式化驱动器                  15H —读取磁盘类型

    08H —读取驱动器参数                 16H —读取磁盘变化状态

    09H —初始化硬盘参数                 17H —设置磁盘类型

    0AH —读长扇区                     18H —设置格式化媒体类型

    0BH —写长扇区                     19H —磁头保护

    0CH —查寻                        1AH —格式化ESDI驱动器

    0DH —硬盘系统复位

     

    (1)       功能00H

     

    功能描述:磁盘系统复位

    入口参数:AH=00H

    DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘

    出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明

     

    (2)       功能01H

     

    功能描述:读取磁盘系统状态

    入口参数:AH=01H

    DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘

    出口参数:AH=00H,AL=状态代码,其定义如下:

    00H — 无错 01H — 非法命令

    02H — 地址目标未发现03H — 磁盘写保护(软盘)

    04H — 扇区未发现05H — 复位失败(硬盘)

    06H — 软盘取出(软盘)07H — 错误的参数表(硬盘)

    08H — DMA越界(软盘)09H — DMA超过64K界限

    0AH — 错误的扇区标志(硬盘)0BH — 错误的磁道标志(硬盘)

    0CH — 介质类型未发现(软盘)0DH — 格式化时非法扇区号(硬盘)

    0EH — 控制数据地址目标被发现(硬盘)0FH — DMA仲裁越界(硬盘)

    10H — 不正确的CRC或ECC编码11H — ECC校正数据错(硬盘)

     CRC:Cyclic Redundancy Check code

     ECC:Error Checking & Correcting code

    20H — 控制器失败40H — 查找失败

    80H — 磁盘超时(未响应)AAH — 驱动器未准备好(硬盘)

    BBH — 未定义的错误(硬盘)CCH — 写错误(硬盘)

    E0H — 状态寄存器错(硬盘)FFH — 检测操作失败(硬盘)

     

    (3)       功能02H

     

    功能描述:读扇区

    入口参数:AH=02H

    AL=扇区数

    CH=柱面

    CL=扇区

    DH=磁头

    DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘

    ES:BX=缓冲区的地址

    出口参数:CF=0——操作成功,AH=00H,AL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明

     

    (4)       功能03H

     

    功能描述:写扇区

    入口参数:AH=03H

    AL=扇区数

    CH=柱面

    CL=扇区

    DH=磁头

    DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘

    ES:BX=缓冲区的地址

    出口参数:CF=0——操作成功,AH=00H,AL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明

     

    (5)       功能04H

     

    功能描述:检验扇区

    入口参数:AH=04H

    AL=扇区数

    CH=柱面

    CL=扇区

    DH=磁头

    DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘

    ES:BX=缓冲区的地址

    出口参数:CF=0——操作成功,AH=00H,AL=被检验的扇区数,否则,AH=状态代码,参见功能号01H中的说明。

     

    (6)       功能05H

     

    功能描述:格式化磁道

    入口参数:AH=05H

    AL=交替(Interleave)

    CH=柱面

    DH=磁头

    DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘

    ES:BX=地址域列表的地址

    出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明。

     

    (7)       功能06H

     

    功能描述:格式化坏磁道

    入口参数:AH=06H

    AL=交替

    CH=柱面

    DH=磁头

    DL=80H~0FFH:硬盘

    ES:BX=地址域列表的地址

    出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明

     

    (8)       功能07H

     

    功能描述:格式化驱动器

    入口参数:AH=07H

    AL=交替

    CH=柱面

    DL=80H~0FFH:硬盘

    出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明

     

    (9)       功能08H

     

    功能描述:读取驱动器参数

    入口参数:AH=08H

    DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘

    出口参数:CF=1——操作失败,AH=状态代码,参见功能号01H中的说明,否则, BL=01H — 360K

    =02H — 1.2M

    =03H — 720K

    =04H — 1.44M

    CH=柱面数的低8位

    CL的位7-6=柱面数的该2位

    CL的位5-0=扇区数

    DH=磁头数

    DL=驱动器数

    ES:DI=磁盘驱动器参数表地址

     

    (10)   功能09H

     

    功能描述:初始化硬盘参数

    入口参数:AH=09H

    DL=80H~0FFH:硬盘(还有有关参数表问题,在此从略)

    出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明

     

    (11)   功能0AH

     

    功能描述:读长扇区,每个扇区随带四个字节的ECC编码

    入口参数:AH=0AH

    AL=扇区数

    CH=柱面

    CL=扇区

    DH=磁头

    DL=80H~0FFH:硬盘

    ES:BX=缓冲区的地址

    出口参数:CF=0——操作成功,AH=00H,AL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明

     

    (12)   功能0BH

     

    功能描述:写长扇区,每个扇区随带四个字节的ECC编码

    入口参数:AH=0BH

    AL=扇区数

    CH=柱面

    CL=扇区

    DH=磁头

    DL=80H~0FFH:硬盘

    ES:BX=缓冲区的地址

    出口参数:CF=0——操作成功,AH=00H,AL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明

     

    (13)   功能0CH

     

    功能描述:查寻

    入口参数:AH=0CH

    CH=柱面的低8位

    CL(7-6位)=柱面的高2位

    DH=磁头

    DL=80H~0FFH:硬盘

    出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明

     

    (14)   功能0DH

     

    功能描述:硬盘系统复位

    入口参数:AH=0DH

    DL=80H~0FFH:硬盘

    出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明

     

    (15)   功能0EH

     

    功能描述:读扇区缓冲区

    入口参数:AH=0EH

    ES:BX=缓冲区的地址

    出口参数:CF=0——操作成功,否则,AH=状态代码,参见功能号01H中的说明

     

    (16)   功能0FH

     

    功能描述:写扇区缓冲区

    入口参数:AH=0FH

    ES:BX=缓冲区的地址

    出口参数:CF=0——操作成功,否则,AH=状态代码,参见功能号01H中的说明

     

    (17)   功能10H

     

    功能描述:读取驱动器状态

    入口参数:AH=10H

    DL=80H~0FFH:硬盘

    出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明

     

    (18)   功能11H

     

    功能描述:校准驱动器

    入口参数:AH=11H

    DL=80H~0FFH:硬盘

    出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明

     

    (19)   功能12H

     

    功能描述:控制器RAM诊断

    入口参数:AH=12H

    出口参数:CF=0——操作成功,否则,AH=状态代码,参见功能号01H中的说明

     

    (20)   功能13H

     

    功能描述:控制器驱动诊断

    入口参数:AH=13H

    出口参数:CF=0——操作成功,否则,AH=状态代码,参见功能号01H中的说明

     

    (21)   功能14H

     

    功能描述:控制器内部诊断

    入口参数:AH=14H

    出口参数:CF=0——操作成功,否则,AH=状态代码,参见功能号01H中的说明

     

    (22)   功能15H

     

    功能描述:读取磁盘类型

    入口参数:AH=15H

    DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘

    出口参数:CF=1——操作失败,AH=状态代码,参见功能号01H中的说明, 否则,AH=00H — 未安装驱动器

    =01H — 无改变线支持的软盘驱动器

    =02H — 带有改变线支持的软盘驱动器

    =03H — 硬盘,CX:DX=512字节的扇区数

     

    (23)   功能16H

     

    功能描述:读取磁盘变化状态

    入口参数:AH=16H

    DL=00H~7FH:软盘

    出口参数:CF=0——磁盘未改变,AH=00H,否则,AH=06H,参见功能号01H中的说明

     

    (24)   功能17H

     

    功能描述:设置磁盘类型

    入口参数:AH=17H

    DL=00H~7FH:软盘 AL=00H — 未用

    =01H — 360K在360K驱动器中

    =02H — 360K在1.2M驱动器中

    =03H — 1.2M在1.2M驱动器中

    =04H — 720K在720K驱动器中

    出口参数:CF=0——操作成功,AH=00H,否则,AH=状态编码,参见功能号01H中的说明

     

    (25)   功能18H

     

    功能描述:设置格式化媒体类型

    入口参数:AH=18H

    CH=柱面数

    CL=每磁道的扇区数

    DL=00H~7FH:软盘

    出口参数:CF=0——操作成功,AH=00H,ES:DI=介质类型参数表地址,否则,AH=状态编码,参见功能号01H中的说明

     

    (26)   功能19H

     

    功能描述:磁头保护,仅在PS/2中有效,在此从略

     

    (27)   功能1AH

     

    功能描述:格式化ESDI驱动器,仅在PS/2中有效,在此从略




    展开全文
  • babyos将使用的引导过程软盘的结构利用BIOS 中断读取软盘相对扇区号的计算读取一个扇区读取任意扇区给定相对扇区号 注:以下程序为原创,若发现任何BUG,欢迎指正;若有问题,欢迎交流;权利归原作者所有,若...
    
    

    注:以下程序为原创,若发现任何BUG,欢迎指正;若有问题,欢迎交流;权利归原作者所有,若转载,请注明出处;若能有益于一二访客,幸甚。

    昨天学习了VGA显示的一些东西,今天准备学习一下读取软盘的知识。


    1.babyos将使用的引导过程

    1)系统上电或reset时,处理器执行一些初始化,CPU处于实模式
    2)处理器会执行一个位于已知位置处的代码,PC中这个位置位于BIOS,它保存在主板上的闪存中
    3)控制权交给BIOS后,它寻找一个可引导的设备(软盘、硬盘等),BIOS读取引导扇区(512字节)到内存0x7c00处,并跳转到该地址执行
    4)引导扇区中存放的指令可以使用BIOS中断,它将会读取软盘中内核部分到一个临时地址(如0x10000,不覆盖0x7c00处的boot代码即可)
    5)将内核前512字节(load.s, 它主要负责将内核剩余部分拷贝到load.s后面)移动到0x0处,将GDT拷贝到0x80000处。为什么不一次全部将内核放到0x0处呢?因为内核可能较大,会覆盖掉0x7c00处的代码。
    6)开启A20总线,置位CR0的bit 0,开启保护模式,加载GDT到GDTR,跳转到GDT第二项(第一项为空GDT),即load.s处执行
    7)load.s将内核剩余部分移动到load.s后面,即0x200开始的地址处。然后执行初始化代码。
    8)初始化代码,至此系统启动成功。

    所以首当其冲的问题就是如何读软盘。

    2.软盘的结构

    3.5寸1.44M 软盘,如图floppy_struct.png 所示,有两个磁头,正反两面各一个;80个磁道(即80个圆圈);每个磁道有18个扇区;每个扇区为512字节。
    容量 = 512字节/扇区 * 2面 * 80磁道(柱面)/面 * 18扇区/磁道 = 1440 KB

    磁头,即面:编号[0, 1]
    80个磁道,即柱面(圆圈):编号[0, 79]
    18个扇区:编号[1, 18]

    相对扇区号[0, 2879]:
    相对扇区号按照柱面排序,即从最外头的圆圈到最里头的圆圈。
    0柱面正面(即磁头号为0)的1-18扇区为0-17号相对扇区,0柱面反面(即磁头号为2)的1-18扇区为18-35号相对扇区,然后是1柱面,2柱面,直到79柱面。如下:
    1. 0柱面,0磁头,1扇区         0  
    2. 0柱面,0磁头,2扇区         1  
    3. ……  
    4. 0柱面,0磁头,18扇区        17  
    5. 0柱面,1磁头,1扇区         18  
    6. ……  
    7. 0柱面,1磁头,18扇区        35  
    8. 1柱面,0磁头,1扇区         36  
    9. ……  
    10. 1柱面,0磁头,18扇区        53  
    11. 1柱面,1磁头,1扇区         54  
    12. ……  
    13. 1柱面,1磁头,18扇区        71  
    14. 2柱面,0磁头,1扇区         72  
    15. ……  

    3.利用BIOS 中断读取软盘

    1. -------------------------------------------------------------------  
    2.                     INT 0x13,功能02  
    3. -----------------------------------------------------------  
    4. 参数:  
    5.     AH      02  
    6.     AL      读取扇区数  
    7.     CH      柱面[0, 79]  
    8.     CL      扇区[1, 18]  
    9.     DH      磁头[0, 1]  
    10.     DL      驱动器(0x0 ~ 0x7f表示软盘,0x80 ~ 0xff表示硬盘)  
    11.     ES:BX   缓冲区地址,即数据读到这里  
    12. 返回值:  
    13.     CF = 0表示操作成功,此时AH=0,AL=传输的扇区数  
    14.     CF = 1即carry位置位(可用JC表示跳转)表示操作失败,AH=状态代码  
    15. --------------------------------------------------------------------  

    4.相对扇区号的计算

    1)知道柱面号,磁头号,扇区号计算相对扇区号
    由上面可知0号柱面包含了相对扇区号[0,35],1号柱面包含相对扇区号[36,71],依次类推。
    设相对扇区号为N,则
    柱面号CH = N / 36;
    令x = N % 36;
    则x范围为[0,35],其中[0,17] 为磁头号0, [18,35]为磁头号1.
    则磁头号DH = x / 18;
    零y = x % 18; y范围[0, 17]
    则扇区号CL = y + 1。

    2)知道相对扇区号,计算柱面号、磁头号、扇区号
    N = 36*CH + 18*DH + CL;
    由此式子,也可计算:
    CH = N / 36
    DH = (N % 36) / 18
    CL = (N % 36) % 18 + 1

    5.读取一个扇区

    实验:将一些数据写入软盘的第二个扇区(第一个扇区是引导扇区),然后用BIOS 中断读取该扇区的数据,并显示在屏幕上。然后看读取的数据是否与写入的数据相同。注:第二个扇区相对扇区号为1.
    1. 写数据的C代码:  
    2. /************************************************************************* 
    3.     > File:      write_data.c 
    4.     > Author:    孤舟钓客 
    5.     > Mail:      guzhoudiaoke@126.com  
    6.     > Time:      2012年12月26日 星期三 01时20分26秒 
    7.  ************************************************************************/  
    8.   
    9. #include <stdio.h>  
    10. #include <string.h>  
    11.   
    12. int main()  
    13. {  
    14.     FILE *fp;  
    15.     fp = fopen("./data""wb");  
    16.       
    17.     int i;  
    18.     char *str = "baby os, guzhoudiaoke@126.com ";  
    19.     int len = strlen(str);  
    20.       
    21.     for (i = 0; i < len; i++)  
    22.         fprintf(fp, "%c", str[i]);  
    23.   
    24.     for (i = 512-len; i > 0; i--)  
    25.         fprintf(fp, "%c", i % 26 + 'A');  
    26.   
    27.     return 0;  
    28. }  
    29.   
    30. 汇编代码:  
    31. # This program draws color pixels at mode 0x13  
    32. # 2012-12-26 01:31  
    33. # guzhoudiaoke@126.com  
    34.   
    35. .include "boot.inc"  
    36.   
    37. .section .text  
    38. .global _start  
    39. .code16  
    40.   
    41. _start:  
    42.     jmp     main  
    43.   
    44. #--------------------------------------------------------------  
    45. # 清屏函数:  
    46. #   设置屏幕背景色,调色板的索引0指代的颜色为背景色  
    47. clear_screen:               # 清屏函数  
    48.     movb    $0x06,  %ah     # 功能号0x06  
    49.     movb    $0,     %al     # 上卷全部行,即清屏  
    50.     movb    $0,     %ch     # 左上角行  
    51.     movb    $0,     %ch     # 左上角列    
    52.     movb    $24,    %dh     # 右下角行  
    53.     movb    $79,    %dl     # 右下角列  
    54.     movb    $0x07,  %bh     # 空白区域属性  
    55.     int     $0x10  
    56.     ret  
    57.   
    58. #---------------------------------------------------------------  
    59. # 直接写显存显示一些文字函数:  
    60. #   调用前需要设置DS:SI为源地址,DI为显示位置,  
    61. #   CX 为显示的字符个数, AL为颜色属性  
    62. draw_some_text:  
    63.     # ES:DI is the dst address, DS:SI is the src address  
    64.     movw    $VIDEO_SEG_TEXT,    %bx  
    65.     movw    %bx,                %es  
    66.       
    67. copy_a_char:  
    68.     movsb  
    69.     stosb  
    70.     loop    copy_a_char  
    71.     ret  
    72.   
    73. #----------------------------------------------------------------  
    74. # 读取软盘第二个扇区:  
    75. #   使用BIOS INT 0x13中断,使用前需要设置ES:BX作为缓冲区  
    76. read_one_sect:  
    77.     movb    $0x02,  %ah     # 功能号  
    78.     movb    $0x01,  %al     # 读取扇区数  
    79.     movb    $0x00,  %ch     # 柱面号  
    80.     movb    $0x02,  %cl     # 扇区号  
    81.     movb    $0x00,  %dh     # 磁头号  
    82.     movb    $0x00,  %dl     # 驱动器号  
    83.   
    84. re_read:                    # 若调用失败则重新调用  
    85.     int     $0x13  
    86.     jc      re_read         # 若进位位(CF)被置位,表示调用失败  
    87.       
    88.     ret  
    89.   
    90. main:  
    91.     movw    %cx,    %ax  
    92.     movw    %ax,    %ds  
    93.     movw    %ax,    %es  
    94.   
    95.     call    clear_screen        # 清屏  
    96.   
    97.     movw    $0,         %ax  
    98.     movw    %ax,        %ds  
    99.     leaw    msg_str,    %si  
    100.     xorw    %di,        %di  
    101.     movw    msg_len,    %cx  
    102.     movb    $TEXT_COLOR,%al  
    103.     call    draw_some_text      # 绘制字符串  
    104.   
    105.     movw    $BUFFER_SEG,%ax       
    106.     movw    %ax,        %es     # ES:BX 为缓冲区地址  
    107.     xorw    %bx,        %bx  
    108.     call    read_one_sect  
    109.   
    110.     # 下面调用绘制函数,在屏幕上显示读取的信息  
    111.     movw    $BUFFER_SEG,%ax  
    112.     movw    %ax,        %ds     # ds:si 为源地址  
    113.     xorw    %si,        %si  
    114.     movw    $160,       %di     # 第一行已经打印了msg_str,从第二行开始显示  
    115.     movw    $512,       %cx     # 显示512个字符  
    116.     movb    $0x01,      %al  
    117.     call    draw_some_text  
    118.   
    119. 1:  
    120.     jmp     1b  
    121.   
    122. msg_str:  
    123.     .asciz  "The data of the second sect of the floppy (sect 1):"  
    124. msg_len:  
    125.     .int    . - msg_str - 1  
    126.   
    127.     .org    0x1fe,  0x90  
    128.     .word   0xaa55  

    实验结果:



    6.读取任意扇区(给定相对扇区号)

    实验,写用C语言写入文件,该文件包含512个‘a’,512个1……512个‘z’, 循环50次,将该文件写入软盘(相对扇区号1~50*26),然后读取给定的相对扇区号的扇区,将读取的内容打印到屏幕上。并与写入的数据比较,验证读取的正确性。

    1. C代码用于写文件:  
    2. /************************************************************************* 
    3.     > File:      write_data.c 
    4.     > Author:    孤舟钓客 
    5.     > Mail:      guzhoudiaoke@126.com  
    6.     > Time:      2012年12月26日 星期三 20时16分45秒 
    7.  ************************************************************************/  
    8.   
    9. #include <stdio.h>  
    10. #include <string.h>  
    11.   
    12. int main(int argc, char *argv[])  
    13. {  
    14.     if (argc != 2)  
    15.     {  
    16.         printf("usage: ./write_data file_name");  
    17.         exit(0);  
    18.     }  
    19.   
    20.     FILE *fp;  
    21.     fp = fopen(argv[1], "wb");  
    22.       
    23.     int i, j, k;  
    24.   
    25.     for (i = 0; i < 50; i++)  
    26.     {  
    27.         for (j = 'a'; j <= 'z'; j++)  
    28.         {  
    29.             for (k = 0; k < 512; k++)  
    30.             {  
    31.                 fprintf(fp, "%c", (char)j);  
    32.             }  
    33.         }  
    34.     }  
    35.   
    36.     return 0;  
    37. }  
    38.   
    39. 汇编代码:  
    40. # This program draws color pixels at mode 0x13  
    41. # 2012-12-26 20:23:42  
    42. # guzhoudiaoke@126.com  
    43.   
    44. .include "boot.inc"  
    45.   
    46. .section .text  
    47. .global _start  
    48. .code16  
    49.   
    50. _start:  
    51.     jmp     main  
    52.   
    53. #--------------------------------------------------------------  
    54. # 清屏函数:  
    55. #   设置屏幕背景色,调色板的索引0指代的颜色为背景色  
    56. clear_screen:               # 清屏函数  
    57.     movb    $0x06,  %ah     # 功能号0x06  
    58.     movb    $0,     %al     # 上卷全部行,即清屏  
    59.     movb    $0,     %ch     # 左上角行  
    60.     movb    $0,     %ch     # 左上角列    
    61.     movb    $24,    %dh     # 右下角行  
    62.     movb    $79,    %dl     # 右下角列  
    63.     movb    $0x07,  %bh     # 空白区域属性  
    64.     int     $0x10  
    65.       
    66.     ret  
    67.   
    68. #---------------------------------------------------------------  
    69. # 直接写显存显示一些文字函数:  
    70. #   调用前需要设置DS:SI为源地址,DI为在屏幕上的显示位置,  
    71. #   CX 为显示的字符个数, AL为颜色属性  
    72. draw_some_text:  
    73.     # ES:DI is the dst address, DS:SI is the src address  
    74.     movw    $VIDEO_SEG_TEXT,    %bx  
    75.     movw    %bx,                %es  
    76.       
    77. copy_a_char:  
    78.     movsb  
    79.     stosb  
    80.     loop    copy_a_char  
    81.   
    82.     ret  
    83.   
    84. #----------------------------------------------------------------  
    85. # 读取软盘一个扇区:  
    86. #   使用BIOS INT 0x13中断,使用前需要设置ES:BX作为缓冲区  
    87. #   AX为相对扇区号  
    88. read_one_sect:  
    89.     movb    $36,    %dl  
    90.     divb    %dl  
    91.     movb    %al,    %ch     # 柱面号=N / 36, 假设x = N % 36  
    92.       
    93.     movb    %ah,    %al     # AL = N % 36  
    94.     movb    $0,     %ah     # AX = N % 36  
    95.     movb    $18,    %dl  
    96.     divb    %dl  
    97.     movb    %al,    %dh     # 磁头号DH = x / 18  
    98.     movb    %ah,    %cl       
    99.     incb    %cl             # 扇区号CL = x % 18 + 1  
    100.   
    101.     movb    $0x00,  %dl     # 驱动器号DL  
    102.   
    103.     movb    $0x02,  %ah     # 功能号  
    104.     movb    $0x01,  %al     # 读取扇区数  
    105.   
    106. re_read:                    # 若调用失败则重新调用  
    107.     int     $0x13  
    108.     jc      re_read         # 若进位位(CF)被置位,表示调用失败  
    109.       
    110.     ret  
    111.   
    112. #-------------------------------------------------------------------  
    113. # 该函数读取指定的若干扇区号  
    114. #   需要指定ES:BX作为缓冲区  
    115. read_sects:  
    116.     movw    $0x00,          %si     # 已经读取的扇区数  
    117.     leaw    sect_no,        %di  
    118. 1:    
    119.     movw    (%di),          %ax     # 获取相对扇区号  
    120.     addw    $2,             %di  
    121.       
    122.     call    read_one_sect  
    123.       
    124.   
    125.     incw    %si  
    126.     incw    %bx  
    127.     cmpw    num_to_read,    %si  
    128.     jne     1b  
    129.   
    130.     ret  
    131.   
    132. main:  
    133.     movw    %cx,    %ax  
    134.     movw    %ax,    %ds  
    135.     movw    %ax,    %es  
    136.   
    137.     call    clear_screen        # 清屏  
    138.   
    139.     # 显示提示信息  
    140.     movw    $0,         %ax  
    141.     movw    %ax,        %ds  
    142.     leaw    msg_str,    %si  
    143.     xorw    %di,        %di  
    144.     movw    msg_len,    %cx  
    145.     movb    $TEXT_COLOR,%al  
    146.     call    draw_some_text      # 绘制字符串  
    147.   
    148.     # 读取软盘  
    149.     movw    $BUFFER_SEG,        %ax       
    150.     movw    %ax,                %es     # ES:BX 为缓冲区地址  
    151.     xorw    %bx,                %bx  
    152.     call    read_sects  
    153.       
    154. # 在屏幕上显示读取的信息  
    155. #   movw    $BUFFER_SEG,%ax  
    156. #   movw    %ax,        %ds     # ds:si 为源地址  
    157. #   movw    $0,         %si  
    158. #   movw    $320,       %di     # 第一行已经打印了msg_str,从第二行开始显示  
    159. #   movw    $512,       %cx     # 显示字符数  
    160. #   movb    $0x01,      %al  
    161. #   call    draw_some_text  
    162.       
    163.     # 将缓冲区中前data_len个字节拷贝到data_save  
    164.     xorw    %ax,        %ax  
    165.     movw    %ax,        %ds  
    166.     movw    num_to_read,%cx  
    167.       
    168.     movw    $BUFFER_SEG,%ax  
    169.     movw    %ax,        %ds  
    170.     xorw    %ax,        %ax  
    171.     movw    %ax,        %es  
    172.     movw    $0,         %si  
    173.     movw    $data_save, %di  
    174.   
    175.     cld  
    176.     rep     movsb  
    177.   
    178.     # 下面调用绘制函数,在屏幕上显示读取的信息  
    179.     xorw    %ax,        %ax  
    180.     movw    %ax,        %ds     # ds:si 为源地址  
    181.     leaw    data_save,  %si  
    182.     movw    $160,       %di     # 第一行已经打印了msg_str,从第二行开始显示  
    183.     movw    num_to_read,%cx     # 显示字符数  
    184.     movb    $0x01,      %al  
    185.     call    draw_some_text  
    186.   
    187. 1:  
    188.     jmp     1b  
    189.   
    190. msg_str:  
    191.     .asciz  "The data read from floppy:"  
    192. msg_len:  
    193.     .short  . - msg_str - 1  
    194.   
    195. sect_no:  
    196.     # 下面的扇区数据为:"babyosguzhoudiaoke"  
    197.     # sect: 2+26*1,     1+26*2,     2+26*3,     25+26*4,    15+26*5,    19+26*6,      
    198.     #       7+26*11,    21+26*12,   26+26*13,   8+26*14,    15+26*15,   21+26*16,  
    199.     #       4+26*31,    9+26*32,    1+26*33,    15+26*34,   11+26*35,   5+26*36  
    200.     .short  28,         53,         80,         129,        145,        175   
    201.     .short  293,        333,        364,        372,        379,        411  
    202.     .short  810,        841,        859,        899,        921,        941  
    203. num_to_read:  
    204.     .short  18  
    205.   
    206. data_save:  
    207.     .asciz  "XXXXXXXXXXXXXXXXXX"  
    208.       
    209.     .org    0x1fe,  0x90  
    210.     .word   0xaa55  



    1. <pre></pre>  
    2. <pre></pre> 


    3. 原文地址 :http://blog.csdn.net/guzhou_diaoke/article/details/8436037 
    展开全文
  • int 0x13 中断理解

    2015-11-21 23:27:25
    BIOS中断INT 0x13中, ah=0x02,即为读磁盘扇区到内存,利用这二号服务即可读入setup模块。 调用此功能将从磁盘上把一个或更多的扇区内容读进存贮器。因为这是一个 低级功能,在一个操作中读取的全部扇区必须在同一条...

    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



    展开全文
  • Bootsect代码详解续

    2019-03-02 22:46:16
    使用的是INT 0x13 BIOS中断程序,主要就是学习一下到底该如何调用这个中断程序。 JNC:如果CF标志位没有被置位。J就是段内跳转指令。常数用#号打头。 读完磁盘4个扇区后,仍然是用INT 0x13中断程序,ah=0x08,dl...

    下面这段汇编代码是从磁盘第2扇区读取4个扇区2K字节到内存0x90200开始处。使用的是INT 0x13 BIOS中断程序,主要就是学习一下到底该如何调用这个中断程序。

    JNC:如果CF标志位没有被置位。J就是段内跳转指令。常数用#号打头。

    读完磁盘4个扇区后,仍然是用INT 0x13中断程序,ah=0x08,dl=0,可以获取到磁盘信息:

    需要说明的是第86行,因为是使用的软盘启动,软盘的磁道号不会超过256的,所以高两位肯定都是0,而这里主要是想获取每道的扇区数量。

    另外,上面代码中使用了“段超越”或者称为段覆盖前缀,将cx(每磁道扇区数)复制到CS:sectors内存处。这里思考一个问题如果不用seg cs,每磁道扇区数会被保存在哪个段呢?另外,INT 0x13修改了es的值,es被修改成了什么?

     

    下面再继续分析获取光标位置和打印文本信息的代码:

    ah=0x03表示读取光标的位置,光标位置存放在DH(y轴)和DL(x轴),bh==0表示以图形方式显示。

    ah=0x13表示从ES:BP内存处读取cx=24个字符显示并且移动光标。

    下面看下msg1的定义:

    Loading system ...为18个byte,加上回车和换行符6个byte共24个字符。

     

    展开全文
  • INT 13h services Drive Table DL = 00h 1st floppy disk ( "drive A:" ) DL = 01h 2nd floppy disk ( "drive B:" ) DL = 02h 3rd floppy disk ( "drive B:" ) . ....DL = 7Fh 128th floppy disk) ...
  • int 0x13中断向量所指向的中断服务程序实质上就是磁盘服务程序。 用途:将指定扇区的代码载入到内存的指定位置。 因此,在使用int 0x13中断时要将參数传递给服务程序: 比如:将指定扇区和载入的内存位置传递给...
  • 背景 基本上,每个硬盘除了每扇(Sector)大小依旧是512字节外,柱面...参考Windows 7也是用INT 0x13/AH=0x42h读磁盘。用该方法读磁盘只需要关注到扇区即可,不需要关注到柱面跟磁头数,很直观。 调试 Bochs...
  • 第一步:重启,敲击F1进入BIOS 此步骤必须是重启过程,外置接口处不能插任何设备。 如开机过程将不会进入BIOS;如安插其他设备将在F1之后无法进入BIOS,需强制关机(长按电源键)再开。 第二步:调节Security下...
  • 注:以下程序为原创,若发现任何BUG,欢迎指正;若有问题,欢迎交流;权利归原作者所有,若转载,请注明出处;...2)处理器会执行一个位于已知位置处的代码,PC中这个位置位于BIOS,它保存在主板上的
  • BIOS INT 10中断功能

    2018-04-07 20:52:18
    INT 10H 是由 BIOS 对屏幕及显示器所提供的服务程序,而后倚天公司针对倚天中文提供了许多服务程序,这些服务程序也加挂在 INT 10H 内。使用 INT 10H 中断服务程序时,先指定 AH 寄存器为下表编号其中之一,该编号...
  • BIOS的10H中断的13号中断用于显示字符串,参数为: 1、AH=13H 2、AL=显示方式  如果AL=0,表示目标字符串仅仅包含字符,属性在BL中包含,不移动光标  如果AL=1,表示目标字符串仅仅包含字符,属性在BL中包含,...
  • 中断INT13功能及用法分析 INT 13H,AH=00H 软、硬盘控制器复位 ...当磁盘I/O功能调用出现错误时,需要调用此功能,此刻复位功能将使BIOS 象该磁盘重新插入一样检查驱动器中磁盘状态,并将磁头校准使之在应该在的
  • 注:以下程序系原创,使用AT&T格式汇编来调用BIOS 0x10中断,如有错误,欢迎指正。表达能力较差,写的不好,但若能帮助一二访客,幸甚。 使用BIOS 显示服务(Video Service)--INT 10H,下面主要探究字符显示...
  • 注:以下程序系原创,使用AT&T格式汇编来调用BIOS 0x10中断,如有错误,欢迎指正。表达能力较差,写的不好,但若能帮助一二访客,幸甚。 使用BIOS 显示服务(Video Service)--INT 10H,下面主要探究字符显示...
  • 引导扇区负责把内核程序读到内存中(通过bios 0x13中断),读入内存后,通过判断是否读成功,在屏幕上显示不同的提示字符(通过bios 0x10中断)。 bootsect.s BOOTSEG equ 0x7c0 section .text vstart=0 jmp ...
  • 2.2 BIOS中断

    2019-07-21 19:52:26
    BIOS中断 BIOS中断简介 计算机刚启动时,进入实模式下,此时操作系统跟硬件(例如键盘鼠标显卡等)交互通过BIOS进行的。通过调用中BIOS中断的方式来访问...中断向量表位于BIOS0x0000 - 0x03FF 地方,大小为 1k。...
  • 我们假定本书所用的计算机是基于 IA—32 系列 CPU, 安装了标准单色显示器、 标准键 盘、一个软驱、一块硬盘、16 MB ... 目前处于实模式下,内存地址为0x00000~0xFFFFF,共1MB,20位地址线,BIOS所占地址为0xFE000~
1 2 3 4 5 ... 20
收藏数 1,888
精华内容 755
热门标签
关键字:

0x13 bios