《X86汇编语言:从实模式到保护模式》学习笔记

第四章:虚拟机的安装和使用

这篇文章首发于我的博客转载请标明出处

书上P42页的实验让我们输入一串汇编语言并执行。

step0:首先需要准备一些必要的软件,

第一个是nasm

Index of /pub/nasm/releasebuilds/2.15.05/win64

nasm使用编译汇编语言的(其实只有汇编和链接步骤)

第二个是书上配套软件包

上网搜就有了,不过配套的nasm编辑器在我的64为windows上用不了,不过没有关系,用VScode就行。Vscode可以装一个高亮nasm的插件。这里主要要用的是写虚拟机硬盘的工具

step1:编写汇编语言

直接把书上的抄过来
《X86汇编语言:从实模式到保护模式》学习笔记

然后使用 nasm -f bin ch3.asm -o ch3.bin 编译

然后就会得到一个错误信息….

ch3.asm:3: error: operation size not specified
ch3.asm:4: error: operation size not specified
ch3.asm:5: error: operation size not specified

这几句说的是三条mov指令没有指定操作数的大小,想来也确实是这样,因为nasm不知道怎么理解这三个ASCII码,可以是8bit的也可以是16或者32bit的。

所以要使用一个修饰符来说明这个操作数是几个bit

看到内存是递增2的,所以应该用 word

《X86汇编语言:从实模式到保护模式》学习笔记

然后再编译一下就可以了,会产生相应的bin文件

然后使用书上配套的工具把这个bin文件写入第一个扇区。最后激动的点击运行虚拟机….
《X86汇编语言:从实模式到保护模式》学习笔记

如果一切正常的话,就会出现这个问题。也就是说BIOS拒绝了启动,为什么会这样呢,是应为BIOS在加载第一个扇区的时候会进行检查,如果最够的两个字节不是0x55AA的话,就不认为这是一个合法的主引导扇区,就会拒绝启动。

解决的方法也很简单,就是填充第一个扇区,使得最后两个字节是0x55AA就行。我写了一个简单的Python程序,可以自动的填充扇区

import struct
padTailDec = 0x55aa
padTailBin = padTailDec.to_bytes(2, byteorder='big', signed=False)
asmFile = open("./ch3.bin","rb")
asmContext = asmFile.read()
padLen = 510 - len(asmContext) #最后两个是0x55和0xaa
padAsm = open("./padAsm.bin","w")
padAsm.close()
padAsm = open("./padAsm.bin","r+b")
zeroBit = struct.pack('x')
for i in range(0,padLen):
    asmContext += zeroBit
padAsm.write(asmContext)
padAsm.write(padTailBin)
print("DONE....")

这是一个非常简陋的代码,简陋到你需要自己改一下文件名…

填充完成之后,用VScode的hexdump就可以看到文件的内容了

《X86汇编语言:从实模式到保护模式》学习笔记

一共512个byte,最后两个是0x55AA。

然而在实际测试的时候,我发现使用word修饰符并不能得到正确输出,为什么会这样一时半会还没有头绪,而且现在还不能调试,先把坑挖了,以后再填。

最后我写的asm是

mov ax,0xb800
mov ds,ax
mov byte ds:[0x0],0x41
mov byte ds:[0x1],0x07
spin:
    jmp spin 

这段代码的逻辑非常简单,先把显存的基地址移动到段寄存器里,然后字符A加上黑底白字下划线的特效移动到偏移0x0处,最后死循环。运行的效果就是
《X86汇编语言:从实模式到保护模式》学习笔记

至此,第四章节的主要内容就结束了。

总结

这一章主要讲的内容

1.整个实验过程,没有操作系统的参与
2.BIOS会把磁盘的第一个逻辑扇区加载到内存中,并检查其合法性
3.显存映射在内存的某一个位置上,可以通过访问指定的位置直接访问显示设备。

遗留问题

1.VirtualBox 到底模拟的是什么架构的处理器?在选择操作系统的时候,我选择了UNknow,编写汇编的时候是是按照8086的方式编的。真实的处理架构到底是怎样的?
2.在学习汇编语言(王爽)的时候,我用virtualBox装了DOS系统,这至少说明了VirtualBox是支持8086模式的,而这次是i386模式,不知道对应的架构是否会变。

后记

希望分享出来的文章可以帮到大家,如果有发现错误或者能够解答遗留问题的读者,欢迎留言交流。

上一篇:libwebsocket windows 编译--openssl


下一篇:如何编译FFmpeg源码(Mac环境)