美文网首页
引导启动程序之bootsect.s

引导启动程序之bootsect.s

作者: 1f706595a1cd | 来源:发表于2018-12-01 20:36 被阅读0次

    1. P52,47~56

    start :
        mov ax, #BOOTSEG             
        mov ds, ax
        mov ax, #INITSEG
        mov es, ax
        mov cx, #256
        sub si, si
        sub di, di
        rep               !  重复执行它的下一条语句movw,直到cx中的数值为0。这里是循环执行256次
        movw              !  以字节为单位,从源地址往目的地址搬移数据,si、di自增
        jmpi go,INITSEG   !  jmpi--段间跳转指令,CS = INITSEG,IP = go,即跳转到INITSEG:go处执行
    

    标志寄存器EFlags

    方向标志DF(Direction Flag),用于决定执行完一次串操作之后,变址寄存器ESI/EDI是加还是减

    • DF=0,自加
    • DF=1,自减

    串操作

    • 取串(LODS),存串(STOS)、移串(MOVS)
    • 可以按照字节(B)、字(W)、双字(D)进行数据处理,

    2. P53,62

    扇区

    一个扇区是512byte,setup 程序大约为 4 个扇区

    段地址+偏移地址

    • x86处理器地址总线是20位,而内部数据总线、寄存器都是16位的。
    • 如何用16位寄存器表示20位?物理地址=段地址 << 4 + 偏移地址
    • eg
      ss = 0x9000,sp=0xff00,那么sp指向的地址是0x90000 + 0xff00 = 0x9ff00

    3. P53,67

    INT 0x13 磁盘服务程序
    • 功能号0x00, 复位驱动器

      AH = 0X00,DL = 需要复位的驱动器号。

    • 功能号0x02, 读磁盘扇区到内存

      AH = 0x02,AL = 需要读出的扇区数量;
      CH = 磁道(柱面)号的低 8 位; CL = 开始扇区(0-5 位),磁道号高 2 位(6-7);
      DH = 磁头号; DL = 驱动器号(如果是硬盘则位 7 要置位);
      es:bx 指向数据缓冲区; 如果读取失败则 CF 标志置位

      返回信息

      传输成功:CF=0,AH=00H,AL=传输的扇区数
      传输失败:CF=1,AH=状态代码(见下表)

    01H — 非法命令 02H — 地址目标未发现 03H — 磁盘写保护(软盘) 05H — 复位失败(硬盘)
    06H — 软盘取出(软盘) 07H — 错误的参数表(硬盘) 08H — DMA越界(软盘) 09H — DMA超过64K界限
    0AH — 错误的扇区标志(硬盘) 0BH — 错误的磁道标志(硬盘) 0CH — 介质类型未发现(软盘) 0DH — 格式化时非法扇区号(硬盘)
    0EH — 控制数据地址目标被发现(硬盘) 0FH — DMA仲裁越界(硬盘) 10H — 不正确的CRC或ECC编码 11H — ECC校正数据错(硬盘)
    20H — 控制器失败 40H — 查找失败 80H — 磁盘超时(未响应) AAH — 驱动器未准备好(硬盘)
    BBH — 未定义的错误(硬盘) CCH — 写错误(硬盘) E0H — 状态寄存器错(硬盘) FFH — 检测操作失败(硬盘)
    • 功能号0x08,读取磁盘驱动器参数
      AH = 0x08,DL = 驱动器号(如果是硬盘则要置位 7 为 1)
      返回信息

      如果出错则 CF 置位,并且 AH = 状态码。
      AH = 0, AL = 0
      BL = 驱动器类型(AT/PS2)
      CH = 最大磁道号的低 8 位,CL = 每磁道最大扇区数(位 0-5),最大磁道号高 2 位(位 6-7)
      DH = 最大磁头数,DL = 驱动器数量
      es:di 软驱磁盘参数表

    4. P54,92~102

    INT 0x10

    CSDN

    由 BIOS 对屏幕及显示器所提供的服务程序

        ! Print some inane message
        mov ah, #0x03       ! read cursor pos,AH=0x03,读取光标,为了获取光标当前的行列
        xor bh, bh           !bh = 页号
        int 0x10               
        
        mov cx, #24
        mov bx, #0x0007     ! page 0, attribute 7 (normal)
        mov bp, #msg1
        mov ax, #0x1301     ! write string, move cursor
        int 0x10
    

    读取光标是必要的,为了获取光标位置(DH、DL)

    • AH=3,读光标位置

      BH = 页号
      CH = 光标开始行
      CL = 光标结束行
      DH = 行
      DL = 列

    • AH=13,表示显示字符串

      ES:BP = 串地址
      CX = 串长度
      DH, DL = 起始行列
      BH = 页号
      BL = 07H,正常的黑底白字

    P55,151~155

    read_it:
        mov ax, es
        test ax, #0x0fff
    die:    jne die         ! es must be at 64kB boundary
        xor bx, bx         ! bx is starting address within segment
    

    test指令

    • test的解释( Intel技术手册)

    TEMP ← SRC1 AND SRC2 ;
      SF ← MSB(TEMP) ;
    IF TEMP = 0
      THEN ZF ← 1 ;
      ELSE ZF ← 0 ;
      FI:
      PF ← BitwiseXNOR(TEMP[0:7]);
      CF ← 0 ;
      OF ← 0 ;

    • 对代码的解释
      • test是进行位与操作,相与等于0,说明ax=es=0x1000,ZF=1
      • JNE/JNZ都是ZF标志位为0时跳转,如果es在64kb处,则顺序执行;否则,死锁

    子程序151~218

    实现功能

    该子程序将系统模块加载到内存地址 0x10000 处,并确定没有跨越 64KB 的内存边界。我们试图尽快 地进行加载,只要可能,就每次加载整条磁道的数据

    执行流程

    • read_it

      • 检测读入的数据是否在内存地址64kB处
      • 是,则执行rp_read;否,则死锁
    • rp_read

      • 首先判断是否已经读完
      • 是,返回调用处;否,执行ok1_read
    • ok1_read

      • 取当前磁道的扇区数,计算是否超过64kB
      • 是,计算能读取的最大值;否,执行ok2_read
    • ok2_read

      • 执行读取操作(跳转到了read_track)
      • 传输的扇区数存储在AL中,判断是否已经读完当前磁道的所有扇区
      • 是,顺序执行,如果当前磁道是0,则磁道号+1,执行ok4_read;如果磁道号是1,则直接跳转到ok4_read;否,执行ok3_read
    • ok3_read

      • 计算当前已读扇区数量,将读取位置存储在bx中
      • 跳转到rp_read,继续读取
    • ok4_read

      • 保存磁道号,清空ax
      • 如果未读完,进入ok3_read;否则,调整基址跳转到rp_read
    • read_track

      • 对通用 寄存器压栈保护
      • 设置要读取的驱动器号、磁道号、扇区,然后调用INT 0x13软件中断
      • 调用正确,返回调用处;否则,执行bad_rt,驱动器复位,然后重新跳转执行read_track
    • kill_motor

      关闭软驱的马达,这样我们进入内核后它处于已知状态,以后也就无须担心它了

    子程序执行流图

    8086寄存器

    数据寄存器

    • AX (Accumulator):累加寄存器,也称之为累加器;
    • BX (Base):基地址寄存器;
    • CX (Count):计数器寄存器;
    • DX (Data):数据寄存器;

    指针寄存器

    • SP (Stack Pointer):堆栈指针寄存器;
    • BP (Base Pointer):基指针寄存器;

    变址寄存器

    • SI (Source Index):源变址寄存器
    • DI (Destination Index):目的变址寄存器;

    控制寄存器

    • IP (Instruction Pointer):指令指针寄存器;
    • FLAG:标志寄存器;

    段寄存器:

    • CS (Code Segment):代码段寄存器;
    • DS (Data Segment):数据段寄存器;
    • SS (Stack Segment):堆栈段寄存器;
    • ES (Extra Segment):附加段寄存器

    相关文章

      网友评论

          本文标题:引导启动程序之bootsect.s

          本文链接:https://www.haomeiwen.com/subject/oiwrcqtx.html