自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 写一个简单的服务器

这里我们在运行服务器后 在新窗口中测试 写入一个hello 然后服务器中输出了hello 并回了一个大写的HELLO。实现一个服务器 客户端发送一个小写的hello给服务器 服务器返回一个大写的HELLO。接下来先用nc指令测试 这里我们使用127.0.0.1 本地ip测试。1.打开用vim创建一个server.c文件 开始编写服务器代码。

2022-11-02 20:54:41 825

原创 RSIC-V指令及介绍(1)

add rd, rs1, x0 # rd = rs1 + x0 x0代表零号寄存器 只读 代表0 这个语句就是把rs1赋给rd。s0 - s11 对应的编号x8 - x9 和 x18 - x27的寄存器用来作为保存寄存器,保存原进程中的关键数据避免在函数调用过程中被破环。addi rd, rs1, 10 # rd = rs1 + 10 针对寄存器和立即数的加法操作。

2022-09-12 18:38:35 3961

原创 编译器-最优寄存器分配

而全局寄存器分配是刚好相反的 在comile time需要跟多的时间 但是performance会表现很好 注意全局寄存器分配不需要像局部分配一样在每一个block结束以后需要把所有的def和use都store 然后在新的block中又把需要的所有def和use进行load 全局分配需要通过conlict graph算法求出以插入最少的store和load为代价使得代码能流畅的作为一个整体运行下去。指需要在最左边的block中def b后面插入一个store b 在use b之前插入一个load b即可。.

2022-08-18 02:52:26 858

原创 编译器-条件/循环代码生成

BB代表的basic block 这里遇到分支branch 或 jump 或 一个新的label 都是一个basic block。在得到AST之后 编译器会构建这样的一个CFG作为一部分中间表达 每一个baisc block里面有一些线性的汇编指令。在优化代码的时候 划分成这些basic block会使逻辑更加清晰 使得优化工作更加简单。这里的com_LT是比较less than 如果r1比r2小 返回true到r3。cbr是condition branch 如果r3是true 走L1 否则走L2。...

2022-08-15 20:03:33 329

原创 编译器-基于AST表达式代码生成

执行完t2 = Expr(node.right);接下来return后 就回到了乘号Op的t1 = Expr(node.left);接下来执行下一行t2 = Expr(node.right);已经执行完毕 return r3 开始执行t2 = Expr(node.right);首先第一步call root 加号+ 调用Expr函数 push进栈中 +是Op 所以会call t1 = Expr(node.left);然后再次进入到Op中的t1 = Expr(node.left);...

2022-08-14 22:36:43 452

原创 编译器-语法制导翻译STD

GNU Bison 是一个通用的解析器生成器,它可以将注释的无上下文语法转换为使用 LALR (1) 解析表的确定性 LR 或广义 LR (GLR) 解析器。一旦您熟练使用 Bison,您可以使用它开发广泛的语言解析器,从简单的桌面计算器中使用的解析器到复杂的编程语言。最后Term作为$1 mult作为$2 Factor作为$3 它们的cost分别为 4 3 1 加起来是8 传给上面的$$也就是说 每次在LR(1)文法中执行reduce 7的时候 执行的其实是$$ = $1来生成AST。...

2022-08-14 19:09:10 284

原创 编译器-LR(1)

这里其实是无法明确置换的 比如Expr+Term*Factor可以reduce 4 但同时也可以reduce 6形成Expr+Term*Term 也是合规的 这就说明虽然我们通过表达式逻辑可以很容易的做出选择 但是系统没有一个明确的算法去确定合适的选择。但其实在这个例子中就能发现 一旦shift读取一个字符到栈中 只要有合理的置换方式 就需要一直置换下去 直到没有任何一个可以置换且遵循follow的时候 才会继续去shift读取下一个字符到栈中。发现d可以置换成B且不违背follow集 所以形成了aAB。.

2022-08-13 04:22:12 266

原创 编译器-LL(1)-First集与Follow集

