从裸机启动开始运行一个C++程序(二)

news2024/11/24 17:36:23

先序文章请看:
从裸机启动开始运行一个C++程序(一)

运行在8086上的第一个程序

既然硬件环境已经就绪了,那接下来,就要想办法让它运行我们的程序了。不过在此之前,我们必须要了解一下8086的主要架构,以及执行程序的方式。

为什么要了解8086

话说,我们不是要研究AMD64架构嘛,干嘛要扯这几十年前的这款胡子都老白了的这款CPU爷爷呢?其实我们在前面介绍AMD64历史的时候就提到过,IA-32也好,AMD64也好,它本质上并不是完全新的架构,而是保持着向下兼容的。

一方面来说,IA-32和AMD64都是从8086模式开始启动的,在开机的那一瞬间,你的电脑其实就是8086,然后再通过一些配置,切换到286模式、386模式、AMD64模式等等的。因此,要想在AMD64架构的裸机开始加载程序,8086的工作方式我们是避不开的。

另一方面来说,从IA-32和AMD64架构中来看,其实它还是有很浓重的8086风格,主干框架并没有大的变动,因此,了解了8086以后,自然而然也就了解了AMD64的其中一部分了。

因此,我们有必要在那些额外扩展的环节之前,先来了解一下8086。

8086体系架构

我们要了解8086体系的计算机中的几大硬件,它们是:

  1. CPU
  2. 内存
  3. BIOS
  4. 硬盘
  5. 显卡
  6. I/O设备

CPU是核心,我们放后面来讲,先讲讲内存、硬盘(外存)和显卡。

内存和外存

「内存」这个词感觉在近年来,已经被移动设备行业的术语给“污染”了。因为我们常说的「手机内存」其实指的并不是计算机领域术语中的「内存」。

内存,全称「内部存储器」,英文名称是「Internal Memory」,又被称为「主存」。之所以叫「内」,这也是有历史原因的。因为早年,内存并不是一个独立的硬件,而是直接将内存颗粒焊死在主板上的。

所以,以这个核心的元器件作为边界,在「里面」的存储器就叫内存,然后在这个体系外部的就叫做了「外存」。

还有一个原因在于,内存是可以直接和CPU交互的,而外存则不可以,它必须通过I/O接口,将数据先通过内存,然后才可以被CPU处理。

内存一般使用的是电路方式存储,比如说由晶体管组成的双稳态电路,通过电路的电压来表示比特位的信号。这种存储方式的优点就是读写速度会很快(毕竟是电路实现),而缺点就是,依赖持续的电力。换句话说,如果断电了,数据就会丢失,重新上电以后,里面的数据是什么是不一定的(随缘,非常的薛定谔),得重新写入以后才会可用。

所以,移动设备行业里所谓的「手机内存」,指的显然不是这个意义上的内存。这其实也是划界的问题,因为手机内存中的「内」是相对于SD卡而言的,手机里自带的存储就叫了个「内存」。但计算机专业领域中的「内存」则是体系结构的内部。(后来也是因为手机内存这个称呼已经有了,再想提及手机里真正意义上的「内存」的时候,又不得不加定语,叫了个「运行内存」。所以用计算机专业领域的概念来说,「手机内存」其实是「外存」,「手机运行内存」才是「内存」)。

我们再来说说外存。外存自然就是前面说的那一套之外的存储设备咯,像是早期的软盘。你想想啊,机器里其实只有一个软驱的,要用的时候,把软盘插到软驱里,再来读取数据。所以,这个「软盘」不就是「计算机外部」的存储设备吗?这样解释可能更容易被接受。

当然,像是硬盘、光盘、U盘等等这些,也都属于外存,虽然硬盘一般是放在机箱里面的,不会频繁插拔,但不影响它在体系结构中的角色。

外存一般用非电路方式存储,像是软盘、机械硬盘采用的就是磁性存储,通过磁头去感应某一个位置磁粉的N极或S极来识别比特位。而光盘则是采用光返性质存储,驱动器来识别某一位置的反光性来识别比特位。再像是U盘(闪存盘)、固态硬盘这些则是用浮栅层来存储,通过栅格中的电子数来识别这一位置的比特位数据。

