亲宝软件园·资讯

展开

编写主引导扇区代码

放飞梦想C 人气:1
## 主引导扇区   处理器加电或者复位之后,如果硬盘是首选的启动设备,那么,ROM-BIOS将试图读取硬盘的0面0道1扇区。传统上,这就是**主引导扇区(Main Boot Sector,MBR)**。   读取主引导扇区数据有**512**字节,**ROM-BIOS**程序将它加载到逻辑地址**0x0000:0x7c00**处,也就是物理地址**0x07c00**处,然后判断它是否有效。   一个有效的主引导扇区,其最后两个字节应当是**0x55**和**0xAA**。**ROM-BIOS**程序首先检测这两个标志,如果主引导扇区有效,则以一个段间转移指令**jmp 0x0000:0x7c00**跳到那里继续执行。 ## 在屏幕上显示文字   如何在屏幕上显示字符。我们需要把数据写入到显存,用数据控制每个**像素**是亮,还是不亮。显存的数据的字节对应着屏幕上连续的8个像素,如果bit是0则不亮,如果是1则点亮对应的像素,要显示更多的颜色一个bit不够了。   如何在屏幕上显示出字符的形状。有这样一个标准,**美国信息交换代码标准(American Standard Code for Information Interchange)**。用特定的**ASCII**码代表字符,显卡在任何时候都认为你发送的是**ASCII**码。 ![ASCII码表](https://img-blog.csdnimg.cn/20200321112341219.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0NkcmVhbWZseQ==,size_16,color_FFFFFF,t_70)![ASCII码表](https://img-blog.csdnimg.cn/20200321112406926.PNG)   如何在屏幕上某个位置显示出字符。计算机在加电自检之后都会把自己初始化到**80×25**的文本模式。在这种模式下,屏幕上可以显示**25**行,每行**80**个字符,每屏总共**2000**个字符。考虑到文本模式下现存的起始物理地址是**0xB8000**,这块内存可以看成是段地址为**0xB800**,偏移地址从**0x0000**延伸到**0xFFFF**的区域,因此我们可以把段地址定为**0xB800**,通过段偏移定位到想显示的位置。   如何在屏幕上显示带颜色的字符。屏幕上的每个字符对应着显存中的两个连续字节,前一个是字符的**ASCII**码,后面是字符的显示属性,包括字符颜色(前景色)和底色(背景色)。字符的显示属性(1字节)分为两个不部分,低4位定义的是前景色,高4位定义的是背景色。色彩主要由**R,G,B** 这三位决定。 ![RGB](https://img-blog.csdnimg.cn/20200321112449947.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0NkcmVhbWZseQ==,size_16,color_FFFFFF,t_70#pic_center) ![RGB](https://img-blog.csdnimg.cn/2020032111250570.PNG#pic_center) ## 代码解析 ```c jmp near start ;跳转到标号代表并指示它所在位置处的汇编地址 text db 'H',0x07,'e',0x07,'l',0x07,'l',0x07,'o',0x07,\ ' ',0x07,'W',0x07,'o',0x07,'r',0x07,'l',0x07,'d',0x07 ;数据标号不仅仅表示内存单元的地址,还表示了内存单元的长度 ;db声明字节,它后面的操作数都占一个字节长度 ;\续行符表示下一行和当前行合并为一行 ;0x07 黑底白字,无闪烁,无加亮 start: ;标号代表并指示它所在位置处的汇编地址 mov ax,0x7c0 mov ds,ax ;数据段逻辑地址0x7c0为主引导起始地址 mov ax,0xb800 mov es,ax ;显存的逻辑段地址0xb800 cld ;清除方向标志DF置0,以表示正方向传送 mov si,text ;设置数据的地址 mov di,0 ;目的段偏移地址为0 mov cx,(start-text)/2 ;设置批量传送的字节数到CX寄存器,因为数据串是在两个标号之间声明的, ;除以2是每个显示的字符实际占两个字节,而movsw每次传送一个字 rep movsw ;movsw,操作码是0xA5,该指令没有操作数。使用movsw而不是movsb的原因是每次需要传送一个字(ASCII码和属性)。 ;单纯的movsb和movsw只能执行一次,如果希望处理器自动的反复执行,需要加上rep(repeat),意思是CX不为0则重复。 times 510-($-$$) db 0 ;伪指令times可用于重复它后面的指令若干次。 ;里面的$表示当前指令的地址,$$表示程序的起始地址0x7c00,所以$-$$就等于本条指令前的字节数, ;times 510-($-$$) db 0 为在填充一些数据共为510个字节, db 0x55,0xaa ;结束表示,整个段程序的大小正好为510字节,占满一个扇区。 ``` ![结果](https://img-blog.csdnimg.cn/20200321131500710.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0NkcmVhbWZseQ==,size_16,color_FFFFFF,t_70)

加载全部内容

相关教程
猜你喜欢
用户评论