自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(30)
  • 收藏
  • 关注

原创 python使用smtplib发送邮件

【代码】python使用smtplib发送邮件。

2024-09-08 09:18:10 132

原创 selenium常用方法

【代码】selenium常用方法。

2024-07-08 09:22:44 311

原创 Python使用ElementTree解析xml的方法

xml.etree.ElementTree是Python标准库中用于处理XML的模块可以通过以下语句引入解析xml时,可以从文件中导入,也可以从string获取。

2024-06-13 15:38:36 319

原创 常用CSS和XPATH元素定位方法

表示id. 表示class空格 表示tag, 表示或(,的优先级比较低,注意加括号):nth-child(n),表示父节点的第n个子节点:nth-last-child(n),表示父节点的倒数第n个子节点Span:nth-of-type(n),表示父节点的第n个类型为span的元素Span:nth-last-of-type(n),表示父节点的倒数第n个类型为span的元素元素1 + 元素2 表示元素2是元素1后面紧跟的兄弟。

2024-05-11 11:26:18 263

原创 设计模式:单例模式

懒汉模式是线程不安全的,因为会有多个线程进入if(instance == nullptr) 的分支。懒汉模式指在第一次获取实例时,才对实例进行初始化。当类的实例只能有一个时,使用单例模式。饿汉模式在类外进行实例的初始化。方法一:使用mutex锁。方法二:使用静态局部变量。

2024-03-24 09:40:01 406

原创 STL源码剖析:vector

vector支持随机存取,而普通指针正好有这样的能力,所以vector提供的是Random Access Iterators,它的迭代器是普通指针。当以push_back()将新元素插入尾端时,若空间不够,则会扩充空间。(重新配置,移动数据,释放原空间)vector和array唯一的区别在于空间运用的灵活性,vector可以动态变化大小。vector维护的是线性连续空间,所以只需要三个迭代器就能提供首尾,容量等信息。vector提供了许多constructors,其中一个允许指定空间大小及初值。

2024-02-21 16:43:24 375 1

原创 STL源码剖析:Allocator

SGI标准的适配器名为 std::allocator。该空间适配器只是对c++的::operator new 和 ::operator delete做了一层浅封装,并且由于封装的缘故反而降低了效率。二级配置器名为__default_alloc_template,其中。一级配置器名为__malloc_alloc_template,其中。在该适配器中,将new和delete的操作细分为四个操作。析构函数有两个版本,第一个版本较简单,第二个版本较复杂。SGI特殊的空间适配器称为 std::alloc。

2024-02-21 10:53:48 425

原创 STL源码剖析:Iterator

迭代器不一定是class,它有可能是native pointer,原生指针无法定义其关联类型,所以需要一个萃取机来分辨所得到的iterator是class还是native pointer,并利用partial specialization(偏特化)来得到其关联的类型。对于外部接口,只接受迭代器和相关参数。对于没有指定类型对应的重载函数时,会调用参数类型为其父类的重载函数。input_iterator_tag: 该种迭代器所指向类型只读。output_iterator_tag: 所指向类型只写。

2024-02-20 16:17:08 527

原创 《操作系统真象还原》 第十七篇:实现堆内存管理

在内存管理系统中,由arena为任意大小的内存分配提供了统一的接口,但是arena是个内存仓库,并不直接对外提供内存分配。内存块描述符将同类arena中的空闲内存汇聚到一起,作为某一规格内存块的入口。内存回收工作分为三大步骤。

2024-02-01 11:01:04 500

原创 《操作系统真象还原》 第十六篇:实现系统调用

printf是vsprintf和write的封装其中vsprintf对字符串进行解析,write将解析后的字符串打印到屏幕上。系统调用分为两部分,一部分是暴露给用户进程的接口函数,另一部分是与之对应的内核具体实现。

2024-02-01 10:32:29 517

原创 《操作系统真象还原》第十五篇:实现用户进程