first集合非常简单 但是要注意follow集合 主要是先看语法箭头右边的内容找到需要判断的符号类型所在位置 如果在行尾 那么就包含箭头左边符号类型的所有follow集合 其次如果不在行尾 就包含后面紧跟着的符号类型的first集 但是要注意的是如果紧跟着的符号类型在first集可以为∈ 那么又要包含箭头左边的符号类型的follow集。//同时第三行Term ‘可以为∈ 那么说明Factor可以作为Term的最后出现 所以要包含Follow(Term)第三行:Term → Factor Term '..

2022-08-11 15:45:08 653

原创 编译器-LL1-parsing tree左右递归

第八步:此时读取的是乘号* Term '有三个选择 Term ' → * Factor Term ' | / Factor Term ' | ∈ 刚好对应上了* 而且Term作为一个项也是不允许把*作为结尾的 不能选空 所以构建第一个 并开始读取下一个字符y。第四步:此时读取的是加号+ 而Term '中有三个选择Term ' → * Factor Term ' | / Factor Term ' | ∈ 然而即不是*也不是/ 所以只能选择∈。接下来用转换好的右递归来parse x + 5 * y。.

2022-08-10 22:20:00 611

原创 编译器-上下文无关语法

在计算机高级语言中 我们把变量名(identifier) 这一个类作为计算机语言表中的一个symbol 在scanner(词法分析)的过程中 无疑就是传入了一个字符串 返回一个类别 把各种类别组合在一起 形成了context-free language 然后用特定的grammar语法定义去判断这一堆类别组合是不是符合所规定的语法 如果不合规就会出现编译错误。这时在数学中(a + b)是一个factor c也是一个factor (a + b) * c是一个term。......

2022-08-10 16:31:45 258

原创 编译器-NFA转DFA

d1是E-closure of q1 即为集合{q1,q2,q3,q4,q6,q9} 这个集合中没有任何一个state走的通a 所以为d空 走b的话集合中q4可以走到E-closure of q5 是个集合需要设为d2 同理走c的话q6可以走到E-closure of q7 是个集合 需要设为d3。d3是E-closure of q7 走a走不通 设为d空 走b的话q4可以走到E-closure of q5 就是d2 走c的话q6可以走到E-closure of q7 即为自己d3本身。.........

2022-08-07 20:58:53 1370

原创 编译器-正则表达式转NFA

2.Concatenation 串联、链接的意思。Regular operation (正则操作符)2.Concatenation在NFA中的体现。1.Union 或的意思。3.Star 重复的意思。a (b U c)* 的 NFA。3.Star在NFA中的体现。(b U c)* 的NFA。b U c 的NFA。...

2022-08-07 15:32:58 222

原创 编译器-有限自动机和正则表达式

编译器的词法分析是基于finite automata(有穷自动机) 和 regular expression(正则表达式)alphabet:finite set of symbols 字母表:有限符号的集合string:sequence of symbols from a given alphabet 字符串:给定字母表的符号序列language:set of string 字符串的集合例如x12 = 32;中有token;......

2022-08-05 22:48:20 578

原创 编译器概述-指令调度的概念

假设每个指令为了得到结果都有一个周期load为3周期mult为2周期div为5周期store为2周期add为1周期注意:这里的周期可以理解为占用的cpu运算资源时间r1r2r3r4r5r6r7x可以看到 第一个load从周期1开始到3经历了1 2 3 三个周期第二个load不依赖于第一个load 所以不需要等待第一个load执行完毕 就可以直接开始执行第三个mult需要依赖于r1和r2的数据 所以必须等上面都执行完毕 再从周期5开始执行。...

2022-08-05 19:06:06 846

原创 编译器概述-寄存器分配的概念

可以看出 当只有两个物理寄存器的时候 不能把每一个虚拟寄存器都映射到物理寄存器上 而是需要临时存入内存 这种情况英文中叫spill 就是溢出到内存中的意思 register allocation会尽可能的不去发生spill的情况。其次这里发现r1和r2都存储着真实的变量(variable)a和b 而r3却是一个中转的临时变量(temporaries) 实际中的汇编是没有变量这个概念的 实际中只有寄存器和内存地址。//第一个行抽象汇编指令实际是第二行的简化 第二行才是抽象汇编指令的完整写法。......

