x86汇编语言学习:第五章 编写主引导扇区代码

《x86汇编语言从实模式到保护模式》的第五章,编写主引导扇区代码。

5.1 欢迎来到主引导扇区

  • 主引导扇区位置(MBR):0面0道1扇区
  • 主引导扇区有512字节,一个有效的主引导扇区的最后两字节为0x55和0xAA
  • ROM-BIOS程序将它加载到逻辑地址0x0000:0x7c00处,也就是物理地址0x7c00,然后判断它是否有效

    5.3 注释

  • 注释必须以英文“;”开始

5.4 在屏幕上显示文字

5.4.1 显卡和显存
  • 显卡为显示器提供内容,并控制显示器的显示模式和状态
  • 显存存储着每个像素的特性,现在流行24个bit对应一个像素
  • 屏幕上的每个字符对应着显存中的两个连续字节,前一个是字符ASCII码,后一个是字符的显示属性,包括字符的颜色(前景色)和底色(背景色);

图一、8bit的字符显示属性

图二、80x25文本模式下的颜色表

5.4.2 MOV指令语法

mov byte [es:0x09],0x07

[es:0x09]:目的内存地址

0x07:源,立即数

byte:修饰,由于源和目的数据的大小均未知,故用byte来修饰

mov ax, [0xf000]
;处理器将0xf000作为偏移地址,去访问数据段(段地址在段寄存器DS中),来取得内存中的一个字0x3F0,并把它传送到寄存器AX中

mov [bx], dl
;在8086处理器上,如果用寄存器来提供偏移地址的话,只能使用BX、SI、DI、BP,不能使用其他寄存器

5.5 显示标号的汇编地址

5.5.1 标号

在NASM汇编语言中,每一条指令的前面都可以拥有一个标号,以代表和指示该指令的汇编地址。例如:

infi: jmp near infi

(冒号可以省略)

5.5.2 初始化数据

DB:Declare Database,声明字节,所以跟在它后面的的操作数都占一个字节的长度,如果要声明超过一个以上的数据,各个操作数之间必须用逗号隔开

DW:Declare Word

DD:Declare Double Word

DQ:Declare Quad Word

例子:numbers db 0,0,0,0,0

numbers db 0,0,0,0,0
message db '1+2+3+...+100='
;这种声明方式也是可以的,编译器会在编译阶段将它们拆开,形成一个一个字节
5.5.3 div除法指令

有两种用法

  • 16位的二进制数除以8位的二进制数 被除数  :放在寄存器AX中

除数   :由8位的通用寄存器或者内存单元提供

商    :在寄存器AL中

余数   :在寄存器AH中

例子:

div cl
div byte [0x0023]
  • 32位二进制数除以16位二进制数 被除数  :高16位在DX中,低16位在AX中

除数   :由16位的通用寄存器或者内存单元提供

商    :在寄存器AX中

余数   :寄存器DX中

例子:

div cx 
div word [0x0230]
5.5.4 xor异或指令
  • 目的操作数 :通用寄存器和内存单元
  • 源操作数  :通用寄存器、内存单元和立即操作数
  • 异或的作用可以用来进行寄存器的清零
    xor dx, dx   ;将dx寄存器清0
    

    例子:

    mov ax 0000_0000_0000_0010B
    xor ax 1111_0000_1111_0001B  &emsp;&emsp;; AX<- 1111_0000_1111_0011B,即 0xf0f3
    

    5.6 使程序进入无限循环

    infi: jmp near infi
    

    关键字near表示目标位置依然在当前代码段 (思考题:为什么上面的代码不是jmp near 0x7c00+infi?)

5.6.1 jmp指令的多种格式
  • 绝对地址
    jmp 0x5000:0xf0c0
    
  • 相对地址
    jmp near infi
    

    如果jmp后面的是绝对地址,编译器就把jmp编译成使用操作码为0xEA的直接绝对转移指令;如果jmp后面的是一个标号,它就会被编译成使用操作码为0xE9的相对转移指令。

5.7 完成并编译主引导扇区的代码

5.7.1 主引导扇区有效标志

一个有效的主引导扇区,其最后两个字节的数据必须是0x55和0xAA

  • times伪指令: 重复它后面的指令若干次
    times 20 mov ax, bx 
    ;编译时,重复生成mov ax, bx指令20次
    times 203 db 0
    ;编译时,保留203个为0的字节
    
    5.7.2 代码的保存和编译

    编译后,代码中的标号,伪指令,注释统统消失了,只剩下代表指令和数据的二进制数

    5.8 把编译后的指令写入主引导扇区

    5.9 程序的调试技术

    5.9.2 bochs程序调试入门
Share: X (Twitter) Facebook LinkedIn