既然是非电路方式,那么它就不怕掉电,数据将会更长久地保存。不过相对地,它的读写速度就会慢很多。

显卡

显卡,全称「显示适配器」,英文是「Graphics Adapter」。顾名思义,就是用来把信号变成画面,呈现在显示器上的硬件。

在早期,显卡的作用仅仅是用来做信号转换,在内存当中会分配一片专属区域,供显卡来使用。显卡就是不断地读取这片内存区域的数据,然后把它按照一定的协议方式,转换成显示器上的图像。当需要变换显示的东西的时候,CPU就会改写这片内存空间,这样在下一帧的时候,显卡就会按照对应的要求,变换显示的图像。

在这套体系当中,图形的处理完全是由CPU来承担的,而用于显示输出的数据,也是由内存的一部分来承担的,我们把这片用于显示画面的内存区域叫做「显存」。

然而后来,随着人们对图形质量的要求越来越高,因此就想到专门搞一个用来处理图像数据的处理器,也就是GPU,GPU也需要自己的主存,也叫做「独立显存」。

稍微多扯几句,现在我们再说「显卡」,默认都是包含了GPU的显卡,而不再是单纯的显示适配器了。随着现代显卡的性能不断发展,在一些对图形性能要求不是那么高的设备上,就考虑不使用独立显卡,而是将显卡(包括GPU)继承在其他部件上,这种显卡也被称为「集成显卡」。将GPU集成在主板上的叫做「板载显卡」,将GPU集成在CPU中的叫做「核心显卡」。不过板载显卡已经被淘汰了,目前如果你的电脑中没有独显的话,那一定是核显。注意,这种情况只是GPU集成在了「CPU这个芯片」当中,但早已不是早期那种,没有GPU的情况了。

BIOS

前面我们介绍了内存和外存的特性,不知道读者有没有这样一个疑问:既然CPU只能操作内存,而内存又是断电后数据就消掉了,外存虽然可以长久保存,但是刚开机的时候,CPU又执行不到这里来。那么,开机后CPU到底要执行哪里的指令呢?

这确实是个很严重的问题,所以说,计算机需要一个「固化」下来的启动程序,做一些硬件自检的功能,然后把一份指令从外存读到内存中,再开始执行。承担这个任务的就是BIOS,全称Basic Input/Output System,中文译作「基本输入输出系统」。一般会用一种类似于FPGA的这种ROM,随着新机器的发型,直接固化在主板上了,当然后来也出了一些可升级固件的BIOS。

硬件的问题解决了,还有另一个问题,照理说,BIOS也不属于内存,那CPU要怎么执行到BIOS中的指令呢?Intel解决这个问题的方法叫做「统一编址」,简单来说,就是把一部分内存地址,映射给内存之外的部件,比如说BIOS。对于CPU来说,它会「认为」自己是在通过内存数据线来操作内存,但其实中间的一部分链接到了BIOS中。

因此,当计算机启动的时候,它会先执行BIOS中的指令,BIOS里会把一份代码从外存加载到内存中,然后再来执行它。由于这份代码是程序员完全可控的,因此接下来的事情就由这份代码来完成了。我们把BIOS加载的第一段程序叫做「MBR(Master Boot Record)」。

另外多啰嗦几句,前面介绍的BIOS也是计算机专业领域当中「BIOS」的概念,而现代我们常说的「BIOS」,里面有丰富图形界面,多种功能(甚至可以超频的那种),其实已经不是传统的BIOS了,而是UEFI(Unified Extensible Firmware Interface)。只不过因为它承担着与BIOS类似的作用,所以大家仍然习惯称之为「BIOS」,这一点希望读者悉知。笔者在后续描述中的「BIOS」特指计算机专业领域术语的BIOS,而对于UEFI则会单独称为「UEFI」。

CPU

终于讲到了核心的部件——CPU。CPU,全称「Central Processing Unit」,中文译为「中央处理单元」或「中央处理器」,但这个中文名用得不多,一般还是直接叫它CPU。

【注:为了简化问题,帮助读者快速上手,下面的CPU框架结构是简化版的,想知道完整、规范地8086CPU内部结构的读者可以在网上自行搜索。】

