自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 分页机制详解

##### 解决内存不足> 解除线性地址与物理地址一一对应的关系,然后将它们的关系重新> 建立。通过某种映射关系,可以将线性地址映射到任意物理地址。>> 对于地址转换这种实时性较高的需求,查找页表的工作也是由硬件完成的。分页机制要建立在 分段机制的基础上,也就是说,段部件的工作依然免不了,所以,分页只能是在分段之后进行的,分页机制的作用有两方面。- 将线性地址转换成物理地址。- 用大小相等的页代替大小不等的段。

2023-10-14 11:23:36 520

原创 Rust dyn - 动态分发 trait 对象

dyn是关键字,用于指示一个类型是动态分发(dynamic dispatch),也就是说,它是通过trait object实现的。假设有一个几何图形的类层次结构,例如圆形(Circle)和矩形(Rectangle),每种几何图形都有一个计算面积的方法。现在编写一个函数,可以计算不同类型几何图形的总面积。类型的参数来接受几何图形的数组。来表示这个特征,并在每个几何图形中实现这个trait。方法,计算它的面积,并将结果累加到总面积中。创建一些具体的几何图形实例,并将它们传递给。trait的具体类型的引用。

2023-08-02 15:19:48 1026

原创 让MBR使用硬盘

在 CHS 方式中扇区的编号是从 1 开始的,不是 0,不是 0,原谅我说了两次,良苦用心你懂的,所以 0 盘 0 道 1 扇区其实就相当于 0 盘 0 道 0 扇区,它就是磁盘上最开始的那个扇区。硬盘的随机存取是靠磁头臂不断移动实现的,磁头臂移动到目标位置的时间称为寻道时间,如果存储的数据不连续,这一块那一片的,磁头就得不断调整位置,这是机械式硬盘不可避免的,这便是硬盘的瓶颈所在,所以一般的硬盘都将寻道时间作为重要参数。当处理器在16 位模式下运行时,也可以使用32 位的寄存器,执行32 位的运算。

2023-06-26 23:33:26 261

原创 计算机启动

BIOS 还做了一件伟大的事情,建立了中断向量表,这样就可以通过“int 中断号”来实现相关的硬件调用,当然 BIOS 建立的这些功能就是对硬件的 IO 操作,这就是 BIOS 称为基本输入输出系统的原因。8086之前是程序加载到固定位置,也就是程序员看到的完全是真实的内存。BIOS 最后一项工作校验启动盘中位于 0 盘 0 道 1 扇区的内容,此扇区末尾的两个字节分别是魔数 0x55 和 0xaa,BIOS 便认为此程序便是主引导记录 MBR,便加载到物理地址 0x7c00。的作法,免得过早被覆盖。

2023-06-20 21:02:22 11543

原创 Rust裸指针的安全性实例

