标题当然是个噱头,今天周末,照例是睡觉读书。下午看了京东读书里面有一本<一个操作系统的实现>,是10多年前一个叫余渊的小伙子写的,CSDN 创始人蒋涛做序推荐。这样的书属于小众图书,把第一个小程序跑起来不难,最近学习操作系统安装了virutalbox,正好练练手。
1.2节就相当于一个hello world。
boot.asm
org 07c00h ;告诉编译器程序加载到7c00处
mov ax, cs
mov ds, ax
mov es, ax
call DispStr ;调用显示字符串的例程
jmp $ ;无限循环
DispStr:
mov ax, BootMessage
mov bp, ax ; ES:BP = 串地址
mov cx, 16 ;串长度
mov ax, 01301h ; AH = 13h, AL = 01h
mov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch, 高亮)
mov dl, 0
int 10h ; 10h 号 BIOS 中断
ret
BootMessage: db "Hello, OS world!"
times 510 - ($-$$) db 0 ;填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ;结束标志
其中比较难理解的也就是倒数第二句:
$ 表示当前行被汇编后的地址。
$$表示一个节(section)的开始处被汇编后的地址。这里的程序只有1节,所以表示的是程序的开始地址,也就是0x7c00.
编译:nasm boot.asm -o boot.bin
做成启动盘书中没有给直接的工具,让直接用软盘,这年月谁还有软盘?软驱也没有。
直接用了以前java的工具,代码如下:
package orange;
import java.io.*;
import java.util.ArrayList;
public class MakeBootbin {
private ArrayList<Integer> imgByteToWrite = new ArrayList<Integer>();
private void readKernelFromFile(String fileName) {
File file = new File(fileName);
InputStream in = null;
try {
in = new FileInputStream(file);
int tempbyte;
while ((tempbyte = in.read()) != -1) {
imgByteToWrite.add(tempbyte);
}
}
catch (Exception e) {
e.printStackTrace();
}
// imgByteToWrite.add(0x55);
// imgByteToWrite.add(0xaa);
// imgByteToWrite.add(0xf0);
// imgByteToWrite.add(0xff);
// imgByteToWrite.add(0xff);
}
public MakeBootbin(String s) {
readKernelFromFile("boot.bin");
int len = 0x168000;
int curSize = imgByteToWrite.size();
for (int l = 0; l < len - curSize; l++) {
imgByteToWrite.add(0);
}
}
public void makeFllopy() {
try {
DataOutputStream out = new DataOutputStream(new FileOutputStream("system.img"));
for (int i = 0; i < imgByteToWrite.size(); i++) {
out.writeByte(imgByteToWrite.get(i).byteValue());
}
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
MakeBootbin op = new MakeBootbin("orange");
op.makeFllopy();
}
}
运行效果如下: