书上P42页的实验让我们输入一串汇编语言并执行。
第一个是nasm
Index of /pub/nasm/releasebuilds/2.15.05/win64
nasm使用编译汇编语言的(其实只有汇编和链接步骤)
第二个是书上配套软件包
上网搜就有了,不过配套的nasm编辑器在我的64为windows上用不了,不过没有关系,用VScode就行。Vscode可以装一个高亮nasm的插件。这里主要要用的是写虚拟机硬盘的工具
直接把书上的抄过来
然后使用 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
然后再编译一下就可以了,会产生相应的bin文件
然后使用书上配套的工具把这个bin文件写入第一个扇区。最后激动的点击运行虚拟机….
如果一切正常的话,就会出现这个问题。也就是说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就可以看到文件的内容了
一共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处,最后死循环。运行的效果就是
至此,第四章节的主要内容就结束了。
这一章主要讲的内容
1.整个实验过程,没有操作系统的参与
2.BIOS会把磁盘的第一个逻辑扇区加载到内存中,并检查其合法性
3.显存映射在内存的某一个位置上,可以通过访问指定的位置直接访问显示设备。
1.VirtualBox 到底模拟的是什么架构的处理器?在选择操作系统的时候,我选择了UNknow,编写汇编的时候是是按照8086的方式编的。真实的处理架构到底是怎样的?
2.在学习汇编语言(王爽)的时候,我用virtualBox装了DOS系统,这至少说明了VirtualBox是支持8086模式的,而这次是i386模式,不知道对应的架构是否会变。
希望分享出来的文章可以帮到大家,如果有发现错误或者能够解答遗留问题的读者,欢迎留言交流。