《30天自制操作系统》 第一周(D1-D7) 笔记

前言:这是我2023年5月份做的一个小项目,最终是完成了整个OS。笔记的话,只记录了第一周。想完善,却扔在草稿箱里许久。最终决定,还是发出来存个档吧。

一、汇编语言

基础指令

  • MOV: move赋值,数据传送指令。一个规则:源数据和目的数据必须位数相同。该指令的数据传送源和传送目的地,不仅可以是寄存器或常数,而且可以是内存地址
  • ADD: add加,演算指令
  • CMP: compare比较指令
  • JMP: jump/goto跳转,跳转到指定的内存地址(例如:JMP 0x7c50)
  • ORG: origin源头起点,程序要从指定的该地址开始
  • DB: define byte往文件里直接写入1个字节的指令,db小写功能相同;也可直接用它写字符串
  • RESB: reserve byte预留n个字节,空出地址上自动填充0x00

条件跳转指令

  • JE: jump if equal如果相等就跳转
  • JB: jump if below如果小于就跳转
  • JAE: jump if above or equal大于或等于时就跳转
  • JBE: jump if below or equal小于或等于时就跳转
  • JC: jump if carry如果进位标志是1就跳转
  • JNC: jump if not carry如果进位标志是0就跳转

其他指令

  • DW: define word16位,2字节
  • DD: define double-word32位,4字节
  • BYTE/WORD/DWORD: 保留字
  • DWORD: Double Word双字节数据类型,是指注册表的键值,每个word为2个字节的长度,DWORD 双字即为4个字节,每个字节是8位,共32位
  • entry: 入口,标签的声明,指定JMP指令的跳转目的地【汇编中,所有标号都是数字,其对应的数字由汇编语言编译器根据ORG指令计算出来】
  • EQU: equal声明常数
  • fin: finish结束
  • INT: interrupt中断,调用BIOS函数的指令
  • HLT: halt停止,让CPU停止动作的指令(进入待机状态),节能
  • CLI: clear interrupt flag中断标志置为0
  • STI: set interrupt flag中断标志置为1
  • EFLAGS: 存储进位标志和中断标志等标志的寄存器
  • PUSHFD: push flags double-word标志位的值按双字节长压入栈
  • POPFD: pop flags double-word标志位的值按双字节长从栈弹出
  • LGDT: 指定一个内存地址,从指定的地址【ESP+6】读取6个字节后赋值给GDTR寄存器(48位)
  • 将指定的段上限【存放在ESP+4】和地址值【ESP+8】赋值给名为GDTR的48位寄存器(低位放在内存地址小的字节里,前)
  • $: 这一行现在的字节数;若有ORG,代表将要读入的内存地址
  • []: 内存/主存,对于CPU,其为外部存储器

二、存储相关概念

缓冲区地址:从软盘上读出的数据装载到内存的哪个位置

EBX处理4G内存,32位基址寄存器

起辅助作用的段寄存器:MOV AL,[ES:BS] 代表ES*16+BX的内存地址

先用附加段寄存器指定一个大致的地址,然后再用基址寄存器来指定其中一个具体地址

可以默认省略数据段寄存器DS,DS必须预先指定为0:

例如

MOV CX,[1234] 等价于MOV CX,[DS:1234]

MOV AL,[SI]等价于MOV AL,[DS:AL]

指定处理的扇区数,范围在0x01-0xff(指定0x02以上的数值时,要特别注意能够连续处理多个扇区的条件。如果是FD的话,似乎不能跨越多个磁道,也不能超过64KB的界限)

读盘顺序:扇区-磁头-柱面

AH=0x02: 读盘

AH=0x03: 写盘

AH=0x04: 校验

AH=0x0c: 寻道

AL=处理对象的扇区数(只能同时处理连续的扇区)

CH=柱面号&0xff

CL=扇区号(0-5位)|(柱面号&0x300)>>2

DH=磁头号

DL=驱动器号

ES:BX=缓冲地址;(校验及寻道时不使用)

返回值:

FLAGS.CF: 进位标志