CPU有三个重要的部分:运算器(CU, Calculation Unit)、执行器(EU, Execution Unit)和寄存器(Register)。其他类似于缓存(Cache)之类的东西先不讲,因为我们暂时感知不到。

运算器,简单来说就是CPU的原子功能,比如说能做加减法运算之类的。它能做哪些运算取决于它的指令集。

执行器,由它来负责,当前要使用运算器的哪个功能,执行什么样的指令。

寄存器,则是CPU内部用来存放数据的地方,对于软件层面来说,我们主要操作的就是寄存器,因为其他部件都是按照自己的规则去执行的,我们只需要控制寄存器,就可以完成我们希望CPU执行的指令。

照理说,这个时候我应该介绍一下8086的14个寄存器的,但是笔者觉得,前面的铺垫有点太多了,读者可能已经迫不及待想写点程序运行运行了,所以,这些内容,等用到的时候再说吧~

让机器执行起来

啰里八嗦了那么多,总算是可以开始运行程序了!现在就请打开bochs,我们用debug模式来裸机运行一下,看看会发生什么。

对于Windows系统来说,直接运行bochsdbg.exe就可以了,暂时还不用加载配置文件,对于macOS来说,需要指定一下显示的配置。我们找一个工作路径(以后项目的代码都可以放到这个里面),例如~/code,再里面创建一个文件名为bochsrc,这是虚拟机的配置文件,然后编辑里面的内容如下:

display_library: sdl2

主要是因为,bochs的显示输出,默认用的并不是sdl2,这在macOS上是显示不出来的,所以我们需要指定到这个库。

如果你的机器上还没有安装,那么可以用brew install sdl2来安装。

保存完毕以后,在工作路径上通过这个配置文件来运行虚拟机:

bochs -qf bochsrc

即可启动虚拟机,命令行会保持在调试状态:
命令行
这时候我们可以输入c,回车,表示继续执行,不出意外的话,会弹出虚拟机的显示窗口:

虚拟机窗口

可以看到,BIOS中的指令已经运行完毕了,但是由于它没有搜索到外存,所以最终停在了这里。

很好!接下来,我们只需要把指令给它加载到外存里就OK了吧!你可以想象,现在我们把程序写好了,放到一张软盘中,然后把软盘插到软驱里,再重启电脑,这样的话,BIOS就应当能检测到软盘中的内容,并自动加载到内存里了。

不过对于虚拟机来说,上面这套动作得靠配置文件来完成。打开我们刚才的bochsrc(如果你用Windows,之前没有建立的话,现在就该建立了!),加入以下内容(注意,macOS的话不可以删除sdl2的配置项哈!):

boot: floppy # 设置软盘启动
floppy_bootsig_check: disabled=0 # 打开自检
floppya: type=1_44, 1_44="a.img", status=inserted, write_protected=0 # 使用1.44MB的3.5英寸软盘,取镜像为a.img,开机默认已插入软驱,不开启写保护

这样再开机的时候,就可以读取软盘镜像了。那么接下来,我们只需要把要执行的指令,写成这个名为a.img的软盘镜像里就大功告成了。

那怎么创建软盘镜像呢?需要用到二进制编辑器。二进制编辑器很多,macOS上推荐使用Hex Fiend,可以直接在App Store中下载到:
HexFiend

对于Windows来说,可以使用ultra edit,请读者自行安装,如果你实在找不到合适的也无妨,因为我们不可能一直用编辑二进制的方式来写程序,下一章开始我们就改用其他方式了,可以看一下笔者的操作,领悟精神即可。

为了能看到执行效果,我们就把一个数写到一个寄存器里,然后通过bochs的调试指令来看看寄存器里的值,如果生效了,那么就证明我们的MBR已经加载并执行成功了。比如说,我们给ax寄存器中放一个数值6。关于ax寄存器是什么后面章节会讲,反正当前只要知道它是一个8086中的寄存器就好了。

那么,把6写入ax寄存器的命令是什么?这个可以通过查Intel手册知道,应当是:

B8 06 00

