boot/include/lib_in_real_mode.inc

本文介绍实模式下的磁盘操作函数,包括扇区读取、获取FAT条目值,以及屏幕显示字符串的功能实现。这些函数用于加载器和启动过程中的基本输入输出操作。
Code:
  1. ;By Marcus Xing   
  2. ;boot/include/lib_in_real_mode.inc   
  3. ;在boot/loader.asm中在实模式下调用的函数   
  4.   
  5. ;--------------------------------------------------------------------Read_Sector   
  6. Read_Sector:   
  7. ;C函数原型(实模式下调用,短调用):   
  8. ;void Read_Sector(byte16 first_sector_index,byte16 read_sector_number);   
  9. ;注意:   
  10. ;调用前es:bx必须指向缓冲区,ds指向数据区   
  11. ;逻辑扇区号转化为系统调用所需参数的公式如下:   
  12. ;相对扇区号/每磁道扇区号(18)的商Q,余数R   
  13. ;其中:柱面号=Q>>1,磁头号=Q&1,相对起始扇区号=R+1   
  14.   
  15. ;对应的系统调用API如下:   
  16. ;功能号ah=02  
  17. ;hal=要读的扇区数   
  18. ;ch=柱面(磁道)号   
  19. ;cl=起始扇区号   
  20. ;dh=磁头号,dl=驱动器号(0表示A盘)   
  21. ;es:bx缓冲区地址   
  22.   
  23.     push    bp   
  24.     mov bp,sp   
  25.     push    ax   
  26.     push    bx   
  27.     push    cx   
  28.     push    dx   
  29.        
  30.     push    bx                      ;暂存缓冲区偏移   
  31.     mov ax,[bp + 6]                 ;取得要读取的扇区数   
  32.     push    ax                      ;暂时保存之   
  33.     mov ax,[bp + 4]                 ;取得要读的逻辑扇区号   
  34.     mov bl,18      
  35.     div bl                          ;除以每柱面扇区数   
  36.     mov ch,al                                  
  37.     shr ch,1                        ;ch<-柱面号   
  38.     mov dh,al   
  39.     and dh,1                        ;dh<-磁头号   
  40.     mov cl,ah   
  41.     inc cl                          ;cl<-相对扇区号   
  42.     mov dl,0                        ;读A盘   
  43.     pop ax                          ;al<-要读的扇区数   
  44.     pop bx                          ;恢复缓冲区偏移   
  45.        
  46. .Go_On_Reading:   
  47.     mov ah,2                        ;ah<-功能号   
  48.     int 13h   
  49.     jc  .Go_On_Reading              ;如果cf=1,继续读   
  50.        
  51.     pop dx   
  52.     pop cx   
  53.     pop bx   
  54.     pop ax   
  55.        
  56.     pop bp   
  57.     ret   
  58. ;------------------------------------------------------------------Get_FAT_Entry   
  59. Get_FAT_Entry:   
  60. ;C函数原型(实模式下调用,短调用):   
  61. ;u16 Get_FAT_Entry(u16 Sector_No_In_Data_Area);   
  62. ;功能:   
  63. ;入口参数为数据区的相对扇区号,返回值为相应的FAT的值,以表示还有没有下一个扇区   
  64. ;ds指向数据区,在此函数中,es:bx=9000h-100h:0用来作为读FAT的缓冲区   
  65.     push    bp   
  66.     mov bp,sp   
  67.   
  68.     push    bx   
  69.     push    dx   
  70.     push    es   
  71.        
  72.     mov byte [_b_Is_Odd],0      ;作用为局部变量,标记相对FAT的条目索引   
  73.        
  74.     ;es指向9000h-100h   
  75.     mov ax,Base_Of_Loader   
  76.     sub ax,100h   
  77.     mov es,ax   
  78.        
  79.     ;1个FAT条目为12位,条目索引*3/2 = *1.5   
  80.     ;ax为相对FAT字节偏移   
  81.     mov ax,[bp + 4]   
  82.     mov bx,3   
  83.     mul bx   
  84.     mov bx,2   
  85.     div bx   
  86.        
  87.     ;判断余数是否为0,是的话为偶,跳转到   
  88.     ;对应标号,否的话把标记变量置1   
  89.     cmp dx,0   
  90.     je  LABEL_EVEN   
  91.     mov byte [_b_Is_Odd],1   
  92.        
  93. LABEL_EVEN:   
  94.     ;ax=当前条目在FAT的相对逻辑偏移扇区   
  95.     ;dx=当前条目相对当前扇区的字节偏移   
  96.     xor dx,dx   
  97.     mov bx,512   
  98.     div bx   
  99.        
  100.     add ax,1                                ;ax自增1,求得相对整个软盘的逻辑扇区偏移   
  101.        
  102.     ;读2个FAT扇区到缓冲区,一次读2个,   
  103.     ;因为FAT条目可能跨越2个扇区   
  104.     xor bx,bx   
  105.     push    2   
  106.     push    ax   
  107.     call    Read_Sector   
  108.     add sp,4   
  109.   
  110.     mov bx,dx                               ;es:bx指向要求的条目首字节   
  111.     mov ax,[es:bx]                          ;把首字节存到ax   
  112.     cmp byte [_b_Is_Odd],1                  ;判断奇偶,奇偶有不同的处理方式   
  113.     jne LABEL_EVEN2   
  114.     shr ax,4                                ;奇数的处理方式   
  115.        
  116. LABEL_EVEN2:                                ;偶数的处理方式   
  117.     and ax,0fffh                            ;返回值放到ax中   
  118.        
  119. LABEL_DONE:   
  120.     pop es   
  121.     pop dx   
  122.     pop bx   
  123.   
  124.     pop bp   
  125.     ret   
  126. ;----------------------------------------------------------Disp_Str_In_Real_Mode   
  127. Disp_Str_In_Real_Mode:   
  128. ;C函数原型(实模式下调用,短调用):   
  129. ;void Disp_Str_In_Real_Mode(const char *p_sz_Str);   
  130. ;注意:   
  131. ;在变量_w_Disp_Pos处显示字符串,ds指向数据区,es的值在此函数中指向数据区   
  132.     push    bp   
  133.     mov bp,sp   
  134.        
  135.     push    ax   
  136.     push    bx   
  137.     push    cx   
  138.     push    dx   
  139.     push    di   
  140.     push    es   
  141.        
  142. ;此BIOS中断API   
  143. ;功能13H    
  144. ;功能描述:在Teletype模式下显示字符串   
  145. ;入口参数:AH=13H   
  146. ;BH=页码   
  147. ;BL=属性(若AL=00H或01H)   
  148. ;CX=显示字符串长度   
  149. ;(DH、DL)=坐标(行、列)   
  150. ;ES:BP=显示字符串的地址 AL=显示输出方式   
  151. ;0——字符串中只含显示字符,其显示属性在BL中。显示后,光标位置不变   
  152. ;1——字符串中只含显示字符,其显示属性在BL中。显示后,光标位置改变   
  153. ;2——字符串中含显示字符和显示属性。显示后,光标位置不变   
  154. ;3——字符串中含显示字符和显示属性。显示后,光标位置改变   
  155. ;出口参数:无   
  156.   
  157.     mov ax,ds   
  158.     mov es,ax      
  159.     mov bp,[bp + 4]                     ;取得要打印的字符串指针   
  160.        
  161.     mov al,[es:bp]   
  162.     cmp al,0ah   
  163.     jne .3   
  164.     mov ax,[_w_Disp_Pos_In_RM]   
  165.     mov bl,80   
  166.     div bl   
  167.     inc al   
  168.     mul bl   
  169.     mov [_w_Disp_Pos_In_RM],ax   
  170.     jmp .4   
  171.        
  172. .3:    
  173.     mov ax,[_w_Disp_Pos_In_RM];得到显示地址   
  174.     mov bl,80   
  175.     div bl   
  176.     mov dh,al                           ;dh<-行号   
  177.     mov dl,ah                           ;dl<-列号   
  178.        
  179.     xor cx,cx                           ;字符串长度计数器   
  180.     mov di,bp                           ;做临时指针es:di指向字符串   
  181.        
  182. .1:   
  183.     mov al,byte [es:di]   
  184.     cmp al,0                            ;遇到0计数结束   
  185.     je  .2   
  186.     inc cx                              ;计数器自增1   
  187.     inc di                              ;临时指针自增1   
  188.     jmp .1   
  189.   
  190. .2:   
  191.     add word [_w_Disp_Pos_In_RM],cx ;显示地址加上字符串长度   
  192.     mov bx,0007h                        ;bh表示第0页,bl表示字符颜色   
  193.     mov ax,1301h                        ;al为输出方式1   
  194.        
  195.     int 10h   
  196.        
  197. .4:   
  198.     pop es   
  199.     pop di   
  200.     pop dx   
  201.     pop cx   
  202.     pop bx   
  203.     pop ax   
  204.        
  205.     pop bp   
  206.     ret   
  207.        
  208. ;---------------------------------------------------------------------Kill_Motor   
  209. Kill_Motor:   
  210. ;C函数原型(实模式下调用,短调用):   
  211. ;void Kill_Motor();   
  212. ;功能:   
  213. ;如名字所示,以免马达灯长亮   
  214.     push    ax   
  215.     push    dx   
  216.        
  217.     mov dx,03f2h   
  218.     mov al,0   
  219.     out dx,al   
  220.        
  221.     pop dx   
  222.     pop ax   
  223.   
  224.     ret   
  225.       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值