代码清单5-1理解过程
1 ;代码清单5-1
2 ;文件名:c05_mbr.asm
3 ;文件说明:硬盘主引导扇区代码
4 ;创建日期:2011-3-31 21:15
5
前5行用于介绍文件信息
6 mov ax,0xb800 ;指向文本模式的显示缓冲区
将立即数 0xB800 传送到 AX
文本模式下显存的起始物理地址是 0xB8000
7 mov es,ax
将 AX 中的值 B800 传送到段寄存器 ES 中,使附加段寄存器 ES 就指向 0xb800 段(段基地址为 0xB800)。
Intel 的处理器不允许将一个立即数传送到段寄存器,所以只能先将一个立即数存入一个通用寄存器中,然后再由通用寄存器传送到段寄存器中。
即:立即数 → 通用寄存器 → 段寄存器;
8
9 ;以下显示字符串"Label offset:"
; 是用于写注释的,在 ; 之后的内容在编译时自动忽略
10 mov byte [es:0x00],‘L’
使用段超越前缀 “es:” ,即我们明确要求处理器在生成物理地址时,使用段寄存器 ES,而不是默认情况下的段寄存器 DS 。
多数汇编语言编译器允许在指令中直接使用字符的字面值来代替数值形式的 ASCII 码。
‘L’ 即将L转换为 0x4C ,然后以字节的方式存入[es:0x00]中; 0x4C作为字符的ASCII代码放入地址 0xB800:0x0000 中。
11 mov byte [es:0x01],0x07
0x07 是字符的显示属性;
0x07 的 二进制是 0000 0111,是黑底白字,无闪烁,无高亮。
详细的字符打印可移步至:东西还在审核中
12 mov byte [es:0x02],‘a’
13 mov byte [es:0x03],0x07
14 mov byte [es:0x04],‘b’
15 mov byte [es:0x05],0x07
16 mov byte [es:0x06],‘e’
17 mov byte [es:0x07],0x07
18 mov byte [es:0x08],‘l’
19 mov byte [es:0x09],0x07
20 mov byte [es:0x0a],’ ’
21 mov byte [es:0x0b],0x07
22 mov byte [es:0x0c],“o”
23 mov byte [es:0x0d],0x07
24 mov byte [es:0x0e],‘f’
25 mov byte [es:0x0f],0x07
26 mov byte [es:0x10],‘f’
27 mov byte [es:0x11],0x07
28 mov byte [es:0x12],‘s’
29 mov byte [es:0x13],0x07
30 mov byte [es:0x14],‘e’
31 mov byte [es:0x15],0x07
32 mov byte [es:0x16],‘t’
33 mov byte [es:0x17],0x07
34 mov byte [es:0x18],’:’
35 mov byte [es:0x19],0x07
36
从11~36行,其目的是为了将字符串"Label offset:"的显示代码放入显存中。
37 mov ax,number ;取得标号number的偏移地址
将 number 处的汇编地址传送到 AX 寄存器中;
number 是一个标号,表示的是第100行指令的汇编地址;
其代码是 100 number db 0,0,0,0,0
通用寄存器 AX 中的数值即number的偏移地址将被作为被除数;
38 mov bx,10
将 10 传送到通用寄存器 BX 中;
作为除数,方便后面作除法分位
39
40 ;设置数据段的基地址
41 mov cx,cs
42 mov ds,cx
把代码段寄存器 CS 的内容传送到通用寄存器 CX,然后再从 CX 传送到数据段寄存器 DS。
在此之后,数据段和代码段都指向同一个段。
之所以这么做,是因为我们刚才声明的数据是和指令代码混在一起的,可以认为是位于代码段中。尽管在指令中访问这些数据可以使用段超越前缀“CS:”,但习惯上,通过数据段来访问它们更自然一些。
43
44 ;求个位上的数字
45 mov dx,0
把 0 传送到 DX 寄存器,这意味着是想把 DX:AX 作为被除数,即被除数的高 16 位是全零。
46 div bx
进行32 位的二进制数除以16 位的二进制数的方法来进行除法运算。
除以 BX 的内容,执行后得到的商在 AX 中,余数在 DX 中。
47 mov [0x7c00+number+0x00],dl ;保存个位上的数字
因为除数是 10,余数自然比 10 小,可以从 DL 中取得余数。
余数就是最后面也是最右边的一位数;
主引导扇区代码是被加载到 0x0000:0x7C00 处的,而非 0x0000:0000。
主引导扇区地址 + number临时数据汇编地址 + 第几位数
48
49 ;求十位上的数字
50 xor dx,dx
使用异或符将通用寄存器 DX 中清零;
51 div bx
52 mov [0x7c00+number+0x01],dl ;保存十位上的数字
53
54 ;求百位上的数字
55 xor dx,dx
56 div bx
57 mov [0x7c00+number+0x02],dl ;保存百位上的数字
58
59 ;求千位上的数字
60 xor dx,dx
61 div bx
62 mov [0x7c00+number+0x03],dl ;保存千位上的数字
63
64 ;求万位上的数字
65 xor dx,dx
66 div bx
67 mov [0x7c00+number+0x04],dl ;保存万位上的数字
44-67行 将5位数都分别保存在汇编地址在number之后的5个字节内存中;
68
69 ;以下用十进制显示标号的偏移地址
70 mov al,[0x7c00+number+0x04]
将存储在万位数的数传送到通用寄存器 AL 中;
方便使其转义为0-9的ascii码值
71 add al,0x30
将通用寄存器 AL 中的值加上 0x30 ,使其在打印时显示在屏幕上的是常规的数字;
72 mov [es:0x1a],al
这个地址是接在 35 mov byte [es:0x19],0x07 的后面;
将已经转化好的数放入[es:0x1a]中;
73 mov byte [es:0x1b],0x04
作为显示属性,0000 0100 黑底红字,无闪烁,无高亮
cy1
74
75 mov al,[0x7c00+number+0x03]
76 add al,0x30
77 mov [es:0x1c],al
78 mov byte [es:0x1d],0x04
79
80 mov al,[0x7c00+number+0x02]
81 add al,0x30
82 mov [es:0x1e],al
83 mov byte [es:0x1f],0x04
84
85 mov al,[0x7c00+number+0x01]
86 add al,0x30
87 mov [es:0x20],al
88 mov byte [es:0x21],0x04
89
90 mov al,[0x7c00+number+0x00]
91 add al,0x30
92 mov [es:0x22],al
93 mov byte [es:0x23],0x04
69~93行,将5位数按照顺序写入显存中;
94
95 mov byte [es:0x24],‘D’
96 mov byte [es:0x25],0x07
95~96行,在字符串后面再加上一个字符 D ,黑底白字,无闪烁,无高亮;
97
98 infi: jmp near infi ;无限循环
无限重复跳转指令jmp;
由于无事可做。为避免发生问题,设置了一个无限循环
99
100 number db 0,0,0,0,0
标号number ,并在此处声明并初始化5个字节的内存空间,用于存储临时数据;
101
102 times 203 db 0
循环执行指令,填充203个字节的0;
103 db 0x55,0xaa
在主引导扇区最后两个字节先后填入 0x55 和 0xAA
使其成为一个有效的主引导扇区;
代码清单5-1
1 ;代码清单5-1
2 ;文件名:c05_mbr.asm
3 ;文件说明:硬盘主引导扇区代码
4 ;创建日期:2011-3-31 21:15
5
6 mov ax,0xb800 ;指向文本模式的显示缓冲区
7 mov es,ax
8
9 ;以下显示字符串"Label offset:"
10 mov byte [es:0x00],'L'
11 mov byte [es:0x01],0x07
12 mov byte [es:0x02],'a'
13 mov byte [es:0x03],0x07
14 mov byte [es:0x04],'b'
15 mov byte [es:0x05],0x07
16 mov byte [es:0x06],'e'
17 mov byte [es:0x07],0x07
18 mov byte [es:0x08],'l'
19 mov byte [es:0x09],0x07
20 mov byte [es:0x0a],' '
21 mov byte [es:0x0b],0x07
22 mov byte [es:0x0c],"o"
23 mov byte [es:0x0d],0x07
24 mov byte [es:0x0e],'f'
25 mov byte [es:0x0f],0x07
26 mov byte [es:0x10],'f'
27 mov byte [es:0x11],0x07
28 mov byte [es:0x12],'s'
29 mov byte [es:0x13],0x07
30 mov byte [es:0x14],'e'
31 mov byte [es:0x15],0x07
32 mov byte [es:0x16],'t'
33 mov byte [es:0x17],0x07
34 mov byte [es:0x18],':'
35 mov byte [es:0x19],0x07
36
37 mov ax,number ;取得标号number的偏移地址
38 mov bx,10
39
40 ;设置数据段的基地址
41 mov cx,cs
42 mov ds,cx
43
44 ;求个位上的数字
45 mov dx,0
46 div bx
47 mov [0x7c00+number+0x00],dl ;保存个位上的数字
48
49 ;求十位上的数字
50 xor dx,dx
51 div bx
52 mov [0x7c00+number+0x01],dl ;保存十位上的数字
53
54 ;求百位上的数字
55 xor dx,dx
56 div bx
57 mov [0x7c00+number+0x02],dl ;保存百位上的数字
58
59 ;求千位上的数字
60 xor dx,dx
61 div bx
62 mov [0x7c00+number+0x03],dl ;保存千位上的数字
63
64 ;求万位上的数字
65 xor dx,dx
66 div bx
67 mov [0x7c00+number+0x04],dl ;保存万位上的数字
68
69 ;以下用十进制显示标号的偏移地址
70 mov al,[0x7c00+number+0x04]
71 add al,0x30
72 mov [es:0x1a],al
73 mov byte [es:0x1b],0x04
74
75 mov al,[0x7c00+number+0x03]
76 add al,0x30
77 mov [es:0x1c],al
78 mov byte [es:0x1d],0x04
79
80 mov al,[0x7c00+number+0x02]
81 add al,0x30
82 mov [es:0x1e],al
83 mov byte [es:0x1f],0x04
84
85 mov al,[0x7c00+number+0x01]
86 add al,0x30
87 mov [es:0x20],al
88 mov byte [es:0x21],0x04
89
90 mov al,[0x7c00+number+0x00]
91 add al,0x30
92 mov [es:0x22],al
93 mov byte [es:0x23],0x04
94
95 mov byte [es:0x24],'D'
96 mov byte [es:0x25],0x07
97
98 infi: jmp near infi ;无限循环
99
100 number db 0,0,0,0,0
101
102 times 203 db 0
103 db 0x55,0xaa
代码清单 5-1 编译后的列表文件内容
1 ;代码清单 5-1
2 ;文件名:c05_mbr.asm
3 ;文件说明:硬盘主引导扇区代码
4 ;创建日期:2011-3-31 21:15
5
6 00000000 B800B8 mov ax,0xb800 ;指向文本模式的显示缓冲区
7 00000003 8EC0 mov es,ax
8
9 ;以下显示字符串"Label offset:"
10 00000005 26C60600004C mov byte [es:0x00],'L'
11 0000000B 26C606010007 mov byte [es:0x01],0x07
12 00000011 26C606020061 mov byte [es:0x02],'a'
13 00000017 26C606030007 mov byte [es:0x03],0x07
14 0000001D 26C606040062 mov byte [es:0x04],'b'
15 00000023 26C606050007 mov byte [es:0x05],0x07
16 00000029 26C606060065 mov byte [es:0x06],'e'
17 0000002F 26C606070007 mov byte [es:0x07],0x07
18 00000035 26C60608006C mov byte [es:0x08],'l'
19 0000003B 26C606090007 mov byte [es:0x09],0x07
20 00000041 26C6060A0020 mov byte [es:0x0a],' '
21 00000047 26C6060B0007 mov byte [es:0x0b],0x07
22 0000004D 26C6060C006F mov byte [es:0x0c],"o"
23 00000053 26C6060D0007 mov byte [es:0x0d],0x07
24 00000059 26C6060E0066 mov byte [es:0x0e],'f'
25 0000005F 26C6060F0007 mov byte [es:0x0f],0x07
26 00000065 26C606100066 mov byte [es:0x10],'f'
27 0000006B 26C606110007 mov byte [es:0x11],0x07
28 00000071 26C606120073 mov byte [es:0x12],'s'
29 00000077 26C606130007 mov byte [es:0x13],0x07
30 0000007D 26C606140065 mov byte [es:0x14],'e'
31 00000083 26C606150007 mov byte [es:0x15],0x07
32 00000089 26C606160074 mov byte [es:0x16],'t'
33 0000008F 26C606170007 mov byte [es:0x17],0x07
34 00000095 26C60618003A mov byte [es:0x18],':'
35 0000009B 26C606190007 mov byte [es:0x19],0x07
36
37 000000A1 B8[2E01] mov ax,number ;取得标号 number 的偏移地址
38 000000A4 BB0A00 mov bx,10
39
40 ;设置数据段的基地址
41 000000A7 8CC9 mov cx,cs
42 000000A9 8ED9 mov ds,cx
43
44 ;求个位上的数字
45 000000AB BA0000 mov dx,0
46 000000AE F7F3 div bx
47 000000B0 8816[2E7D] mov [0x7c00+number+0x00],dl ;保存个位上的数字
48
49 ;求十位上的数字
50 000000B4 31D2 xor dx,dx
51 000000B6 F7F3 div bx
52 000000B8 8816[2F7D] mov [0x7c00+number+0x01],dl ;保存十位上的数字
53
54 ;求百位上的数字
55 000000BC 31D2 xor dx,dx
56 000000BE F7F3 div bx
57 000000C0 8816[307D] mov [0x7c00+number+0x02],dl ;保存百位上的数字
58
59 ;求千位上的数字
60 000000C4 31D2 xor dx,dx
61 000000C6 F7F3 div bx
62 000000C8 8816[317D] mov [0x7c00+number+0x03],dl ; 保存千位上的数字
63
64 ;求万位上的数字
65 000000CC 31D2 xor dx,dx
66 000000CE F7F3 div bx
67 000000D0 8816[327D] mov [0x7c00+number+0x04],dl ;保存万位上的数字
68
69 ;以下用十进制显示标号的偏移地址
70 000000D4 A0[327D] mov al,[0x7c00+number+0x04]
71 000000D7 0430 add al,0x30
72 000000D9 26A21A00 mov [es:0x1a],al
73 000000DD 26C6061B0004 mov byte [es:0x1b],0x04
74
75 000000E3 A0[317D] mov al,[0x7c00+number+0x03]
76 000000E6 0430 add al,0x30
77 000000E8 26A21C00 mov [es:0x1c],al
78 000000EC 26C6061D0004 mov byte [es:0x1d],0x04
79
80 000000F2 A0[307D] mov al,[0x7c00+number+0x02]
81 000000F5 0430 add al,0x30
82 000000F7 26A21E00 mov [es:0x1e],al
83 000000FB 26C6061F0004 mov byte [es:0x1f],0x04
84
85 00000101 A0[2F7D] mov al,[0x7c00+number+0x01]
86 00000104 0430 add al,0x30
87 00000106 26A22000 mov [es:0x20],al
88 0000010A 26C606210004 mov byte [es:0x21],0x04
89
90 00000110 A0[2E7D] mov al,[0x7c00+number+0x00]
91 00000113 0430 add al,0x30
76
92 00000115 26A22200 mov [es:0x22],al
93 00000119 26C606230004 mov byte [es:0x23],0x04
94
95 0000011F 26C606240044 mov byte [es:0x24],'D'
96 00000125 26C606250007 mov byte [es:0x25],0x07
97
98 0000012B E9FDFF infi: jmp near infi ;无限循环
99
100 0000012E 0000000000 number db 0,0,0,0,0
101
102 00000133 00<rept> times 203 db 0
103 000001FE 55AA db 0x55,0xaa
吐槽:调整代码格式真的是把我的眼睛都看花了。。。。。。
资料参考
- 《x86 汇编语言:从实模式到保护模式》(编著:李忠 王晓波 余杰)
转载:https://blog.csdn.net/qq_43068326/article/details/104736789