FLACG.CF==0: 没有错误,AH==0

FLAGS.CF==1: 有错误,错误号码存入AH内(与重置(reset)功能一样)

0x10(16号): 控制显卡

//显示一个字符
AH=0x0e;
AL=character code;
BH=0;
BL=color code;
返回值:无
//系统复位,复位软盘状态,再读一次
AH=0X00
DL=0X00
INT=0x13

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

一般向一个空软盘保存文件时,

1)文件名会写在0x002600以后的地方

2)文件的内容会写在0x004200以后的地方

img

如果与C语言联合使用,有的寄存器能自由使用:EAX/ECX/EDX,其他寄存器只能使用其值,不能改变其值

char *p;//用于BYTE类地址
short *p;//用于WORD类地址
int *p;//用于DWORD类地址

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

os思想:把操作和机制分开

三、术语

TAB=4: TAB键的宽度

FAT=12: 用Windows或MS-DOS格式化出来的软盘就是该格式

boot sector: 启动区,软盘的第一个扇区(512字节为1扇区),一张软盘共有2880个扇区

IPL: initial program loader启动程序加载器,必须取8字节的名字

boot: bootstrap启动,原指靴子上附带的便于拿取的靴带,自力更生完成任务

BIOS: basic input output system基本输入输出系统,组装在电脑主板的ROM(read only memory)单元里

0x00007c00-0x00007dff: 启动区内容的装载地址

地址空间:一个进程用于寻址内存的一套地址集合。主要用于解决多个应用程序同时处于内存中并且互不影响的问题——保护和重定位。

.com: 地址空间可以非数字,以.com结尾的网络域名的集合也是地址空间。

sys是system的缩写,就是系统的意思,sys是Windows的系统文件。如安装文件,日志文件,驱动文件,备份文件,操作如播放等文件,还有些垃圾文件等诸如此类。 都是这类sys后缀名的。

sys文件是驱动程序的可执行代码,其扩展名为.sys,驱动程序安装保持在windows/system32/drivers目录中。

在windows中文件的文件的路径是用反斜杠(\)表示(当初是为了和Unix的文件路径使用”/“区分开来),例如 C:\windows\system,但是我们在写程序的时候能不能再路径的字符串中写成C:\windows\system?答案是不能的,这一点想一下就会可以理解,在很多编译器中,“\”是一个转义字符,例如“\n,\r”等,如果在程序中写成“C:\windows\system“那么实际上编译出来的就是“C:windowssystem ",从而获取不到文件,但是这个路径可以写成C:\windows\system,或者也可以用正斜杠C:/windows/system,这两中方式都是可以的。说到这里,基本上这两种用法不会混淆了,只要记住”\“反斜杠有转义的功能,那么写路径的时候就不会出问题了。 顺便拓展一下,文件的相对路径和绝对路径: 例如一个绝对路径:C:\Windows\System\aaa.dll 如果当前目录是C:\windows 那么aaa.dll这个文件的地址可以表示为: ./system/aaa.dll 中”.“表示当前路径, …/windows/system/aaa.dll中”…“表示父级目录。

VGA显卡:VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。

sprintf: 只对内存进行操作,可应用于所有OS。不是按指定格式输出,只是将输出内容作为字符串写在内存中。能够不使用OS的任何功能。

分段:将4GB的内存分割,每一块的起始地址都看作0来处理

分页:paging,有多少个任务就要分多少页,还要对内存进行排序

GDT设定要优先于IDT

GDT: global (segment) descriptor table全局段号记录表。将这些数据整齐地排列在内存的某个地方,然后将内存的起始地址和有效设定个数放在CPU内被称作GDTR(global segment descriptor table register)的特殊寄存器中,设定完成。C语言里不能对GDTR赋值。

IDT: interrupt descriptor table中断记录表

中断功能:当CPU遇到外部状况变化,或者是内部偶然发生某些错误时,会临时切换过去处理这种突发事件。这就是中断功能。

要使用鼠标,就必须要使用中断。