2022-08-05 16:06:07 922

原创 编译器概述-结构和主要组件

并不是说所有的编译器优化都能保证提高代码速度 只能说优化是有可能提高代码速度 例如上面那个优化就会使得代码在cpu中运行的负担加重 因为t其实只是维护了两个变量的相加 但却要多占用一个寄存器的位置 到不如直接算两遍a+b了 如果t中维护了很多变量 显然这个优化是有用的 所以编译器中的优化无疑不是绝对意义上的智能优化。虽然说看上去优化的这个过程和cpu内部设计是无关的 但是其实这也不是绝对的 寄存器的数量 cpu内部的设计逻辑其实也会影响到优化设计的过程。看一个例子 x = a*b + c*d;...

2022-08-04 19:56:20 369

原创 进程-信号的基本概念和产生函数

信号是Linux进程间通信的最古老方式。信号是软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式。信号可以导致一个正在运行的进程被另一个正在运行的异步进程中断,转而处理某一个突发事件。这里我们学习的信号就是属于这么一种中断。我们在终端上敲Ctrl + c就产生了一个中断,相当于产生了一个信号,接着就会处理这个一个中断任务信号的特点:1.简单2.不能携带大量信息3.满足某个特设条件才能发送。...

2022-08-04 16:48:32 200

原创 进程-共享存储映射

其实linux系统给我们提供了创建匿名映射区的方法,无需依赖一个文件即可创建映射区。共享内存可以说是最有用的进程间通信方式,也是最快的PC形式,因为进程可以直接读写内存,而不需要任何数据的拷贝。offset:以文件开始处的偏移量,必须是4k的整数倍,通常为0,表示从文件头开始映射。addr:指定映射的起始地址,通常设为NULL,由系统指定。fd:由open返回的文件描述符,代表要映射的文件。存储映射I/O使一个词磁盘文件与存储空间中的一个缓冲区相映射。参数:addr:使用mmap函数创建的映射区的首地址。.

2022-08-03 16:00:36 196

原创 进程-exec/僵尸和孤儿进程/wait/管道

任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。孤儿进程父进程先于子进程结束则子进程成为孤儿进程,子进程的父进程成为init进程,称为init进程领养孤儿进程。成功清理掉的子进程id失败-1(没有子进程)僵尸进程进程终止,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸进程。...

2022-08-02 02:17:01 247

原创 进程-CPU和MMU/环境变量/创建子进程

Linux操作系统是一个多任务多用户的开源操作系统多任务并发多用户同一时间点了可以有多个用户登陆到一台计算上环境变量是指在操作系统中用来指定操作系统运行环境的一些参数通常有以下特征1.字符串(本质)2.有统一的格式名=值[值]3.值用来描述进程环境信息PATH用来记录文件的可执行路径echo$PATHSHELL记录当前的命令解析器是什么当前Shell它的值通常是/bin/bashTERM。......

2022-07-30 22:31:44 662

原创 Linux基础-内建函数

空洞文件的作用例如当我们在网上下载一个10个g的文件的时候刚开始下载的时候磁盘上就多了一个10个g的文件这里就使用空洞文件进行填充的填充后就方便多线程下载时文件指针的移动。这时候发现aa的大小变为了2015因为我们在最后写了一个字节的a在文件中出现了2000个字节的空洞。这时候发现两个文件一样大证明写的没有问题。用lseek函数做一个文件的扩展。这时候发现aa文件有14个字节。输出了这个文件的所有信息。...

2022-07-29 14:33:55 218

原创 Linux基础-gdb/makefile/库函数工作流程

PHONYclean的作用就是当我们在目录下touchclean后再makeclean因为makefile的工作原理系统会把touch出来的clean一直当成最新的就不会执行makefile中的clean加了.PHONYclean就会生成尾目标就能解这个问题。⚠️这么写的好处就是当需要编译的文件有很多的时候可能对整体的一次编译就需要耗时几个小时如果按照第二个版本的makefile去写当我只修改了例如add.c中的一行代码再次编译的时候系统只会重新编译add.c而不是所有文件。......

