OS-3
建立OS框架includeinclude文件夹下面放一些需要用到的头文件,如type.h等等。
注意,我们在定义头文件的时候需要在开头和结尾加上:
123456#ifndef xxx#define xxxbalabala#endif
防止出现多重定义的报错
OS-4
建造二级引导器二级引导器的作用二级引导器作为操作系统的先驱,它需要收集机器信息,确定这个计算机能不能运行我们的操作系统,对 CPU、内存、显卡进行一些初级的配置,放置好内核相关的文件。
二级引导器的设计
运行流程GRUB启动后,选择对应的启动菜单,GRUB会通过自带的文件驱动,定位到对应的eki文件(即我们的操作系统)
GRUB通过识别GRUB头部(imginithead.asm),获取二级引导器的信息并加载(inithead_entry.c将二级引导器的代码(这些代码将对机器进行初始设置),加载到内存里)。
代码讲解实现GRUB头我们的 GRUB 头有两个文件组成,一个 imginithead.asm 汇编文件,它有两个功能,既能让 GRUB 识别,又能设置 C 语言运行环境,用于调用 C 函数;第二就是 inithead.c 文件,它的主要功能是查找二级引导器的核心文件——initldrkrl.bin,然后把它放置到特定的内存地址上。
多重引导的前置知识能够被 GRUB 引导的内核有两个条件:
需要有一个 Multiboot Header ,这个 Multiboot Heade ...
OS-2
测试环境的配置暂未整理,参考这篇文章
https://zhuanlan.zhihu.com/p/390128368
vim-1
vim-1vim的安装这里以Ubuntu的安装vim GTK3版本为例:
12sudo apt update //先更新apt列表sudo apt install vim-gtk3 //安装GTK3的vim
vim的简单使用
vim的一些命令行指令:
“:q!”:退出 Vim
“:wq\”:存盘退出
“:s”:执行替换
“:!”:执行外部命令
“:edit”(一般缩写为 “:e”):编辑文件
“:w”:写文件
“:r”:读文件
“:help”:查看帮助
vim的四种模式正常模式缺省的编辑模式;如果不加特殊说明,一般提到的命令都直接在正常模式下输入;在任何其他模式中,都可以通过键盘上的 Esc 键回到正常模式。
插入模式输入文本时使用;比如在正常模式下键入 i(insert)或 a(append)即可进入插入模式。
可视化模式用于选定文本块;可以用键 v(小写)来按字符选定,Vim 里也提供其他不同的选定方法,包括按行和按列块。
命令行模式用于执行较长、较复杂的命令;在正常模式下键入冒号(:)即可进入该模式;使用斜杠(/)和问号(?)开始搜索也算作命令行模式。命令行模式下 ...
OS-1
CPU三种工作模式实模式特点
运行真实的指令
发往内存的地址是真实的
实模式寄存器下面是x86 CPU实模式下的寄存器,均为16位
寄存器
描述
AX, BX, CX, DX, DI, SI, BP
通用寄存器
IP
指向下一条指令的地址
SP
栈指针寄存器,始终指向栈顶
CS, DS, ES, SS
段寄存器,存放一个内存段的基地址
FLAGS
存放CPU运算产生的标志位
实模式访问内存
代码段由CS和IP确定,栈段由SS和SP确定
示例汇编代码:
12345678910111213141516data SEGMENT ;定义一个数据段存放Hello World! hello DB 'Hello World!$' ;注意要以$结束data ENDScode SEGMENT ;定义一个代码段存放程序指令 ASSUME CS:CODE,DS:DATA ;告诉汇编程序,DS指向数据段,CS指向代码段start: MOV AX,data ;将data段首地址赋值给AX MOV D ...
shell编程小技巧
Shell编程小技巧
由于一般的基础语法百度都能搜到,这里不多做介绍。也由于Ando平时不多接触shell编程,因此可能一些比较基础的用法也被记在里面了。
小trick$()和${}
$()表示将括号内命令的执行结果赋值给变量
${}用于做精准的变量替换(一般情况下同直接$某个var)
1234567891011121314${file#*/}:拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt${file##*/}:拿掉最后一条 / 及其左边的字符串:my.file.txt${file#*.}:拿掉第一个 . 及其左边的字符串:file.txt${file##*.}:拿掉最后一个 . 及其左边的字符串:txt${file%/*}:拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3${file%%/*}:拿掉第一条 / 及其右边的字符串:(空值)${file%.*}:拿掉最后一个 . 及其右边的 ...
gcc优化技术
GCC优化技术简析
gcc优化等级从O0-O3(Os约为O2.5),每个等级都是在之前的优化基础上再进行优化
GCC O0不做任何优化
GCC O1defer-pop这个优化应用在汇编层面上(后端优化),一般情况下, 函数的输入值被保存在堆栈中并且被函数访问,函数返回之后,输入值被立即弹出堆栈。这个选项允许函数返回时, 输入值还在堆栈中。等到多个函数调用后,一起弹出
merge-constans合并相同的常量(即常量折叠)
thread-jumps合并连续的jump为一个jump
loop-optimize循环不变量外提
if-conversion通过减少或者删除条件分支, 以及使用条件传送,设置标志和使用运算技巧来替换他们, 编译器可以减少if-then语句中花费的时间量。
if-conversion2if-conversion的基础上结合更高的数学特性
delayed-branch试图根据指令周期时间重新安排指令。 它还试图把尽可能多的指令移动到条件分支前, 以便最充分的利用处理器的延迟槽。
guess-branch-probability试图确定条件分支最可能的结果, 并且相应 ...
GoLang-1
GoLang入门(1)写出第一个go程序项目结构
程序内容1234567package main // 表示该文件所在的包,每个文件必须归属于一个包import "fmt" // import fmt库func main(){ fmt.Println("Hello world!")}
运行程序12go build xxx.go对xxx.go文件进行编译,生成可执行文件go run xxx.go可以直接执行xxx.go
go程序的执行入口是main函数
go语言不需要加分号
go强制要求定义的变量和引用的库必须要用到
acmTrick.md
算法竞赛的小技巧STL篇
count函数:
1count(a.begin(), a.end(), 1) 获取a中1出现的次数
accumulate函数
1accumulate(a.begin(), a.end(), 0) 从0开始累加a中的元素
accumulate还可以自定义数据类型:
12vector<pair<ll, ll>> a;ll sum = accumulate(a.begin(), a.end(), 0LL, [](ll a, pair<ll, ll> x){return a + x.first;});
注意long long时的初始值要加上LL
组反向排序(从大到小)
1sort(a.rbegin(), a.rend())
string类型find
1int a = s.find('1'); //找到第一个出现'1'的位置
找不到返回string::npos。示例用法:
12345char c;if(string("codeforces&q ...
图着色寄存器分配算法
图着色寄存器分配算法背景架构概述这里先阐明我架构中的几个概念:
虚拟寄存器:在生成后端代码时暂用的寄存器,寄存器分配的过程中会将虚拟寄存器逐一替换为物理寄存器
基本块:后端代码的每个函数中包含着若干基本块,每个基本块有若干指令构成且最后一条一定是跳转或返回指令
生命周期:一个寄存器的生命周期从该寄存器第一次被定义开始,一直到该寄存器中的值最后一次被使用
临时寄存器:没有被提前染色(即不属于abi约定好功能的寄存器),也没有被算法处理过的寄存器。
原理概述将每个虚拟寄存器视作一个点,若两个虚拟寄存器的生命周期有重合的地方,即为它们连一条边,由此构建一个图。我们为图上的每个点染色,要求是一条边上的两个点不能为相同的颜色,且尽量用较少的颜色去染色(其实就是用较少的寄存器)。这就是图着色法对寄存器分配问题的抽象。
这是一个NP完全问题,我们找到最优解会花费较长时间,因此我们通常采用的是一种启发式算法。
算法流程概述算法大致分为以下五个阶段:build, coalesce, simplify, spill, select。
build: 构建香蕉相交图(interference graph)。 ...