各个设备有变化时就产生中断,中断发生后,CPU暂时停止正在处理的任务,并做好接下来能够继续处理的准备,转而执行中断程序。中断程序执行完后,再调用事先设定好的函数,返回处理中的任务。正是得益于中断机制,CPU可以一直不用查询键盘、鼠标、网卡等设备的状态,将精力集中在处理任务上。

这就是为什么每个操作前后要加中断标志的原因叭~

系统专用和应用程序用 等价于 内核模式和用户模式

PIC: programmable interrupt controller可编程中断控制器。将8个中断信号IRQ(interrupt request)集合成一个中断信号的装置。

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

PIC寄存器(8位)

IMR: interrupt mask register中断屏蔽寄存器。8位分别对应8路IRQ信号。如果该位值为1,对应IRQ信号被屏蔽,PIC忽视该路信号。理由:对中断设定进行更改时,如果再接受别的中断会引起混乱,所以要屏蔽;此外,还可以屏蔽静电干扰等。

ICW: initial control word初始化控制数据。(只有CPU里word指代16位,这里不一定)

OCW:操作命令字。OCW1写入奇地址口,OCW2、OCW3写入偶地址口。功能:PIC继续时刻监视IRQ信号中断是否发生。io_out8(PIC0_0CW2, 0x60+IDQ号码)

四、遇到的问题

描述问题1:模拟运行操作系统时,双击"!cons_9x.bat"启动失败。 解决方法:导致该问题的原因是我自己没有仔细看书上的标注,双击"!cons_nt.bat"重试后启动成功。原因是两个文件中的命令不同,"!cons_9x.bat"中命令为command,适合linux一类系统,而"!cons_nt.bat"中命令为cmd.exe适合我现在所用的windows系统。

问题2

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

人麻了,以为路径表示不对,跟着重新打了一遍一模一样的,最后发现是拼写失误!IMG写成ING了。

改了名称,一切正常。

网上跟我同一个报错的,但理由又是各不相同。

问题3数据也能执行吗?msg 机器语言也能显示吗?entry

不会报错,标号只是一个数字,但会错乱

不太懂以下的语句:

0A 0A——OR CL,[BP+SI]

68 65 6C——PUSH 0x6c65

问题4

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

问题5 无法生成sys文件

磁盘名称11字节

代码抄错,生成镜像文件时,一定要确保bin,sys, Makefile 同时存在

报错驱使我把代码看得更细

人才:把200写成了2OO,吐血

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

学会定位错误。添加新的中间文件makefile时,需要注意前后的连贯性,是否需要添加/增减

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

忘记声明全局变量了

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

问题可能出在makefile/naskfunc.nas/bootpack.c中

问题

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

使用32位寄存器需要你进入保护模式,进入保护的方法就是开A20 gate,我看下面几行的汇编应该就是在对CR0的这个位进行设置,从而进行快速A20。如果想使用64位寄存器,就必须在进入保护模式之后,开启长模式(long mode)。

uploading.4e448015.gif

正在上传…重新上传取消正在上传…重新上传取消

INSTRSET指令:告诉nask这个程序是给486使用的哦,nask会将EAX解释成寄存器名

486是英特尔系列的CPU【32位】

指定内存时,不知道是BYTE,WORD,DWORD,只有另一方也是寄存器的时候才能省略

p不是指针,而是地址变量,用于存放地址值

问题:如何显示字符

这个逻辑还是没有搞清楚

//extern char hankaku[4096]; why can delete?

//GDT的长度是怎么定的?0x270000-0x27ffff

问题:

第六天中的GB到底是什么?

1GB(Gigabyte)=1024MB

G:granularity颗粒度,单位的大小

4KB * 1M=4GB。1KB * 1M = 1GB。

问题: 为什么键盘输入需要缓冲区

缓冲区其实就是一块内存空间,它用在硬件设备和用户程序之间,用来缓存数据, 目的是让快速的CPU 不必等待慢速的输入输出设备,同时减少操作硬件的次数

_io_stihlt

汇编语言写的函数,链接到C语言使用时,一定要加_

