鱼C论坛

 找回密码
 立即注册
查看: 3149|回复: 0

[学习笔记] X86汇编语言-从实模式到保护模式—笔记(3)

[复制链接]
发表于 2017-10-25 21:17:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 兰陵月 于 2017-12-5 21:56 编辑

第2部分  实模式
第5章  编写主引导扇区代码
5.1  本章代码清单
(略)
5.2  欢迎来到主引导扇区
处理器加电或者复位后,如果硬盘是首选的启动设备,那么,ROM-BIOS将试图读取硬盘的0面0道1扇区。传统上,这就是主引导扇区(Main Boot Sector,MBR)
读取的主引导扇区数据有512字节,ROM-BIOS程序将它加载到逻辑地址0x0000:0x7c00处,也就是物理地址0x07c00处,然后判断它是否有效。
一个有效的主引导扇区,其最后两字节应当是0x55和0xAA。ROM-BIOS程序首先检测这两个标志,如果主引导扇区有效,则以一个段间转移指令jmp 0x0000:0x7c00跳到那里继续执行。
一般来说,主引导扇区是由操作系统负责的。
5.3  注释
注释必须以英文字母“;”开始。
5.4  在屏幕上显示文字
【5.4.1 显卡和显存】
为了显示文字,通常需要两种硬件,一是显示器,二是显卡。
显卡的职责是为显示器提供内容,并控制显示器的显示模式和状态,显示器的职责是将那些内容以视觉可见的方式呈现在屏幕上。
显卡控制显示器的最小单位是像素,一个像素对应着屏幕上的一个点。屏幕上通常有数十万乃至更多的像素,通过控制每个像素的明暗和颜色,我们就能让这大量的像素形成文字和美丽的图像。
显卡都有自己的存储器,因为它位于显卡上,故称显示存储器(Video RAM,VRAM)。
图形模式中,最流行的是用24个比特,即3个字节来对应一个像素。因为224=16777216,所以在这种模式下,同屏可以显示16777216种颜色,这称为真彩色。
专门用于显示字符的工作方式称为文本模式。文本模式图形模式是显卡的两种基本工作模式,可以用指令访问显卡,设置它的显示模式。在不同的工作模式下,显卡对显存内容的解释是不同的。
由于历史的原因,所有在个人计算机上使用的显卡,在加电自检之后都会把自己初始化到80×25的文本模式,这种模式下,屏幕上可以显示25行,每行80个字符,每屏总共2000个字符。
0XB8000~0xBFFFF这段物理地址空间,是留给显卡的,有显卡来提供,用来显示文本。
【5.4.2 初始化段寄存器】
显存地址一般为:
0xB800:0x0000~0xB800:0x7FFF
文本模式下的显示缓冲区不过32KB。一般用ES来段寄存器访问显存。
Intel处理器不允许将一个立即数传送到段寄存器。
【5.4.3 显存的访问和ASCII代码】
在计算机中,每个用来显示在屏幕上的字符,都有一个二进制代码。这些代码和普通的二进制数字没有什么不同,唯一的区别在于,发送这些数字的硬件和接收这些数字的硬件把它们解释为字符,而不是指令或者用于计算的数字。
这就是说,在计算机中,所有的东西都是无差别的数字,它们的意义,只取决于生成者和使用者之间的约定。
为了在终端和大型主机,以及主机和打印机、显示器之间交换信息,1967年,美国国家标准学会制定了美国信息交换标准代码(ASCII)。
ASCII是7位代码,只用了一个字节的低7比特,最高位通常置0。这意味着,ASCII只包含128个字符的编码。
屏幕上每个字符对应着显存中的两个连续字节,前一个字节是字符的ASCII代码,后面1个字节是字符的显示属性,包括字符颜色(前景色,低4位)和底色(背景色,高4位)。
【5.4.4 显示字符】
为了方便,多数汇编语言编译器允许在指令中直接使用字符的字面值来代替数值形式的ASCII码,这个字面值必须用单引号括起来。在源程序的编译阶段,汇编语言编译器会将它转换成ASCII码的形式。
访问内存单元,必须给出段地址和偏移地址。没有段前缀的,统一默认为DS段。
内存地址的必须用方括号括起来,表示这是一个地址。
【5.4.5 MOV指令的格式】
起始地址:0xB8000,对应的段地址:0xB800,偏移量为0x0F9E,连续写入0x48、0x27
【5.5.1 标号】
处理器访问内存时,采用的是“段地址:偏移地址”的模式。对于任何一个内存段来说,段地址可以开始于任何16字节对齐的地方,偏移地址则总是从0x0000开始递增。
汇编地址是在源程序编译期间,编译器为每条指令确定的汇编位置,指示该指令相对于程序或段起始处的距离,以字节计。当编译后的程序装入物理内存后,它又是该指令在内存段内的偏移地址。当编译好的程序加载到物理内存后,它的每一句指令在段内的偏移地址和它在编译阶段的汇编地址是相同的。
在NASM汇编语言里,每条指令的前面都可以拥有一个标号,以代表和指示该指令的汇编地址。毕竟,由我们自己来计算和跟踪每条指令所在的汇编地址是极其困难的。
标号之后的冒号是可选的。
标号并不是必须的,只有在我们需要引用某条指令的汇编地址时,才使用标号。
标号可以单独占用一行的位置。
标号可以由字母、数字、“_”、“$”、“#”、“@”、“~”、“.”、“?”组成,但必须以字母、“.”、“_”和“?”中的任意一个打头。
【5.5.2 如何显示十进制数字】
标号代表并指示它所在位置处的汇编地址。
以mov ax,number为例,传送到寄存器ax的值是在源程序编译时确定的,在编译阶段,编译器会将标号number转换成立即数。问题在于,如果不是借助于别的工具和手段,我们不可能知道此处的汇编地址是0x012E,所以,在汇编语言中使用标号的好处是不必关心这些。
要在屏幕上显示某个数字,可以用这个数字不停地除以10,直到商为0为止,然后把每次的余数反向组合在一起,就可以了。当然要在屏幕上显示的话,必须将每次的余数加上0x30,这样就是余数的ASCII代码,这样就能在屏幕上显示了。
【5.5.3 在程序中声明并初始化数据】
DB用来声明字节数据,DW用来声明字数据,DD用来声明双字数据,DQ用来声明四字数据。DB、DW、DD、DQ并不是处理器指令,它只是编译器提供的汇编指令,所以称作伪指令。伪指令是汇编指令的一种,它没有对应的机器指令,所以它不是机器指令的助记符,仅仅在编译阶段由编译器执行,编译成功后,伪指令消失了,所以在程序执行时,伪指令是得不到处理器光顾的,实际上,程序执行时,伪指令已不存在。
声明的数据可以是任何值,只要不超过伪指令所指示的大小。
和指令不同,对于在程序中声明的数值,在编译阶段,编译器会在它们被声明的汇编地址处原样保留。
声明数据时,如果数据超过所指示的大小,则实际编译时只取低位同等长度。如果数据小于所指示的大小,则实际编译时在高位取0补齐。
【5.5.4 分解数的各个数位】
除法指令div的两种除法
第一种:用16位的二进制数除以8位的二进制数。在这种情况下,被除数必须在寄存器AX中,必须事先传送到AX寄存器里。除数可以由8位的通用寄存器或者内存单元提供。指令执行后,商在寄存器AL中,余数在寄存器AH中。
任何时候,只要是在指令中涉及内存地址的,都允许使用段超越前缀。
还可以用标号来代替被除数和除数的汇编地址。
第二种:用32位的二进制数除以16位的二进制数。在这种情况下,因为16位的处理器无法直接提供32位的被除数,故要求被除数的高16位在DX中,低16位在AX中。除数可以由16位的通用寄存器或者内存单元提供,指令执行后,商在AX中,余数在DX中。
为什么要将余数存放到标号number处时,在实际程序中不是使用number+偏移,还需要加上0x7c00,是因为程序不是加载到0x0000:0x000处,而是加载到0x0000:0x7c00处,程序不是从偏移为0的地方开始的,是从偏移为0x7c00的地方开始的,但程序在汇编的时候是默认程序开始的地方是偏移为0,因此,在编写的时候就需要人为加上这个偏移差,也就是0x7c00。
xor异或指令。其目的操作数可以是通用寄存器和内存单元,源操作数可以是通用寄存器、内存单元和立即数(不允许两个操作数同时为内存单元)。而且,异或操作是在两个操作数相对应的比特之间单独进行的。一般情况来说,xor指令的两个操作数应当具有相同的数据宽度。
xor操作与mov操作的速度比较:mov dx,0的机器码为BA 00 00,有三个字节长,xor dx,dx的机器码为31 D2,长度只有两个字节,比mov指令短。而且xor操作是在两个通用寄存器之间进行,所以执行的速度会比较快。
【5.5.5 显示分解出来的各个数位】
add指令是加法指令,目的操作数可以是8位或者16位的通用寄存器,或者指向8位或者16位实际操作数的内存地址;源操作数可以是相同数据宽度的8位或者16位通用寄存器、指向8位或者16位实际操作数的内存地址,或者立即数,但不允许两个操作数同时为内存单元。相加后,结果保存在目的操作数中。
200D
0X0030
90230
5.8  加载和运行主引导扇区代码
【5.8.1 把编译后的指令写入主引导扇区】
【5.8.2 启动虚拟机观察运行结果】
5.9  程序的调试技术
【5.9.1 开源的Bochs虚拟机软件】
【5.9.2 Bochs下的程序调试入门】

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-25 00:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表