来自:清泛网http://www.tsingfun.com/html/2015/dev_0804/hello_os_word_my_first_os.html

首先阐述下程序运行的基本原理:计算机CPU仅仅运行二进制指令,我们使用的开发语言开发出的程序终于由对应的编译器编译为二进制指令。二进制中包括程序相关的数据、代码指令(用我们最常见的公式描写叙述就是:程序=数据+算法)。CPU读取对应的指令、数据后開始运行,运行后的结果输出到外部设备,如屏幕、磁盘等。整个过程中,CPU发挥最为核心的作用,与其它设备一起完毕程序的运行、输出。

OS本身也是程序。它的执行也是如此,开机后从指定地址处(0x7c00),開始执行指令。

先看看本节样例终于执行效果:


编译执行环境:

nasm:Inter x86汇编编译工具。用户将我们的汇编代码编译为二进制。(下载地址

Bochs:执行os的虚拟机工具。模拟载入我们生成的软盘映像,并执行os。

下载地址


代码例如以下:

;--------------------------------------------------------------
; 平庸OS(Pf OS) 一个最简单的OS
; Author : tsingfun.com
;-------------------------------------------------------------- ; FAT12引导扇区
ORG 0x7c00 ;引导開始地址,固定的,主板BIOS决定,本条指令仅仅是申明,不占字节(有兴趣的能够单独编译这条指令,然后查看二进制,文件0k)
JMP _START ;CPU执行的第一条指令。就是跳转到_START地址处(这里是标签。实际编译后_START是有一个相对地址的)
TIMES 3-($-$$) NOP ;NOP:一个机器周期。$:当前地址,$$:首地址。由于以上信息必须占3个字节。所以不足的部分用nop指令填充,
;详细nop占用几个字节请读者使用二进制查看工具自行验证。 DB "PFOSBEST" ; 标识(公司、品牌等)8个字节
DW 512 ; 每扇区字节数
DB 1 ; 每簇扇区数
DW 1 ; Boot内容占几个扇区
DB 2 ; 共同拥有多少FAT表
DW 224 ; 根文件夹文件数最大值
DW 2880 ; 扇区总数
DB 0xf0 ; 介质描写叙述符
DW 9 ; 每FAT扇区数
DW 18 ; 每磁道扇区数
DW 2 ; 磁头数(面数)
DD 0 ; 隐藏扇区数
DD 2880 ; 若上面“扇区总数”为0。则这个值记录扇区总数
DB 0,0,0x29 ; 中断13的驱动器号;未使用;拓展引导标记
DD 0xffffffff ; 卷序列号
DB "PFOS v1.0.0" ; 卷标(11个字节)
DB "FAT12 " ; 文件系统类型(8个字节)
;---------------------------------------------------------------------
; 448个字节。引导代码、数据及其它填充字符
TIMES 18 DB 0 _START:
MOV AX, 0 ;AX:累加寄存器,CPU内置的16位寄存器,最为经常使用。能够用于存储执行的中间结果,此处清零
MOV SI, MSG ;SI:(source index)源变址寄存器。经常使用来存储待操作的数据的首地址。此处指向数据区的字符串
_LOOP: ;循环指令開始
MOV AL, [SI] ;[]取地址中的内容,AL是AX的低8位,所以取8bit,即1字节,字符串的ASCII。
ADD SI, 1 ;字符串往后移动一个字节
CMP AL, 0 ;推断当前取出的ASCII是否是0,
JE _END ;JE:Equal则Jmp,等于零表示字符串显示完了。结束。
MOV AH, 0x0e ;调用系统10h中断显示ASCII字母。AH,BX指定显示模式及參数(详见:http://www.tsingfun.com/html/2015/dev_0804/570.html)
MOV BX, 15
INT 0x10
JMP _LOOP ;继续下一个字符的显示
_END:
JMP $ ;跳到当前的地址。当然就陷入无限循环啦,此处为了让程序停在此处。 ;数据区,就是待输出的字符串信息
MSG DB 0x0a, "----------------------------------------------", 0x0d, 0x0a, \
"| Hello, OS World! |", 0x0d, 0x0a, \
"----------------------------------------------", 0x0d, 0x0a, 0x0 TIMES 510-($-$$) DB 0
DW 0xaa55 ; 结束标志
;---------------------------------------------------------------------- ; FAT数据区
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
TIMES 4600 DB 0
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
TIMES 1469432 DB 0

当中。基本的步骤代码中都有详尽的凝视,如有不论什么问题,请移步至论坛《深入OS》板块发帖讨论。


编译运行过程:

打开dos窗体。进入源代码所在文件夹,运行命令nasm boot.asm -o pfos.img:



同文件夹下生成一个"pfos.img"软盘映像文件。接下来仅仅须要把它装载到虚拟机执行就可以,当然有条件的话能够实际写入老式的软盘用真机执行,结果是一样的。



同文件夹下新建一个“pfos.bxrc” Bochs配置文件,内容例如以下:

#how much memory the emulated machine will have
megs:4 #filename of ROM images
romimage:file=$BXSHARE\BIOS-bochs-latest,address=Oxf0000
vgaromimage: file=$BXSHARE\VGABIOS-elpin-2.40 #what disk images will be used
floppya:1_44="pfos.IMG",status=inserted #Choose the boot disk
boot:a #where do we send log messages?
#log:bochsout.txt

双击“pfos.bxrc”启动Bochs执行就可以启动我们自己写的os了。

源代码点此下载


接下来解释一下执行原理:

首先。软盘大小是1.44M(这个是固定的)。所以我们在程序中指定它为1,474,560 字节,除了程序本身的指令、数据外。不足的部分所有补零。

TIMES 1469432  DB 0     就是此处開始写1469432个字节的0。

软盘採用的是FAT12文件格式,我们如今的常见的文件格式有FAT32、NTFS、EXT3等。FAT12是早期的一种文件格式。文件格式是文件格式化存储的一种算法,比方我们要将一个文件存储到软盘(磁盘)上,有些人可能会想我直接从地址0開始存储。直到结束。那么文件名称、文件大小、创建时间等其它信息怎么存?紧接着后面继续存储么?那该给各部分分配多少字节空间?先不说兴许查找文件的效率。这样的存储方法无章可循会全然失控,是不行的方案。

文件格式化算法就攻克了此类问题,并且兼顾文件的高效率查找。

基本原理就是给软盘(磁盘)分区:FAT区、文件夹区、数据区,存储文件时先存储文件基本信息到文件夹区。然后文件的数据依照一定格式存储到数据区,文件夹区中有数据区中文件数据的地址。

这里仅仅简介一下FAT12格式。兴许篇章会深入解析每一个字节代表的含义。

我们来看看我们生成的映像里面究竟有什么东西?这时我们须要用到二进制查看工具WinHex,点此下载

以上看到的是二进制静态代码。实际执行中各指令的地址都是动态变化的,下来一起借助Bochs的debug功能来一探到底。

我们双击“pfos.bxrc”默认是以执行模式启动Bochs,实际上我们应该启动bochsdbg.exe。因此写个简单的批处理脚本启动它吧。例如以下:

@echo off

SET BXSHARE=C:\Program Files (x86)\Bochs-2.5

if %PROCESSOR_ARCHITECTURE% == x86 (
SET BXSHARE=C:\Program Files\Bochs-2.4.6
) "%BXSHARE%"\bochsdbg -q -f "pfos.bxrc"

双击脚本,启动debug模式,例如以下:

Bochs经常使用的debug命令例如以下:

b 0x...   断点命令,指定地址处调试

info break  显示当前断点信息

c    继续运行

s    步入运行

n    单步运行

info cpu   查看cpu寄存器(可分别运行 r/fp/sreg/creg)

print-stack   打印堆栈

xp /长度 地址     显示地址处内容(xp:物理地址,x:线性地址)

u 起始地址 结束地址   反汇编一段代码

trace on    反汇编运行的每条指令

trace-reg on   每运行一条指令都打印一下cpu信息

exit   退出调试

大家有兴趣的话能够调试下,然后看看每步骤寄存器值的变化。



总结:本篇主要是让大家对操作系统有个总体概念上的认识。揭开os神奇的面纱。从底层调试到执行,每一个过程都真真切切展如今大家面前。

至于汇编指令、地址寻址临时不懂的话,也不要紧。兴许章节会继续作具体阐述,力求使大家在不断的执行、调试过程中逐渐熟悉并掌握汇编及计算机底层技术。

作者:清泛网,专注IT干货分享。

关注我们的微博:http://weibo.com/tsingfun

官网:http://www.tsingfun.com

第一个Hello,OS World操作系统的更多相关文章

  1. Mac OS X操作系统常见快捷键集锦

    Mac OS X操作系统常见快捷键集锦 启动时的快捷键 启动时按住 X 键 : 强制从 Mac OS X 启动(适用于那些在同一宗卷上安装了 Mac OS X 和 Mac OS 9 双系统的 Mac ...

  2. Mac OS X 操作系统下JDK安装与环境变量配置

    1. 下载JDK. 去oracle官网的Java SE Downloads页面(如图 1),下载Mac os版本JDK(如图 2): 图 1 图 2   2. 安装JDK. 下载完成后,双击.dmg文 ...

  3. os与操作系统进行交互,sys解释器相关,random随机数,shutil解压和压缩

    1.os 与操作系统相关 对文件的处理 对路径的处理 import os#主要用于与操作系统进行交互 掌握: print(os.makedirs('a/b/c'))#创建目录 可用递归创建 print ...

  4. linux 下一个 osw先从操作系统和标准脚本主动发起

    linux 下一个 osw与操作系统的引导和启动标准的脚本.osw它指的是--os watcher,这是一个显示器os这些指标shell脚本.osw监测数据一般使用oracle技能评估os资源的使用, ...

  5. Mac OS X 操作系统下IntelliJ IDEA激活码(Activation code)破解

    Mac OS X 操作系统(版本:10.13.6)下载并安装IntelliJ IDEA: Version: 2018.2.4 Download IntelliJ IDEA 下一步对IntelliJ I ...

  6. Octoroit OS VB操作系统简单介绍

    官方地址:http://octoroit.weebly.com/ 首先需要指明的是 :Octoroit OS 并不是一个真正意义上的操作系统,它是运行在windows 之上的 窗口系统,一个Visua ...

  7. 深入NodeJS模块os - 与操作系统“打交道”

    读了 os 模块的文档,研究了几个有意思的问题:

  8. [No000035]操作系统Operating System之OS Interface操作系统接口

    接口(Interface) 仍然从常识开始… 日常生活中有很多接口:电源插座:汽车油门… 那什么是接口? 连接两个东西.信号转换.屏蔽细节… Interface: electrical circuit ...

  9. windows用户用VMware 虚拟机安装黑苹果Mac.OS.X操作系统

    使用的操作系统操作系统 windows7 SP1 X64 本教程所用 的软件的下载地址都在本教程中 ) 电脑内存低于 4G 的,加内存吧 … 1. SecurAble (检测你的 CPU 是否支持硬件 ...

随机推荐

  1. GCC内嵌汇编一些限制字符串

    /******************/ “b”将输入变量放入ebx “c”将输入变量放入ecx “d”将输入变量放入edx “s”将输入变量放入esi “d”将输入变量放入edi “q”将输入变量放 ...

  2. 使用 D8 分析 javascript 如何被 V8 引擎优化的

    在上一篇文章中我们讲了如何使用 GN 编译 V8 源码,文章最后编译完成的可执行文件并不是 V8,而是 D8.这篇我们讲一下如何使用 D8 调试 javascript 代码. 如果没有 d8,可以使用 ...

  3. pycharm配置 自动运行指定脚本

    配置:RUN -Debug Configuration Script: 脚本的地址 Script Parameters: 脚本的参数 Interpreter: python解释器

  4. 九度oj 题目1079:手机键盘

    题目描述: 按照手机键盘输入字母的方式,计算所花费的时间 如:a,b,c都在“1”键上,输入a只需要按一次,输入c需要连续按三次. 如果连续两个字符不在同一个按键上,则可直接按,如:ad需要按两下,k ...

  5. [LOJ#530]「LibreOJ β Round #5」最小倍数

    [LOJ#530]「LibreOJ β Round #5」最小倍数 试题描述 第二天,LCR 终于启动了备份存储器,准备上传数据时,却没有找到熟悉的文件资源,取而代之的是而屏幕上显示的一段话: 您的文 ...

  6. socket编程-微软小兵

    socket两端建立连接,不断开的连接的情况下做数据交互,客户端发送数据和服务端返回数据.直到客户端要求断开,则关闭连接. 代码目录结构:

  7. bzoj 3456 城市规划 无向简单连通图个数 多项式求逆

    题目大意 求n个点的无向简单连通图个数 做法1 \(f[i]\)表示i个点的无向简单连通图个数 \(g[i]=2^{\frac {i*(i-1)}{2}}\)表示i个点的无向简单图个数(不要求连通) ...

  8. Codeforces878E. Numbers on the blackboard

    $n \leq 100000$的数列,数字范围$-1e9,1e9$,现$q \leq 1e5$个每次问在一个区间玩游戏,能得到的最大的数.“游戏”:选相邻两个数$a_x,a_y$,然后把他们删掉,变成 ...

  9. Python入门--17--pickle

    pickle模块,实际用途也很简单.单一,主要用于保存列表(list),元祖(Tuple),字典(dictionary) 当然,一定是大的列表.字典什么的,成千上万行的字典.列表,才能凸显出它的用武之 ...

  10. 微信JSSDK分享功能详解

    本文以微信分享到朋友圈,分享给微信好友为例为参考,进行调用测试,想添加其他的功能,自行查看开发人员文档即可 工欲善其事,必先利其器,好好利用下边的帮助工具,都是腾讯给开发人员的工具 1.微信开发者说明 ...