【代码】《操作系统真象还原》第十五篇:实现用户进程。

2024-01-31 11:30:57 654

原创 《操作系统真象还原》 第十四篇:定义并初始化TSS

TSS由程序员提供,由CPU来维护。用于进程切换时,保存进程的上下文环境。在现代操作系统中,TSS仅用于为0特权级的任务提供栈指针当CPU由地特权级进入高特权级时,会自动从TSS中获取对应特权级的栈指针TSS结构如下:为了访问到TSS,需要在GDT中注册TSS描述符,并将其选择子写入tr(task register)寄存器TSS描述符结构如下:写入tr寄存器的命令如下:ltr “16位通用寄存器” 或 “16位内存单元”//任务状态段tss结构。

2024-01-31 11:12:24 429

原创 《操作系统真象还原》第十三篇:实现io缓冲区和键盘驱动

计划将键盘的输入存入一个io缓冲区中,以备消费者获取。因为缓冲区大小固定,所以采用环形队列的数据结构。64。

2024-01-24 17:52:10 389 1

原创 《操作系统真象还原》第十二篇:实现同步机制:锁

咱们的锁是基于二元信号量来实现的,当信号量为0时,需要阻塞线程。因此在实现锁之前,要先实现线程的阻塞函数。

2024-01-22 18:01:36 385 1

原创 《操作系统真象还原》第十一篇:实现多线程调度

线程调度分为三个步骤。

2024-01-20 16:04:49 574

原创 《操作系统真象还原》第十篇:实现线程相关数据结构和双向链表

/双向链表的结点,因为我们只需要结点本身的地址,所以不需要数据成员//前驱结点//后继结点//双向链表数据结构。

2024-01-20 15:52:44 482

原创 《操作系统真象还原》第九篇:实现内存管理系统

将物理内存分为两个部分,一部分为内核物理内存池,另一部分为用户物理内存池。由于进程使用的是虚拟内存,所以还需要一个虚拟内存池来管理虚拟内存空间。两个内存池各占剩余内存的一半。分配内存可分为以下三个步骤。

2024-01-17 11:15:19 429

原创 《操作系统真象还原》第八篇:实现字符串操作函数,实现位图(bitmap)

对于内存管理系统,计划用位图来进行管理,位图中一个bit对应一页(4KB).当该bit为1时表示该页被分配,当该位为0时表示该页空闲。位图和内存的关系如下图所示:1//位图的长度,以字节为单位//位图数组的首地址//初始化位图//全部初始化为0//判断位图的某个位是否为1//索引数组下标//索引字节内的位//在位图中寻找连续的cnt个位,找到则返回起始下标,否则返回-1//先找到第一个有0的bytebyte_idx++;//如果没找到则返回-1。

2024-01-17 11:06:29 313

原创 《操作系统真象还原》第七篇:实现assert断言,并改用makefile来编译

在ASSERT排查出错误后,需要在关中断的情况下打印报错信息。

2024-01-15 15:04:01 379

原创 《操作系统真象还原》第六篇:改进中断处理程序,设置可编程计数器8253

上一节中我们设置了中断处理程序的入口,但是还未指定中断处理程序。接下来我们将让中断处理程序入口指向c语言编写的中断处理函数。首先声明中断处理程序数组,可以根据中断号进行访问同时为了便于调试,添加中断异常名接下来便是注册处理函数,和初始化异常名称数组最后修改kernel.S,使中断入口能跳进响应的中断处理程序可编程计数器8253介绍8253结构如下:计数器0用于产生实时时钟信号,要对其进行初始化,需要先写入控制字寄存器再写入计数器0控制字寄存器结构入下:其中工作方式如下:由于目前我们只开启了时钟中断

2024-01-12 16:35:05 361

原创 《操作系统真象还原》第五篇:编写中断处理程序,开启中断