2022-07-26 22:03:39 410

原创 Linux基础-vim/静态库/共享库

Ctrl+l清屏指令(ubuntu)创建终端。

2022-07-25 18:15:25 410

原创 Linux基础-压缩/网络进程/服务器基础指令

⚠️限定不允许匿名用户在任意目录直接切换只能在一个指定的目录范围内工作需要在ftp服务器上创建一个匿名用户的目录——匿名用户的根目录。进入配置文件在第十行(最后)加上/home/sam/NFSshare*(rw,sync)这里的*是一个网段代表从哪里共享出去的rw是读和写的权限sync是实时更新。使用useradd创建用户-s后内容代表用bash指令解析器-g后面的内容是属于哪个组-d是存放哪个目录下-m是没有userA则创建一个。......

2022-07-24 21:17:27 305

原创 Linux基础-指令操作

没有了-s就是硬链接hello.c的硬链接数+1这个硬链接有点像是指针如果查看硬链接的大小那么和源文件一样如果对硬链接做修改也会修改源文件内容hello.c和hello.hard指的都是同一块存储单元所以删除hello.c并不会影响hello.hard他们之间没有依赖关系访问时候的本质其实就是直接访问存储单元。显示filename文本文件的属性信息。/devdev是Device的缩写该目录下存放的是Linux的外部设备在Linux中访问设备的方式和访问文件的方式是相同的。...

2022-07-23 18:45:41 1046

原创 c++设计模式-行为型模式

用来对类或对象怎样交互和怎样分配职责进行描述 定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 输出结果: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。 案例: 命令模式 将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销操作。命令模式

2022-07-21 17:58:36 324

原创 c++设计模式-结构型模式

代理模式的定义为其他对象提供了一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。在生活中代理模式的例子有很多比如我们想要访问外网youtube但是无法直接访问就需要用到代理服务器或者说当很多很同时向一个网页发起请求的时候会变得很卡这时候可以在中间设置一个代理服务器处理延迟初始化和缓存查询结果的工作输出结果用户名和密码正确,验证通过系统启动用户名或密码错误权限不足。......

2022-07-20 21:44:05 522

原创 C++设计模式-工厂

应用场景对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。

2022-07-20 16:37:20 877

原创 c++设计模型-面向对象设计原则

对于面向对象软件系统的设计而言,在支持可维护性的同时,提高系统的可复用性是一个至关重要的问题,如何同时提高一个软件系统的可维护性和可复用性是面向对象设计需要解决的核心问题之一。在面向对象设计中,可维护性的复用是以设计原则为基础的。每一个原则都蕴含一些面向对象设计的思想,可以从不同的角度提升一个软件结果的设计水平。面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含在很多设计模式中,它们是从许多设计方案中总结出的指导性原则。面向对象设计原则也是我们用于评价一个设计模式的使用效果的重要指标之一。...

2022-07-20 16:23:54 319

原创 c++设计模式-单例模式

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。输出结果我是饿汉式构造我是main函数两个指针指向同一块内存是单例两个指针指向同一块内存是单例。...

2022-07-20 16:11:09 985

原创 c++提高-Lambda表达式

intsum=func(1,3);//这里结果为9如果不使用引用结果就为14。捕获的变量默认带const修饰符加mutable可以修改const变量。如图所示lambda表达式无疑就是上面的那个类只是简化的书写表达。首先我们先来写一个仿函数和一段有同等效果的lambda表达式。输出结果x15。......

2022-07-18 21:18:32 262

原创 starUML教程-用例图/类图

也称为用户模型图是从软件需求分析到最终实现的第一步它是从客户的角度来描述系统功能它包含3个基本组件1.参与者与系统打交道的人或使用该系统的人2.用例表示该系统的某项完整功能3.关系定义用例之间的关系——泛化关系扩展关系包含关系用例之间的关系——泛化关系表示同意业务目的(父用例)的不同技术实现(各个子用例)在UML中用例泛化用一个三角箭头从子例指向父例说白了就是面向对象继承里的父子类关系用例之间的关系——包含关系。......

2022-07-17 23:32:44 15660

