引导扇区汇编程序-操作系统

引导扇区汇编程序-操作系统

首先先看一个简单的例子,在显示屏上输出字符串。首先一个扇区是512字节。

org 07c00h          ; 告诉编译器程序加载到7c00处
    mov ax, cs
    mov ds, ax
    mov es, ax
    call    DispStr     ;调用显示字符串子程序
    jmp $               ; 无限循环
DispStr:
    mov ax, BootMessage
    mov bp, ax          ; 将字符串的首地址给堆栈指针bp
    mov cx, 16          ; 字符串长度传给cx寄存器
    mov ax, 01301h      ; AH = 13,  AL = 01h
    mov bx, 000ch       ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
    mov dl, 0
    int 10h             ; 10h号中断
    ret
BootMessage:        db  "Hello, OS world!"
times   510-($-$$)   db  0   ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw  0xaa55                   ; 结束标志

看上面这个例子,是不是还不是很清楚,我们现在详细的分析一下。
介绍一下代码中存在的寄存器:
十六位的通用寄存器:
AX――累加器(Accumulator),常用于存放算术、逻辑运算中的操作数或结果。另外,所有的I/O指令都要使用累加器与外设接口传道递数据
BX――基址寄存器(Base Register),常用来存放访问内存时的地址
CX――计数器(Count Register),常作为计数器,在循环、串操作指令中用作计数器
DX――数据寄存器(Data Register),存放数据,在寄存器间接寻址中的I/O指令中存放I/O端口的地址
当然AX、BX、CX、DX,都还可以分为高(H:High)、低(L:low)两个独立的8位寄存器,分别取名为AH / AL、BH / BL、CH / CL、DH / DL。
八位的通用寄存器:
SI――源变址寄存器(Source Index),常保存存储单元地址
DI――目的变址寄存器(Destination Index),常保存存储单元地址
BP――基址指针寄存器(Base Pointer),表示堆栈区域中的基地址
SP――堆栈指针寄存器(Stack Pointer),指示堆栈区域的栈顶地址
IP――指令指针寄存器(Instruction Pointer),指示要执行指令所在存储单元的地址。IP寄存器是一个专用寄存器。
然后我们逐句分析:

org 07c00h

org伪指令: org + 数值表达式;即org语句后的指令或数据以数值表达式给出的值作为起始的偏移地址。数值表达式必须是一个可计算得到的正整数,数值范围在0~65535之间。BIOS将相应启动设备的第一个扇区(也就是MBR扇区)读入内存地址为0000:7C00H 处。

    mov ax, cs
    mov ds, ax
    mov es, ax

cs 为代码段寄存器,一般用于存放代码;ds 为数据段寄存器,一般用于存放数据;es 为扩展段寄存器;这一操作使cs=ds=es,令各个段,处于一个相同的 64K 存储器空间,集中在一起,便于处理代码和数据。这等于是写引导程序的初始化阶段。

    call    DispStr  
    jmp $               

以调用子程序的方式操作。$被称为当前位置计数器,在汇编程序对源程序进行汇编的过程中,使用地址计数器来保证当前正在汇编的指令地址,一直在当前跳转,即在当前无限循环。
接下来看子程序:DispStr

    mov ax, BootMessage
    mov bp, ax          
    mov cx, 16         
    mov ax, 01301h      
    mov bx, 000ch      
    mov dl, 0
    int 10h           
    ret

将字符串首地址给ax,然后通过ax将字符串首地址给堆栈指针bp。在汇编中,不能直接将立即数直接传给段寄存器(bp作为堆栈指针在段寄存器ss中–ss是堆栈段寄存器),而这边字符串的首地址即等于立即数。接下来将字符数传给cx(计数器寄存器)。然后就是比较难的几句了,有关于中断,暂时简单理解,从代码中看出是int 10h中断,是由BIOS对显示器和屏幕所提供的服务程序。想要详细了解10h中断的可看:int 10h中断详解
mov ax, 01301h :寄存器ax分为ah,al,在此中ah=13h,查阅可知13h表示写字符串。
以下是我查阅的:
在这里插入图片描述
由此可见:al=01h,表示写完字符串后,光标位置。设置好ax,然后设置bx,000ch,由此上表可见,bh=页号,此处为0。bl=0ch,bl表示属性,属性即字符的颜色、背景颜色、是否闪烁、有没有底线等性质。在彩色显示中,通常以第 0~3 位表示文字本身颜色;第 4~6 位表示背景颜色,背景颜色只有上表左栏的 8 种而已;第 7 个位,表示是否闪烁,0 表示不闪烁,1 表示闪烁。查表可知:0c表示黑底红色(实际是淡红色),然后mov dl, 0
由上表可知,dh=行号,dl=列号,所以此处字符串从第0列开始显示。最后设置好这些后,才可以调用int 10h。ret :子程序返回指令,也就是子程序返回。

BootMessage:        db  "Hello, OS world!"
times   510-($-$$)   db  0   
dw  0xaa55                   

最后:BootMessage:伪指令,db “Hello, OS world!”:db定义字节类型变量,一个字节数据占1个字节单元。即占16个字节单元。表示要显示的字符串。times:重复指令或数据,$$:表示一个节(一段代码)的开始处被汇编后的地址。

$-$$:经常被用到,表示本行距离程序开始处的相对距离
times   510-($-$$)   db  0   

就是将剩下的512剩下的空间用0填充。为什么边是510,是因为最后还有引导扇区结束符代码,占两字节。在hex可查看知中扇区结束标志为0x55aa,由于dw是低端序存放,在汇编代码中为0xaa55。dw定义字类型变量,一个字数据占2个字节单元,读完一个,偏移量加2。

最后,这篇博客我写了很久,基于对汇编语言,寄存器等的不熟,又源于老师上课讲的不够详细,所以我查看了很多博客,资料,才写了这篇博客,也供我自己学习
以下是我参考的一些资料:
汇编代码解释合集
自己动手写操作系统(一)
颜色搭配显示+BIOS功能调用表+INT 10H功能详细列表
int 10中断

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chrisyyl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值