31是intel保留,所以我们的中断向量号只能从32号用起,所以这里先编写到0x20号中断。IDTR和GDTR结构类似,低16位表示界限,高32位表示起始地址。ICW1->ICW4必须按顺序编写。

2024-01-12 09:30:45 381

原创 《操作系统真象还原》第四篇:完善内核,实现打印函数

​ 以CRT Controller Register为例,默认情况下,Address Register的端口地址为0x03D4,Data Register的端口地址为0x03D5。​ 所以对这类分组的寄存器的操作方法是先在Address Register中指定寄存器的索引值,然后在Data Register寄存器中对所索引的寄存器进行读写操作。Address Register作为数组的索引,Data Register作为寄存器数组中该索引对应的寄存器。

2024-01-09 16:56:17 419 1

原创 《操作系统真象还原》第三篇:解析ELF文件头,加载内核

然后在开启分页后,解析内核文件,并跳转进内核执行。program header结构如下。elf header中的数据类型。初始内核很简单,就是一个无限循环。通过以下命令编译、链接并写入硬盘。elf header结构如下。首先将内核从硬盘读入内存。

2024-01-08 15:00:49 1051 1

原创 《操作系统真象还原》第二篇:启动分页机制

​ 处理器准备了一个高速缓存,可以匹配高速的处理器速率和低速的内存访问速度,它专门用来存放虚拟地址页框和物理地址页框的映射关系,这个缓存就是TLB,即Translation Lookaside Buffer,俗称快表。​ 只有P位为1的页表项才能在TLB中,TLB并不自动更新,由操作系统开发人员维护。二级页表相比一级页表可以动态地创建页表,达到节省空间的目的。将虚拟地址分为高10位,中间10位,低12位三部分。页目录项和页表项结构如下,均为32位。接下来正式开启三部曲。

2024-01-03 09:40:24 1021 1

原创 《操作系统真象还原》第一篇:编写MBR,加载loader,构建GDT,检测内存容量,进入保护模式

GDT是全局描述符表(Global Descriptor Table),用于索引描述符寄存器GDTR(GDT Register)用来存储GDT的内存地址及大小,GDTR是一个48位寄存器GDTR第0-15位为GDT界限,第16-47位为GDT内存起始地址对此寄存器的访问只能通过lgdt指令,指令格式为 lgdt 48位内存数据进入保护模式后,段的信息增加了很多,需要段描述符来描述一个段的各种属性。在保护模式下,内存访问依旧是“段基址:段内偏移地址”的形式,但段寄存器中是选择子,而不是段基址。

2023-12-22 12:10:49 1007

原创 计算机启动过程和硬盘接口简单介绍

data:用于数据的读取和写入error:读取失败时,会记录失败的信息。写入时,用于指定命令的额外参数sector count: 用于指定待写入或待写入的扇区数。(每成功一次便减1)LBA low:记录LBA(Logical Block Address)地址的0-7位LBA mid:记录LBA的8-15位LBA high:记录LBA的16-23位command:记录命令,identify:0xEC,识别硬盘;read sector:0x20,读扇区;

2023-12-21 20:01:14 398

原创 x86汇编常见语法(GNU格式)

x86汇编常见指令

2023-12-19 21:19:44 1165

原创 侯捷c++学习笔记-String类

关于侯捷老师的c++教学视频string类部分的要点总结和代码分享。1.有指针对象的类,要浅拷贝和深拷贝的问题,避免发生内存泄漏和野指针问题,要自己写构造函数(new)和析构函数(delete)2.拷贝赋值( = ),要检测自我复制(self assignment) ,否则在delete自己的时候会造成错误。3.new的过程//分配内存(内部调用malloc(n) ) pc = static_cast < Complex * >(mem);

2023-04-17 11:14:06 112

原创 候捷C++学习笔记-Complex类

侯捷c++视频学习总结

2023-04-16 17:20:34 159 1

原创 30天自制操作系统(day1)

30天自制操作系统第一天内容

2022-11-08 20:59:30 1852 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除