原创 c+笔记-stl案例:分组比赛

项目介绍有12个参赛选手共两轮比赛第一轮比赛12个人分成两组随机分组每组6个人。淘汰规则每个人由10位评委打分去掉最高分和最低分剩下的取平均分。第二轮剩下的一共6个人作为一组角逐分数从高到低得出冠亚季军。每组经过角逐只留下一半的人(每组6个人变为3个人).........

2022-07-17 19:10:26 257

原创 一、区块链技术与应用-密码学原理

加密货币(crypto-currency) 密码学中所用的哈希函数被称为cryptographic hash function它有两个重要的性质: 哈希碰撞是不可避免的 因为输入空间远远大于输出空间 输入可以是任意文本或数字 空间是无限大的 有任意多种输入的可能 然而输出空间却只有种可能 因为哈希值就是一个256位的二进制数 所以就会必然出现两个输入映射到同一个输出的情况 实际中 靠蛮力 也称为brute-force去找到

2022-07-13 21:23:31 3789

原创 c++入门笔记-stl常用算法-拷贝和替换/算数生成/集合

算法简介: copy //容器内指定范围的元素拷贝到另一容器中 replace //将容器内指定范围的旧元素修改为新元素 repalce_if //容器内指定范围满足条件的元素替换为新元素 swap //互换两个容器元素copy: 函数原型:copy(iterator beg, iterator end, iterator dest) //按值查找元素 找到返回指定位置迭代器 找不到返回结束迭代器位置

2022-07-12 23:00:34 383

原创 c++入门笔记-stl常用算法-遍历/查找/排序

概述: 算法主要是由头文件组成 是所有STL头文件中最大的一个 范围涉及到比较、交换、查找、遍历操作、复 制、修改等 体积很小 只包括几个在序列上面进行简单数学运算的模版函数 定义饿了一些模版类 用以声明函数对象 for_each //遍历容器 transform //搬用容器到另...

2022-07-12 20:15:24 329

原创 c++入门笔记-stl函数对象/谓词/内建函数对象

重载函数调用操作符的类 其对象常称为函数对象 函数对象使用重载的()时 行为类似函数调用 也叫仿函数本质: 函数对象(仿函数)是一个类 不是一个函数函数对象使用特点: 函数对象在使用时 可以像普通函数那样调用 可以有参数和返回值 函数对象超出了普通函数的概念 函数对象可以有自己的状态 函数对象可以作为参数传递......

2022-07-11 19:17:04 353

原创 c++入门笔记-map/multimap容器

map中所有的元素都是对组pair pair中的第一个元素为key(键值) 起到索引作用 第二个元素为value(实值) 所有元素会根据元素的键值自动排序本质 :map/multimap属于关联式容器 底层结构是二叉树类型实现 优点:非常的高效能 可以根据key值快速的找到value值 具有有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作缺点:空间占用率大 因为底层的数据结构是红黑树实现的 每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得

2022-07-11 18:12:56 1306

原创 c++入门笔记-set/multiset集合容器

简介:所有元素都会在插入时自动被排序本质:set/multiset属于关联式容器 底层结构是用二叉树实现 set和multiset区别:set不允许容器中有重复的元素multiset允许容器中有重复的元素 注意⚠️:只要包含了set头文件就可以使用multisetset st; //默认构造set(const set &st); //拷贝构造set& operator=(const set &st); //重载等号操作符输出结果:size(); //返回容器中元素个数empty(); ...

2022-07-11 14:19:21 464

原创 c++入门笔记-list链表

list基本概念功能:讲数据进行链式存储链表是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现链表的组成:由一系列结点组成结点的组成:一个是存储元素的数据域,另一个是存储下一个结点地址的指针域stl中的链表是一个双向循环链表双向:指针域中next指向了下一个结点 而prev指向了前一个结点循环:循环在下面图片中没有展示出来 以下图为例 stl中第一个结点中prev指向的不是null而是最后一个结点 而最后一个结点的next指向的则是第一个结点 形成了循环结构 优点分析:数组输

2022-07-10 22:13:42 994

空空如也

空空如也

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

TA关注的人

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