B8是指令码,表示给ax寄存器中存入数据。后面的06 00是操作数,因为ax是一个十六位寄存器,所以给它应该要放一个16位的操作数。那为什么是06 00而不是00 06呢?这是因为,8086体系使用小端序,也就是低字节放数的低位。但是在书写数据的时候,我们又习惯从低到高来写,所以就变成了06 00,看上去可能有点不适应,但是还是需要大家适应一下~

那是不是这样就OK了?并不是!虽然BIOS会自动加载数据,但是,BIOS有一个约定,它会检测这段数据的最后两个字节是否是55 AA,是才会认为这是一段合法的MBR,才会加载。至于为啥是这俩魔数……emmm……估计没人晓得~

由于BIOS只会加载512字节(也就是对于软盘来说的第一个扇区),又对后两个字节有标志检测,所以,MBR应当是不多不少正好512字节,并且要在软盘的第一个扇区,这样才能正确被加载。所以,我们补全到512字节,并且把后两个字节设置为55 AA,如下图:

MBR

保存成a.img,就可以使用了!

保存a.img

然后我们再执行bochs -qf bochsrc,(Windows可以先打开bochsdbg.exe,然后选择Load按钮加载bochsrc),注意,现在还不能无脑按c,因为我们的MBR里只有一条指令,黑着往下执行的话会观察不到。所以,我们需要打一个断点,让bochs执行到这个位置的时候停一下。

那么另一个问题来了,断点应该打在哪?这取决于,BIOS会把MBR加载到内存的哪一个位置。这里的约定是0x7c00的位置(同样,至于为什么是这个地址估计也没人知道了~总之是作为一种约定),那么我们就要在0x7c00的位置打断点,所以执行下面的调试指令:

pb 0x7c00

然后再按c,这样执行到这一位置的时候就会停下来:

打断点

停下来的时候,调试页面会显示这样的情况:

调试

注意最下面一行,中括号里的就是当先执行指令的内存地址,也就是0x7c00,证明这个断点位置是对的,在继续执行之前,我们先来看一下当前ax寄存器的情况,输入r指令,回车可以看到通用寄存器的状态:

寄存器状态

这里需要解释一下,由于bochs是AMD64架构的模拟器,所以这里的寄存器都是按64位显示的,它们的扩展情况将会在后续章节来介绍,目前我们只需要知道,要看ax寄存器的值,其实就是看rax的最后16位(也就是最后4位十六进制位),如上图红框里的,就是ax的值,现在是aa55

然后,我们往下执行一条指令就好了,s命令是单条执行,只会向下执行一句指令。所以我们输入s,回车,再输入r来打印一下寄存器的情况:

执行一步

OK,ax寄存器真的被改写成0006了,说明我们的指令已经成功运行了!

改用汇编语言

不知道会不会有读者跟笔者一样,第一次在裸机上运行一句指令以后会无比兴奋,仿佛打开了新世界的大门,恨不得现在就着手写一片江山上去!但是先别急!因为这种用二进制机器码直接编程的难度也忒大了。我得去记住所有的指令码和指令格式,万一错一个数字那就整个都不对了,况且它可读性也很差呀!谁能一眼看出来B80600是什么鬼?

当然了,要是退回到8086的年代,可能程序员真的是这么干的,但是现在,我们有了更方便的工具,这种仿古式的编程方法,稍微体验一下就OK啦。回到上面的指令,既然B80600是「给ax寄存器写入0006这个数」的含义,那么,能否有一个翻译器,把我的这种表意,转换成机器指令呢?

当然有!这就是汇编器,它可以把汇编语言转换成机器码。比如说:

mov ax, 0x06

表明给ax寄存器中传入0x06这个十六进制数,然后交由汇编器将其转换为B80600。这样的语言就叫做汇编语言,汇编语言看起来是比机器码要友好得多了吧?

不过成熟的汇编器除了做指令翻译以外,可能还会有一些更方便的功能,类似于编译器的预处理,做一些静态的数值转换之类的工作,但是不同的汇编器支持的汇编语言也会略有不同,业界比较常用的有两个:nasm和gas。

gas也就是GNU的asmmbly(汇编语言),之所以比较常用,是因为gcc只能将C代码编译成gas格式,后续本篇的示例中,也会使用gcc编译器,编译后的就是gas格式。