根据CPU规范,机器语言的STI指令之后,如果紧跟着HLT指令,那么就暂不受理这两条指令之间的中断,而要等到HLT指令之后才受理,所以使用io_stihlt函数就能克服这一问题

最常出现的错误:can't link

关注细节语法错误,重点看中断部分

.h 和 naskfunc.nas

问题:

改善FIFO缓冲区,还存在E0问题

五、总结感悟

  • 头文件.h 和 makefile类正则匹配的共同目的:减少重复片段
  • 头文件.h的作用:类似目录
  • 报错首先检查笔误,再依次按关联度从高到低排查文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/246317.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【重点】【DP】123.买卖股票的最佳时机III

题目 法1&#xff1a;单次遍历&#xff0c;Best! class Solution {public int maxProfit(int[] prices) {int f1 -prices[0], f2 0, f3 -prices[0], f4 0;for (int i 1; i < prices.length; i) {f1 Math.max(f1, -prices[i]);f2 Math.max(f2, f1 prices[i]);f3 Ma…

交叉导轨为何要保持日常清洁?

在工业自动化的发展中&#xff0c;交叉导轨因其具有精度高、高刚性、高耐磨性等特点&#xff0c;在数控技术的发展中得到了越来越多的使用&#xff0c;对于交叉导轨来说&#xff0c;保持日常清洁对其性能和寿命具有重要意义。 1、防止灰尘和杂质的侵入&#xff1a;交叉导轨在机…

保姆级教学:Java项目从0到1部署到云服务器

目录 1、明确内容 2、apt 2.1、apt 语法 2.2、常用命令 2.3、更新apt 3、安装JDK17 4、安装MySQL 4.1、安装 4.2、检查版本及安装位置 4.3、初始化MySQL配置⭐ 4.4、检查状态 4.5、配置远程访问⭐ 4.6、登录MySQL 4.7、测试数据库 4.8、设置权限与密码⭐ 5、安…

『OpenCV-Python|鼠标作画笔』

Opencv-Python教程链接&#xff1a;https://opencv-python-tutorials.readthedocs.io/ 本文主要介绍OpenCV-Python如何将鼠标作画笔绘制圆或者矩形。 示例一&#xff1a;图片上双击的位置绘制一个圆圈 首先创建一个鼠标事件回调函数&#xff0c;鼠标事件发生时就会被执行。鼠标…

【代码随想录-数组】移除元素

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

多维时序 | Matlab实现CNN-BiGRU-Mutilhead-Attention卷积双向门控循环单元融合多头注意力机制多变量时间序列预测

多维时序 | Matlab实现CNN-BiGRU-Mutilhead-Attention卷积双向门控循环单元融合多头注意力机制多变量时间序列预测 目录 多维时序 | Matlab实现CNN-BiGRU-Mutilhead-Attention卷积双向门控循环单元融合多头注意力机制多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一…

element+vue 之 v-limit 按钮操作权限

