x86汇编语言 代码清单5-1理解笔记

代码清单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 汇编语言:从实模式到保护模式》(编著:李忠 王晓波 余杰)
发布了29 篇原创文章 · 获赞 42 · 访问量 8493

猜你喜欢

转载自blog.csdn.net/qq_43068326/article/details/104736789
今日推荐