nasm是一个比较被普遍认可的汇编器,全称Netwide Assembler。它的优点在于语法简洁易用。在本篇的示例中,对于需要直接手动开发的汇编语言部分,将会使用nasm。

接下来就来介绍如何安装nasm。

安装nasm汇编器

首先,登录nasm官网,点击当前最新的稳定版本(读者看到的时候有可能已经是高于截图的版本了,不过没关系,选择最新的稳定版即可)。
nasm官网

接下来,根据自己所使用的OS选择对应的文件夹,如果你用macOS,就选macosx,如果你用Windows,就选win64。注意,这里只区分操作系统,不区分你的实际硬件架构,即便你使用苹果自研芯片的Mac,或者搭载骁龙芯片的Windows,这里的软件也同样适用。
下载对应OS版本的nasm

接下来Windows和macOS的步骤会有不同,笔者分别来介绍。

在Windows上安装nasm

由于Windows版本中提供了安装包,因此,比较方法的做法是下载这个installer,然后通过自带的安装程序安装到电脑中。当然,如果你对搭建环境比较熟的话,也可以直接下载下面的zip,解压缩后得到的直接是nasm程序本身。
选择安装器

如果你选择了安装器的版本,那么直接运行安装器,安装选项全部默认即可。
nasm安装器

不过这里要注意一下安装路径,默认情况是C:\Program Files\NASM,Windows默认这个带空格的路径确实是一个饱含诟病的历史遗留问题,不过对于nasm来说影响不大,安装在默认路径下也是OK的,只不过我们要记住这个路径,保证能找到它。如果你没有用安装器,而是直接下载的zip然后解压缩的话,也请把整个文件夹放在一个合适的路径下,保证自己找得到。
安装路径

等安装完毕后,nasm就已经躺在刚才的安装路径下了。但是每次都指定绝对路径去运行着实麻烦了一些,也不方便我们进行项目的迁移,因此,我们还要把它配置到环境变量里。按Win+R组合键,弹出「运行」窗口,输入sysdm.cpl,回车,即可打开系统属性设置。
运行

在「系统属性」设置中,选择「高级」标签页,再点击下面的「环境变量」按钮。
系统属性

接着,在环境变量中找到用户变量里的Path,这个变量决定了,如果你不指定绝对路径,而是直接输入一个命令的时候,系统会去哪些路径中找程序。我们希望的效果是,当我们想运行nasm的时候,直接输「nasm」就好了,而不是每次都要输「C:\Program Files\NASM\nasm」,因此,就要把这个路径也配置到环境变量中。

选择Path后点击「编辑」,或者直接双击Path也可以,就可以编辑环境变量了。
环境变量

在「编辑环境变量」的窗口中点击「新建」,然后把nams的安装路径写进去。注意,要写全路径,并且只需要写到NASM这层路径就好了,确保这个路径下有nasm.exe这个可执行程序。
编辑环境变量

环境变量设置好以后,我们就可以尝试运行一下nasm了。按Win+R打开「运行」,输入cmd,回车,即可调出控制台。
运行

在控制台中输入nasm -v,如果能够看到打印出的nasm版本号信息,就说明我们已经安装配置完毕了!
运行nasm

在macOS上安装nasm

由于macOS版本的nasm没有安装包,所以我们只能下载源程序的压缩包。
下载nasm

解压缩之后,就已经是可以执行的程序了,不过一般情况下浏览器默认会把文件下到「下载」这个路径中,这里自然不合适放一个经常要用到的程序,所以请手动把它挪到一个妥当的位置。

我这里选择的是用户根路径,也就是~/。文件夹它默认带版本号,你可以改个名字,也可以不管它,只要确保里面有nasm这个可执行程序就好了。我这里的路径是~/nasm-2.16.01

同样地,为了让我们使用时可以只输入nasm,而不是~/nasm-2.16.01/nasm,我们还需要把这个路径放入环境变量。

macOS最早默认使用的bash,后来换成了zsh,因为这个切换已经很久了,所以笔者介绍zsh的情况,如果你用的是其他版本的shell,就请自行解决环境变量的配置问题。