如果是空指针,则创建一个名为的新实例,并将其封装到一个Box对象中。然后通过函数将其转换为裸指针(即将其所有权转让给全局指针这个操作非常危险,因为裸指针的生命周期并没有明确规定,所以需要注意避免出现内存泄漏或多重释放的问题。如果不是空指针,则说明调度器已经被初始化过了,不能重复初始化。在这种情况下,我们会通过kBUG!()宏打印一个日志信息,然后通过panic!()函数抛出一个恐慌(即类似于抛出一个异常)。这将导致程序崩溃并终止运行。

2023-05-10 22:45:28 622 1

原创 第八章 硬盘和显卡的访问与控制(2)

用于加载用户程序的物理地址phy_base是16字节对齐的,而用户程序中,每个段的汇编地址也是16字节对齐的。因此,每个段在内存中的起始地址也是16字节对齐的,将它们分别右移4位,就是它们各自的逻辑段地址。代码使用ror循环右移(ROtate Right),循环右移指令执行时,每右移一次,移出的比特既送到标志寄存器的CF位,也送进左边空出的位。68~74行是循环体,每次循环开始后,BX总是指向需要重定位的段的汇编地址,而且都是双字,需要分别传送到寄存器。用户程序头部内,偏移为0x06处的双字,存放的是。

2023-03-16 22:16:55 480 1

原创 第8章 硬盘和显卡的访问与控制(1)

本章把主引导扇区改造成一个程序加载器,功能是加载用户程序,并执行该程序(将处理器的控制权交给该程序)

2023-03-14 22:50:27 286

原创 第七章-X86汇编语言从实模式到保护模式

AX清零,1传到寄存器,开始累加。同100比较AX中得到累加和。得到累加和,要把各数位分解出来,并准备在屏幕上显示。保存在栈中,栈段,由段寄存器SS指向。需要栈指针寄存器来指示下一个数据应当压入栈内的什么位置,或者数据从哪里出栈40~42行初始化和的内容44行 除数传送到每次除法结束后,都做一次判断,如果商为0的话,分解过程可以提前结束,必须记住实际有多少个数位。45行寄存器清零,用来累计47到53行也是循环体,每次执行,分解一个数位。每次分解加一,表明多一个数位48,49行,将清零,和一起形成32

2023-03-13 18:11:41 819

原创 MOV指令使用

mov用于数据传送。之后分为目的操作数和源操作数,目的操作数必须是通用寄存器或者内存单元:源操作数可以是具有相同数据宽度的通用寄存器或者内存单元,还可以是立即数。传送指令只影响目的操作数内容,不改变源操作数内容。

2023-03-03 18:13:50 3900

原创 8086内存分段机制

另一个点是段的大小的划分,这个比较随意,但是为了让段不重叠,最多可以将1MB的内存分成65536个段,段寄存器只有16位段寄存器就不够存了。接着,任务是定义段地址并设置处理器的段寄存器,其中最重要的是段地址的选取。为了解决这个问题,8086处理器在形成物理地址时,先将段寄存器的内容左移4位(相当于乘以十进制的16)形成20位的段地址,然后再同16位的偏移地址相加,得到20位的物理地址。有一个难理解的点,8086的段寄存器和IP寄存器都是16位的,但是为了使它有1MB的内存,提供了20根地址线。

2023-03-01 21:09:34 559

原创 UEFI启动的七阶段笔记

研究起点是CPU收到ResetVector信号后,开始执行第一行代码,一直到计算机关机/重启/崩溃,被划分为七个不同阶段。

2023-02-27 20:19:03 674

原创 多道程序与分时多任务--rCore[3]

计算机硬件在快速发展,内存容量在逐渐增大,处理器的速度也在增加,外设 I/O 性能方面的进展不大。于是就想到,让应用在执行 I/O 操作或空闲时,可以主动 释放处理器 ,让其他应用继续执行。

2022-12-30 01:24:50 1163 3

原创 在裸机上输出Hello,world! [rCore-lab1]

非常简单的“Hello, world”应用程序,实际上有着多层硬件和软件工具和支撑环境隐藏在它背后,才让我们不必付出那么多努力就能够创造出功能强大的应用程序。生成应用程序二进制执行代码所依赖的是以 编译器 为主的开发环境;运行应用程序执行码所依赖的是以 操作系统 为主的执行环境。这次本文章梳理文档,要在裸机上实现输出Hello,world!./os/src├── bootloader(内核依赖的运行在 M 特权级的 SBI 实现,本项目中我们使用 RustSBI)

2022-11-21 22:34:12 999

原创 Rust 错误处理

大多数语言并不区分可恢复错误和不可恢复错误,并采用类似异常这样方式统一处理他们。Rust 没有异常。相反,它有 Result 类型,用于处理可恢复的错误,还有 panic!宏,在程序遇到不可恢复的错误时停止执行。

2022-11-13 17:52:19 773

原创 Rust 所有权、引用与借用

相比之下,在堆上分配内存则需要更多的工作,这是因为分配器必须首先找到一块足够存放数据的内存空间,并接着做一些记录为下一次分配做准备。可变引用有一个很大的限制:如果你有一个对该变量的可变引用,你就不能再创建对该变量的引用。Rust释放堆的方式为:对于某个值来说,当拥有它的变量走出作用范围时,内存会立即自动的交还给操作系统。x由于是i32类型实现了copy trait,往函数里传的是x的副本,x在第8行以后仍然是有效的。当变量离开作用域时,Rust会自动调用drop函数,并将变量使用的heap内存释放。

2022-11-11 19:56:15 560

原创 选择和循环结构的机器级表示

此处机器级代码是先判断了a>17和a

2022-10-20 11:11:53 429

原创 函数(过程)调用机器级表示(一)

- 准备阶段:前三行第一条指令总是把就的EBP的值压入栈中此时ESP指向此处第二条mov指令后,EBP也指向此处,栈底就此形成第三条指令减法,ESP-24,栈顶移动,留足空间- 分配局部变量:4、5条125送到ebp-12的地址80送到ebp-8的地址- 准备入口参数:6-9条80送到ESP+4(即对t2参数赋值)125送到esp(即对t1赋值)

2022-10-19 20:51:51 818

原创 从汇编指令解决浮点数疑问

(右边多一条赋值语句)**问题:使用老版本gcc -O2 编译时,程序一输出0,程序二输出1,是什么原因造成的?**

2022-10-17 21:46:52 1453

原创 IA-32定点算术指令

ALU运算结束后,标志信息送到标志寄存器中,通过多路选择器,把加法器选择输出送回0号寄存器,0号寄存器为80000001。译码后,得知功能R[eax]

2022-10-17 15:53:07 710

原创 IA-32传送指令执行

IA-32常用传送指令–通用数据传送指令MOV:一般传送,包括movb、movw和movl等MOVS:符号扩展传送,如movsbw、movswl等MOVZ:零扩展传送,如movzwl、movzbl等XCHG:数据交换

2022-10-16 16:43:33 368

原创 IA-32指令系统概述

IA是Intel Architectture的缩写。

2022-10-16 15:27:09 483

原创 程序转换概述

可执行的指令的集合,包括指令格式、操作种类以及每种操作对应的操作数的相应规定;左边为位移量,中间是机器指令,右边为汇编指令(没有带长度后缀,常数十六进制)-操作数所能存放的寄存器组的结构,包括每个寄存器的名称、编号、长度和用途;-指令执行过程的控制方式,包括程序计数器、条件码定义等。-操作数在存储空间存放时按照大端还是小端方式存放;-操作数所能存放的存储空间的大小和编址方式;-指令获取操作数的方式,即寻址方式;地址起始不是0,而是实际的虚拟地址。-指令可以接受的操作数的类型;ISA是必不可少的抽象层。

2022-10-15 20:31:56 190

原创 运算电路基础

在整数加/减运算部件基础上,加上寄存器、移位器以及控制逻辑,就可实现ALU、乘/除运算以及浮点运算。

2022-10-12 22:23:13 604

原创 系统调用的实现

系统调用是内核与用户空间程序交互的接口很多情况下,用户进程需要获得系统服务(调用系统程序),这时就必须利用系统提供给用户的“特殊接口”——系统调用了,它的特殊性主要在于。

2022-07-19 11:33:18 876

原创 深入理解epoll

同 I/O 多路复用和信号驱动 I/O 一样,Linux 的 epoll(event poll)API 可以检查多个文件描述符上的 I/O 就绪状态。epoll是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。...

2022-07-15 17:02:31 904

原创 C++多态实现原理

多态:当不同的对象去完成同一件事时会产生出不同的状态。

2022-07-12 14:54:15 457

原创 TCP流量控制_(滑动窗口)

一、TCP vs. UDPTCP可提供可靠的数据传输而UDP无法做到,那我们为什么还用UDP?·使用UDP传送单条消息的开销要比TCP小·响应式通信,UDP的速度要比TCP快。DNS是应用UDP的绝好例子。但使用UDP又需要可靠性保证的应用程序必须自行实现可靠性保障功能。如果需要更高级的流量控制和拥塞控制,最好直接用TCP。下面我们粗浅的了解一下TCP的流量控制二、滑动窗口(Sliding Window)请仔细阅读下图(上图在接收端用小方块表示1K数据,.

2022-05-30 21:31:01 212

原创 TCP状态转移图

先回顾一下三次握手和四次握手1、建立连接协议(三次握手)(1)客户端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的报文1。(2)服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN标志。因此它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯。(3)客户必须再次回应服务段一个ACK报文,这是报文段3。2、连接终止协议(四次握手)   由于TCP连接是全双工的,因此每个方向

2022-05-30 21:08:08 445

原创 C++引用

因为在看书时多处看到引用但理解不深,思考之后,决定写一篇博客。一、基本语法引用 作用:给变量起别名int a=10;//操纵这块内存起一个b,也去操纵这块内存。数据类型与原来一样 数据类型 &别名 = 原名int &b=a;b=20;cout << a << endl; 20修改同一块内存二、注意事项:引用必须初始化,且一旦初始化后不可以再改变。三、引用做函数参数,可以简化指针修改实参int mysw

2022-05-24 17:41:40 77

原创 Unix进程原语(1)

在写进程池之前,我们再来看看进程原语函数。(之前没有整理出来)1.forkfork会创建出一个子进程,子进程有自己的虚拟地址空间0-4G,父进程继续执行后面的代码,子进程完全复制(clone)了父进程一份(0-3G),那么如何标识子进程父进程的区别,PCB中的pid号不同。fork函数十分简洁没有参数, 返回用来存放pidfork:(1)调用一次,返回两次。因为是clone,所以整段代码在父子进程中都有,在父进程中调用返回子进程的PID,在子进程中调用则返回0。读时共享,

2022-05-16 22:36:08 176

原创 信号量实现生产者消费者

我们用条件变量和互斥量实现了生产者消费者之后,也可以试试用信号量。甚至会更加简单。可能大家对信号量还比较陌生1.介绍信号量信号量与互斥量信号量相当于初始化值为N的互斥量。互斥量保护了共享数据,但也使并行的线程变成串行,执行效率变低了。互斥量一次只有一个线程可以访问公共区域,信号量可以同时有N个线程访问共享数据信号量与信号:信号量(semaphore)和信号(signal)无关,完全是两回事。O(∩_∩)O哈哈~信号量不只能用于线程中,也可以用于进程间同步。2.函数用法

2022-05-08 13:36:37 479

原创 服务器端客户端最小模型(TCP)

前两天我们已经知道了服务器端和客户端交互的过程那么废话不多说,talk is cheap,直接上代码。(已做代码详细注释)(先不考虑出错处理)server.c#include<stdio.h>#include<sys/socket.h>#include<netinet/in.h>#include<string.h>//bzero#include<arpa/inet.h>//inet_ntop#inclu...

2022-05-06 22:23:24 474

原创 网络IPC:socket引入

本文开始引入网络进程间通信(network IPC),套接字网络进程间通信接口,进程用该接口能够和其他进程通信,无论它们是在同一台计算机上还是在不同的计算机上。同样的接口既可以用于计算机间通信,也可以用于计算机内通信。socket函数为了了解本函数,我们要先理解一些概念。socket这个词可以表示很多概念:在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通讯中的一个进程,“IP地址+端口号”就称为socket。在TC...

2022-05-05 21:58:40 1368

原创 TCP连接建立/断开

网络应用(进程)IP+端口号三次握手 四次握手...

2022-05-04 22:02:46 407

原创 ARP协议(网络基础)

1.模型网络TCP/IP模型TCP/IP通信过程2.数据包封装封装是分层联网协议的一个重要原则。传输层及其以下的机制由内核(内核中的TCP/IP协议栈)提供,应用层由用户进程提供应用程序对通讯数据的含义进行解释,而传输层及其以下处理通讯的细节,将数据从一台计算机通过一定的路径发送到另一台计算机。应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation)。 不同的协议层对数据包有不同的...

2022-05-03 15:37:30 2390 1

原创 文件究竟是如何被存储/删除的?

我们的磁盘很大,我们日常存储删除的文件又非常多,磁盘一个是扇区512字节它们用来存数据,能存进去还能读出来,那么这么多文件是如何被找到的呢?这就需要一个复杂的文件系统。本文章以ext2文件系统为例做具体讲解(ext4原理类似)首先我们需要先把文件系统组成搞清楚。结构图:我们知道,一个磁盘可以划分成多个分区,每个分区必须先用格式化工具(例如某种mkfs命令)格式化成某种格式的文件系统,然后才能存储文件,格式化的过程会在磁盘上写一些管理存储布局的信息linux把磁盘分成.

2022-04-24 21:29:40 462

原创 文件I/O(3)

lseek记录读写位置fseek文件流指针 偏移量 SEEK_SET文件最开头,当前,末尾基准坐标偏移量off_t返回偏移指针位置到文件最开头有多少个字节怎么看里面内容od -tcx abc拓展文件一定要有一次写操作#include<stdio.h>#include<fcntl.h>#include<sys/types.h>#include<unistd.h>#include<sys/stat.h>#incl

2022-04-24 18:34:13 188

原创 补充:线程分离态

pthread_detach一般情况下,线程终止后,其终止状态一直保留到其它线程调用pthread_join获取它的状态为止。但是线程也可以被置为detach状态,这样的线程一旦终止就立刻回收它占用的所有资源,而不保留终止状态。不能对一个已经处于detach状态的线程调用pthread_join,这样的调用将返回EINVAL。如果已经对一个线程调用了pthread_detach就不能再调用pthread_join了。...

2022-04-20 22:11:52 74

原创 线程创建、终止、回收

学习了线程概念之后,我们就可以学习一些函数了。1.pthread_create 创建线程pthread_t *thread:传递一个pthread_t变量地址进来,用于保存新线程的tid(线程ID)const pthread_attr_t *attr:线程属性设置,如使用默认属性,则传NULLvoid *(*start_routine) (void *):函数指针,指向新线程应该加载执行的函数模块返回值:成功返回0失败返回errno,当函数调用失败多线程的时候,再去设.

2022-04-19 22:39:06 935

原创 把线程概念讲清

要了解线程,首先就要联系我们学过的进程1、线程和进程的关系1.线程是一个轻量级进程(light-weight process),也有PCB,创建线程使用的底层函数和进程一样,都是clone。2.从内核里看进程和线程是一样的,都有各自不同的PCB,但是PCB中指向内存资源的三级页表是相同的。Unix中如何管理内存,PCB记录地址表,采用三级页面每个页面默认4096字节大小每四个字节看成一个指针,一个页面1024个指针,指向1024个页面。三级页面寻址到G(Linux实际用的四

2022-04-19 18:16:13 624

空空如也

空空如也

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

TA关注的人

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