bootsect.S框架基础级分析

本篇内容:

  •       8086处理器执行指令原理
  •       本程序相关as86汇编基础
  •       bootsect.S分析
===============================================
1   8086处理器执行指令过程
 1.0 相关概念:

   >内存单元的物理地址:
    所有内存单元构成的存储空间是一个一维的线性空间,每一个单元都有一个唯一的地址即单元的物理地址。
   >CPU(8086)内部形成物理地址的方式:
     公式:物理地址=段地址 X 16 + 偏移地址
     原理: CPU相关部件提供两个16位的地址:段地址和偏移地址,地址加法器将
         两个16位地址合成一个20位的物理地址;物理地址将被送上地址总线到达存储器;
     地址加法器工作流程如图:
    
    >CS:IP
    CS: 代码段寄存器:存放段地址
    IP: 指令指针寄存器:存放偏移地址
    设任意时刻,CS中的内容为M,IP中的地址为N,8086CPU将从内存M*16+N单元开始,
    读取一条指令并执行。
 1.1 过程:
     <1> CPU从CS:IP指向的内存单元读取指令,读取的指令被送入指令缓冲器;
     <2> IP=IP+所读指令的长度,从而指向下一条指令;
     <3>执行指令,转到步骤<1>重复这个过程。
     
 2  本程序相关的as86汇编基础
  2.0 as86概念
    as86是8086..80386处理器下的汇编程序,它所采用的语法与Intel/MS采取的语法类似,而不同于广泛运用于UNIX下的汇编语法(译注,gas中的语法,AT&T汇编)  
 2.1 本程序部分指令/语法/基础器:  
     格式 ".xxx" 是伪操作符,具体作用与xxx有关
     例如:.txt 指定正文段开始位置
        .data 指定数据段开始位置
        .bss 指定未初始化数据段开始位置
        .org 定义当前汇编的位置,执行结果:将把当前的位置计数器值调为该伪操作符语句上给出的值
     格式 "AAA" 标识符,功能之一:可作常量
     例如: AAA = 123
     
     格式 "yyy:" 标号, 标号是"标识符+冒号"
     例如:.globl 作用为定义随后的标号是外部的或是全局的,并且即使不适用也强制引入(在引入时,标号无需带":")。
            .globl yyy begtext zzz
           其它时候需要带冒号":"
        例如:.txt
              begtext:
             
        数据格式:
        .ascii 写到输出的ASCII字符串(Ascii string copied to output.)
        .asciz 尾部带有一字节的nul(Ascii string copied to output with trailing nul byte.)
        .byte/ FCB/ DATA1/ DB 一字节的对象列表
        .word/ FDB/ DATA2/ DW 两字节的对象列表
        .LONG/ DATA4/ DD 四字节的对象列表
        部分指令:
        jmpi 段间跳转
        例如 jmpi go, BOOTSEG  !即CS = BOOTSEG, IP = go  (标号go是偏移地址)
        int 中断调用
        int 0x10  !使用BIOS功能19子功能1,作用显示一字符串到屏幕指定位置
        寄存器:
        8086寄存器列表如下:
         
        ax bx cx dx 16位寄存器: 通用寄存器/数据寄存器
          ah ax的高8位,al ax的低8位   ah&al = ax
        bp (base pointer)基址指针寄存器
        sp (stack pointer) 堆栈指针寄存器
        cs (Code Segment)段寄存器
        ds (Data Segment)数据段寄存器
        es (Extra Segment)附加段寄存器
        ss (Stack Segment)堆栈段寄存器
       
        显示一行字符串可能用到的寄存器:
         cx,dx,bx,ax :用于指定字符串的字符串长度/显示位置/字符属性/光标位置
        bp :指定要显示的字符串
      
       
 3 bootsect.S分析
  !boot.s/bootsect.s 是磁盘引导程序,驻留在第一个扇区(引导扇区,0磁道 , 0磁头 第一个扇区)。
  !在PC机加电ROM BIOS 加电自检后,ROM BIOS 会将boot.s 或者bootsect.s 加载到0x7c00开始处,并且开始运行。
!感叹号用于注释
!此代码段功能:用0x07替换字符串msg的第18个字符,然后在屏幕指定位置显示。
!为什么把操作系统的引导程序加载到0x7c00处:
!BIOS就是将MBR读入0x7C00地址,然后进行后续的引导的。
!操作系统或是bootloader开发者必须假设 他们的汇编代码被加载并从0x7C00处开始执行       
.globl begtext,begdata,begdata,begbss,endtext,enddata,endbss
.text !正文段
begtext: !在正文段定义一个标号begtext
.data !数据段
begdata: !在数据段定义一个标号begdata
.bss !未初始化数据段
begbss: !在未初始化数据段定义一个标号begbss
.text  !正文段
BOOTSEG = 0x7c0 !BIOS加载原始段地址,根据以上公式推算,
!要跳到物理地址0x7c00, CS 须是:0x7c0 (理由:0x07c00 + 0x0000 = 0x07c00)
entry start    !告知链接程序,程序从start标号处开始执行。 boot/bootsect.S与boot/setup.s可以省略
!因为我们并不希望在生成的纯二进制执行文件包含任何符号信息
start:
 jmpi go,BOOTSEG !跳转到CS=BOOTSEG,IP=go处执行,其实就是go处
go: mov ax,cs  !初始化ds,es ,设为cs便于对程序中的数据进行寻址
  mov ds,ax
  mov es,ax
  mov [msg1+17],ah  !替换字符
  mov cx, #20 !显示字符总数
  mov dx, #0x1004 !显示位置:第17行第5列
  mov bx, #0x000c !显示字符属性:红色
  mov bp, #msg !指向要显示的字符串(中断调用要求,个人猜测:0x10中断会判断bp是否为空,bp实际就是字符串首地址)
  mov ax, #0x1301 !跳转光标到某处
  int 0x10 !BIOS调用字符串显示中断
loop0: jmp loop0 !死循环,不退出程序
msg1: .ascii "Loading system ..." !18个字符
      .byte 13,10  !再补充两个字符:一个回车一个换行(ASCII)
      .ascii "Marry Chritmas"
      .byte 13,10
.org 510   !定义当前的位置计数器为510
   .word 0xAA55   !再写两个字节,正好512 bytes(一个扇区的大小)
.text    !表示代码段的结束位置
endtext:
.data   !表示数据段的结束位置
enddata:
.bss      !表示未初始化数据段的结束位置
endbss:   
             
附图:window 10和RedHat Enterprise Linux 5运行bochs成功的图片
windows


linux:

我在bochs配置遇到不少问题(Linux下),可能会找时间分享。

参考与引用:

      《Linux内核完全剖析-基于0.12内核》--- 赵炯

CSDN博客:

"as86汇编语言" --- AstrayLinux

"CPU如何执行指令(CS/IP)" --- zhliao





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值