执行下面的命令,编辑zsh的配置文件:

vim ~/.zprofile

注意,即便你当前没有.zprofile这个文件也没关系,上面的命令执行会以新建文件的方式。

然后再编辑界面按「i」键,进入编辑模式,此时左下角会显示「INSERT」,表示在编辑模式。如果里面已经有一些配置了,无视就好,我们在文件最后加上:

PATH=$PATH:/Users/xxx/nasm-2.16.01

注意,由于我是放在~/里的,但这里要写全路径,所以你需要看一下全路径是什么,用波浪线有时可能会失效。

那一句的意思就是,在PATH这个变量后面,加上一个nasm的路径,所以这里要填写你的nasm所在路径。

由于.zprofile会在每次运行终端的时候自动执行,因此我们把命令写在这个文件里就不用每次手动配置了,但由于现在还没生效,所以你还需要执行一句:

source ~/.zprofile

或者干脆把终端关了,重新开一下,就生效了。

然后我们在控制台输入

nasm -v

如果能够看到版本信息,那么说明nasm已经安装配置成功。
nasm版本

小结

本篇介绍了8086的体系和计算机硬件的基本常识,然后尝试在bochs上运行了一条指令来修改ax寄存器的值,最后介绍了安装nasm的方法,下一篇开始,我们将会使用汇编语言继续开发我们的MBR。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小白安装 stabel diffusion 篇