1.新建一个permission.js文件 import store from /storeexport default {inserted: function (el, binding) {const { perms: limits } store.state.userconst { value: params } bindingif (!limits.length) returnif (params && Array.isArray(params)) {if (!limi…

GraphQL的力量:简化复杂数据查询

1. GraphQL GraphQL 是一种由 Facebook 开发并于 2015 年公开发布的数据查询和操作语言&#xff0c;也是运行在服务端的运行时&#xff08;runtime&#xff09;用于处理 API 查询的一种规范。不同于传统的 REST API&#xff0c;GraphQL 允许客户端明确指定它们需要哪些数据&am…

【Spring】Spring简介、IOC、DI

目录 Spring简介 Spring Framework五大功能模块 IOC容器 IOC思想 IOC容器在Spring中的实现 基于XML管理bean 配置bean 获取bean 依赖注入之setter注入 依赖注入之构造器注入 特殊值处理 字面量赋值 null值 xml实体 CDATA节 为类类型属性赋值 为数组类型属性赋值 为集合类型属性…

03-Redis缓存高可用集群

文章目录 1、Redis集群方案比较2、Redis高可用集群搭建redis集群搭建Java操作redis集群 4、Redis集群原理分析槽位定位算法跳转重定位Redis集群节点间的通信机制gossip通信的10000端口网络抖动 Redis集群选举原理分析集群脑裂数据丢失问题集群是否完整才能对外提供服务Redis集群…

机器学习工程师在人工智能时代的角色

机器学习工程师在人工智能时代的角色 在当今的数字时代&#xff0c;人工智能&#xff08;AI&#xff09;已成为许多行业不可或缺的一部分。从流程自动化到增强客户体验&#xff0c;人工智能具有改变企业的巨大潜力。这一变革性技术的核心是机器学习&#xff0c;该领域专注于开…

五、Kotlin 函数进阶

1. 高阶函数 1.1 什么是高阶函数 以下 2 点至少满足其一的函数称为高阶函数&#xff1a; 形参列表中包含函数类型的参数 //参数 paramN 可以是&#xff1a;函数引用、函数类型变量、或 Lambda 表达式。 fun funName(param1: Type1, param2: Type2, ... , paramN: (p1: T1, p2…

快速搭建一个基于MVC架构的Spring Boot应用

提示&#xff1a;如果对 MVC 架构模式不熟悉可以看我的博客 > MVC架构模式与三层架构 快速搭建一个基于MVC架构的Spring Boot应用 一、Web 服务二、快速构建一个Spring Web MVC的 Web 应用1.使用脚手架快速的搭建环境&#xff1a;2.准备数据库&#xff1a;3.编写Dao层访问数…

Tortoise-tts Better speech synthesis through scaling——TTS论文阅读

笔记地址&#xff1a;https://flowus.cn/share/a79f6286-b48f-42be-8425-2b5d0880c648 【FlowUs 息流】tortoise 论文地址&#xff1a; Better speech synthesis through scaling Abstract: 自回归变换器和DDPM&#xff1a;自回归变换器&#xff08;autoregressive transfo…

探索IOC和DI:解密Spring框架中的依赖注入魔法

IOC与DI的详细解析 IOC详解1 bean的声明2 组件扫描 DI详解 IOC详解 1 bean的声明 IOC控制反转&#xff0c;就是将对象的控制权交给Spring的IOC容器&#xff0c;由IOC容器创建及管理对象。IOC容器创建的对象称为bean对象。 要把某个对象交给IOC容器管理&#xff0c;需要在类上…

LeetCode:376.摆动序列

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;算法_仍有未知等待探索的博客-CSDN博客 题目链接&#xff1a;376. 摆动序列 - 力扣&#xff08;LeetCode&#xff09; 一、题目 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称…

jsp原理与EL,JSTL表达式基础内容整理

2024年了&#xff0c;vue都到了灌篮高手的版本&#xff0c;真的没想到我还会在这个时间整理一篇关于jsp页面操作的文章。技术就是一个不用就忘的东西&#xff0c;既然工作中还有用武之地&#xff0c;那就整理一下以备不时之需。 长话短说&#xff0c;不展开叙述&#xff0c;只记…

Hive3.1.3基础(续)

参考B站尚硅谷 分区表和分桶表 分区表 Hive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录&#xff0c;每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择查询所需要的分区&#xff0c;这样的查询效率会提高很多。 分区表基本语法 分区表…

【linux】Debian挂起和休眠

一、挂起和休眠 在Debian桌面系统中&#xff0c;挂起和休眠是两种不同的状态&#xff0c;它们之间有一些区别。 挂起&#xff08;Suspend&#xff09;是将当前系统的状态保存到RAM&#xff08;内存&#xff09;中&#xff0c;然后关闭所有硬件设备&#xff0c;除了RAM之外。在…

如何在美国硅谷高防服务器上运行自定义的脚本和应用程序

在美国硅谷高防服务器上运行自定义的脚本和应用程序需要一定的技术和知识。下面我们将介绍一些关键步骤&#xff0c;帮助您顺利地在这些服务器上运行自定义应用程序和脚本。 确保您有对服务器的访问权限&#xff0c;并且已经通过SSH等方式连接到服务器。接下来&#xff0c;您可…