windows 系统安装 stabel diffusion 软件的方法其实很简单,只有 4 步(安装过程遇到的报错问题,本文有详细的解决方案,都是我踩过的坑,给大家探路了): 1、安装 python(建议安装 3.10…

孙鑫VC++第五章 文本编程

目录 1. 插入符 1.1 创建文本插入符 1.2 创建图形插入符 2. 文字输出和OnDraw函数 2.1窗口重绘 2.2 添加字符串资源 3. 路径层和剪切区域 3.1 路径 3.2 裁剪区域 4. 字符输入 4.1 字符输入 5. 字幕变色功能的实现 5.1 设置字体 5.2字幕变色功能的实现 6. 总结 1…

windows11 安装WSL2全流程

文章目录 1、启用window子系统及虚拟化1.1 命令行方式1.2 使用图形界面 2、手动安装2.1、安装内核更新包2.2、设置默认WSL版本2.3、配置分发版本2.3.1 下载发行版本2.3.2 安装到C盘2.3.3 安装到D盘2.3.3.1 导出镜像2.3.3.2 导入镜像2.3.3.3 默认系统设置及多系统选择 3、自动安…

全景 I 0基础学习VR全景制作,第26章热点功能-文档

本期为大家带来蛙色VR平台,热点功能—文档功能操作。 功能位置示意 热点,指在全景作品中添加各种类型图标的按钮,引导用户通过按钮产生更多的交互,增加用户的多元化体验。 文档热点,即点击热点后会嵌入式弹出所选文档…

一次线上mysql 调优 ,join 的调优,索引优化(Block Nested Loop)

原因: 某接口调用十分缓慢,通过 Explain 发现是SQL问题 FROMorderInfo o LEFT JOIN orderDetail d ONo.orderCode d.orderCode LEFT JOIN user u ONo.userId u.userId LEFT JOIN product p ONd.productCode p.productCode LEFT JOIN adminUser au O…

Linux之打包压缩

1、参考 11-文件压缩与打包 linux tar压缩排除指定文件夹 2、打包与压缩 在windows上似乎打包和压缩是同一个东西,大家都明白你的意思,实际上是打包和压缩是两个过程,只不过常用zip压缩一站式解决了。 打包:就是将文件夹或多个…

《终身成长》笔记七——建设性的批评

目录 总结 经典摘录 我们能做什么 成长型思维模式与马上行动有异曲同工之妙 改变孩子的思维模式 两种思维模式对比 总结 《终身成长》是卡罗尔德韦克的代表作,在这部作品中,她以通俗易懂的笔触总结了自己对人类两种思维模式的研究。也许因为思维模…

mysq的约束学习

第13章_约束 1. 约束(constraint)概述 1.1 为什么需要约束 数据完整性(Data Integrity)是指数据的精确性(Accuracy)和可靠性(Reliability)。它是防止数据库中存在不符合语义规定的数据和防止因错误信息的…

鸿蒙Hi3861学习十五-Huawei LiteOS-M(Socket客户端)

一、简介 在网络编程的时候,不管是客户端还是服务端,都离不开Socket。那什么是Socket,这里做个简单介绍。详细的内容,可以参考这篇文章:WIFI学习一(socket介绍)_wifi socket_t_guest的博客-CSDN…

ChatGPT发展报告:原理、技术架构详解和产业未来(附下载)

今年12月1日,OpenAI推出人工智能聊天原型ChatGPT,再次赚足眼球,为AI界引发了类似AIGC让艺术家失业的大讨论。 据报道,ChatGPT在开放试用的短短几天,就吸引了超过 100 万互联网注册用户。并且社交网络流传出各种询问或…

其他类型的CMOS逻辑门

1.CMOS与非门 电路结构如图所示 如图所示,T1、 T3为两个串联的PMOS, T2、 T4为两个并联的NMOS. A、B有一个为“0”时,T2、 T4至少有一个截止, T1、 T3至少有一个导通,故输出为高电平,Y=1. A、…

用Colab免费部署AI绘画云平台Stable Diffusion webUI

Google Colab 版的 Stable Diffusion WebUI 1.4 webui github 地址:https://github.com/sd-webui/stable-diffusion-webui 平台搭建 今天就来交大家如果来搭建和使用这个云平台。 第一步: 打开链接 https://colab.research.google.com/github/altryne/sd-webu…

求最大字段和(穷举法、动态规划、分治法)

目录 1、案例要求2、算法设计与实现2.1 穷举法2.1.1 算法设计思路2.1.2 代码实现 2.2 动态规划2.2.1 算法设计思路2.2.2 实现代码 2.3 分治法2.3.1 算法实现思路2.3.2 代码实现 3、总结 1、案例要求 给定由n个整数(可能为负整数)组成的序列a1,a2,…,an&…

菜鸟对原型链的理解

1.什么是原型 函数下的prototype属性,是个指针,指向的对象就是原型 2.什么是原型链 很多个原型连接起来就是一条链了。 function Person() { } var test new Person(); 当我们new一个构造函数是,实例对象(test)&a…

Windows平台上的5种敏捷软件开发(过程)模型

我是荔园微风,作为一名在IT界整整25年的老兵,今天总结一下Windows平台上的5种敏捷软件开发(过程)模型。 说到这个问题,你必须先知道除了敏捷模型还有没有其他什么模型?同时要比较模型的区别,首先还要看看什么叫软件开…

文件权限-chmod命令 – 改变文件或目录权限

Linux chmod命令 – 改变文件或目录权限 在Linux系统中,每个文件和目录都有自己的权限属性,这些属性包括读、写、执行等权限。通常情况下,只有文件的所有者和管理员可以设置文件权限,而普通用户只能管理自己文件的权限。为了更好…

数据结构总结5:堆

后续会有补充 堆 堆是一种数据结构,总是一棵完全二叉树,是使用数组存储的,是非线性的;并且要求树中所有的父亲都小于等于孩子(小根堆)/树中所有的父亲都大于等于孩子(大根堆)不一定…

人工智能基础部分16-神经网络与GPU加速训练的原理与应用

大家好,我是微学AI,今天给大家介绍一下人工智能基础部分16-神经网络与GPU加速训练的原理与应用,在深度学习领域,神经网络已经成为了一种流行的、表现优秀的技术。然而,随着神经网络的规模越来越大,训练神经…

Linux下部署Samba服务(实现windows和linux共享)

关于Linux和Windows系统之间的文件传输,很多人选择使用FTP,相对较安全,但是有时还是会出现一些问题,比如上传文件时,文件名莫名出现乱码,文件大小改变等问题。相比较来说,使用Samba作为文件共享…

Midjourney会员充值教程

本教程收集于:AIGC从入门到精通教程 Midjourney会员充值教程 目录 一、 打开会员订阅页面 二、 选择您需要订阅的会员