【CPU指令】

CPU控制器通过读取存储器中的指令确定要执行的功能,CPU运行需要不停的读取指令,计算机启动后CPU会从固定地址处开始读取指令,首先读取 NOR Flash 存储器中的固件,固件执行完毕后引导操作系统执行。

指令是一个二进制数据,主要由如下两部分组成:
1.操作码,设置控制器执行的功能,比如读写数据、数学运算、逻辑运算。
2.地址码,设置指令读写数据的位置,可以是寄存器、内存单元、IO端口,若要将一个固定的数据写入到其它位置,可以将数据直接存储在地址码中,存储在地址码中的数据称为立即数。

x86是英特尔发明的一种复杂指令集,最早用于16位的8086处理器,之后扩展到32位处理器,进入64位处理器时代后,由AMD扩展为支持64位处理器,此版本的x86称为x86-64,或AMD64。

在计算机中,一个数据既可以用来表示一个数学中使用的数据,也可以表示指令,为了区分两者,之后的文章将数据分为数学数据和指令数据,以免混乱。

【指令执行方式】

指令执行顺序

CPU使用专用寄存器记录指令数据所在的内存地址,依靠此寄存器读取指令数据执行,指令的执行顺序有两种:

1.顺序执行,本条指令执行完毕后,CPU自动增加指令地址寄存器的值,定位到下一条指令所在的地址,指令按存储顺序依次执行。
2.跳转执行,本条指令执行完毕后,不按照存储顺序执行下一条指令,称为跳转执行,可以向前跳转也可以向后跳转,跳转执行由跳转指令实现,跳转指令会修改指令地址寄存器的值,从而实现跳转执行。

指令流水线与转移预测

CPU为了提高指令的执行速度,会将每一条指令的执行分为多个步骤,使用流水线的方式执行每一个步骤,一条指令正在执行时,其它指令已经在流水线中进行前期准备工作。

若遇到跳转指令,CPU会进行分析,预测将要跳转到的地址,然后读取预测地址处的指令进入流水线,这个预测的正确率一般为90%以上,但是无法做到100%,若判断出错,就要清空指令流水线,重新来过,为了避免这种情况发生,在编写程序代码时应该尽量减少使用有条件跳转指令,高级编程语言的编译器会使用多条非跳转指令的组合代替某些有条件跳转指令。

指令流水线的设计方式类似工厂流水线,工厂流水线的每一级都要设置合理,级数越多工作越简单,每级的生产速度就更快,但是级数过多会导致货物整体生产速度降低,CPU设计也是如此,指令流水线级数越多半导体器件开关频率越快,但是若流水线每级的工作设置不合理会导致指令整体执行速度降低。

指令调度策略

程序指令按照自身设置的顺序去执行,但是程序设置的指令执行顺序并非最优、最快的,CPU为了更快的执行指令,会将指令执行顺序重新排序,称为动态调度,同时在本条指令进入等待状态后(等待某个数据传输)执行下一条指令,动态调度的前提是不会影响指令原先执行顺序的最终执行结果。

高级语言编译器也会进行类似优化,将指令进行重新排序,不会完全按照代码的编写顺序进行编译,称为静态调度优化,可以减轻CPU动态调度的工作量。

指令执行限制

最早的计算机同一段时间只需要执行一个程序,程序的执行无需做任何限制,指令可以使用CPU的任何资源、可以读写任意内存地址、可以随意跳转执行。
之后人们需要在计算机中同时执行多个程序,此时就需要使用一个程序管理其它所有程序的执行,提供管理功能的程序称为操作系统。

x86处理器为了配合操作系统实现管理功能将指令的执行分为4个权限等级,使用0-3表示。
0级权限最高,可以使用CPU的任何资源、可以读写任意内存地址、可以跳转到低权限指令执行。(注:80486之后,0级指令也不能在只读内存区写入数据,需要首先取消只读限制)
3级权限最低,不能使用CPU的某些寄存器、只能读写操作系统为其分配的内存空间、不能跳转到高权限指令执行。

操作系统使用0级权限执行指令,从而控制用户程序的执行,用户程序使用3级权限,1-2级权限被操作系统废弃不用。

x86处理器启动后,默认不对指令进行任何限制,此模式称为实模式,指令可以通过修改控制寄存器CR0的PE位进入保护模式,保护模式会开启指令的限制功能,进入保护模式后就不能再返回实模式。

【处理器中断】

处理器工作时可能会发生各种事件,此时需要暂停正在执行的程序,转而去处理事件,处理器中断功能提供此功能,中断用于暂停正在执行的程序,每个中断对应一个事件,每个中断都有一个编号,CPU通过中断编号确定事件类型,每个中断都可以绑定一个事件处理程序,发生中断后CPU暂停正在执行的程序,然后执行事件处理程序,处理程序执行完毕后返回之前的程序执行。

x86处理器使用地址 0 - 1023 的内存单元存储事件处理程序的执行入口地址,这段内存空间也称为中断向量表。

CPU执行中断处理程序之前,首先使用入栈指令将标志寄存器、CS、IP寄存器中的数据存储到内存中,称为保存现场,然后从中断向量表中读取事件处理程序的地址修改CS、IP寄存器,执行处理程序,处理程序执行完毕后,CPU不会自动将标志寄存器CS、IP寄存器的值恢复,恢复现场的工作由中断处理程序完成,恢复现场使用iret指令即可,执行iret执行时相当于执行如下3条指令:

pop ip
pop cs
popf

中断分为两大类,内中断和外中断。

内中断

由CPU内部产生的中断称为内中断,也有人称为异常,x86处理器在以下情况会发出内中断:

1.执行除法指令时出错,比如除数为0,比如被除数长度不够。
2.处理器启用了单步中断功能,每执行一条指令就产生一个内中断,用于调试程序。
3.访问内存错误,比如向只读内存区写入数据、3级指令访问不属于自己的内存空间。
4.执行int、into指令。

单步中断用于调试程序,控制器每执行完一条指令就会检测标志寄存器的TF位,若为1则产生单步中断,之后CPU执行保存现场工作,此时会将标志寄存器的TF、IF位设置为0,避免在执行处理程序时一直产生单步中断。

外中断

由CPU之外的设备产生的中断称为外中断,外中断分为可屏蔽中断和不可屏蔽中断,多数外中断都是可屏蔽的,可以通过修改标志寄存器的IF位屏蔽这些外中断。

CPU对外连接的两个引脚用于外中断功能(对应可屏蔽中断和不可屏蔽中断),CPU每执行完一条指令就会检查外中断引脚的电压,外部设备通过改变此引脚的电压来告知CPU是否有外部事件发生,比如按下键盘按键后会向CPU发出一个外中断,告知CPU输入设备有数据发送,硬件设备运行出错时也会向CPU发出一个外中断。

【多字节数据存储方式】

多字节数据在内存中的排序方式有两种:大端排序、小端排序,数据使用哪种排序方式没有固定规则,不同处理器有不同的安排,x86处理器使用小端排序方式。

大端排序方式

数据的低位字节存储在高地址中,高位字节存储在低地址中,比如一个4字节数据 0x12345678(0x表示16进制,2位16进制数字对应1字节),需要存储在地址0-3的内存单元中,地址0存储高位的0x12,地址0-3依次存储的数据为 0x12345678。

小端排序方式

数据的低位字节存储在低地址中,高位字节存储在高地址中,比如一个4字节数据 0x12345678(0x表示16进制,2位16进制数字对应1字节),需要存储在地址0-3的内存单元中,地址0存储低位的0x78,地址0-3依次存储的数据为 0x78563412。

【内存管理方式】

最简单的处理器读写内存单元时直接使用一个数据指定操作的内存地址,此时程序必须放在固定的内存地址处,放在其他位置就会执行出错,比如程序需要跳转执行时,跳转到的地址已经写死,无法改变。
这种内存管理方式适用于功能简单的单片机,它只执行一组固定的程序,程序存储在固定的地址中。

当计算机需要同时执行多个程序时,内存管理方式就会变的复杂,程序需要放在内存的任何位置都能正常执行,并且每个程序只能使用自己占用的内存空间,不能使用其它程序占用的内存空间,为此x86提供了分段、分页两种内存管理方式。

分段管理方式

此方式下处理器将内存分为多组使用,每一组称为一个段,内存地址使用两个数据相加得出,这样做的目的有两个:
1.形成更大范围的内存地址空间,使用容量更大的内存。
2.方便程序重定位,放在内存中的哪个位置都能够正确执行。

内存分段后,指令使用两个数据指定内存地址,分别称为段地址、偏移地址。
1.段地址,存储内存分段在内存空间中的起始地址。
2.偏移地址,存储分段内部存储单元的编号,编号从0开始分配。

内存分段方式起源于8086处理器,8086是16位处理器,内存地址寄存器也是16位的,但是8086为了使用容量更大的内存设计了20位的内存地址。
为了让16位的8086形成20位的内存地址,处理器使用两个数据相加得出内存地址,但是两个16位数据相加最大也只能形成长度17位的数据,8086的解决方法是将段地址乘以16,然后再与偏移地址相加,这样就能形成一个长度20位的二进制数据,乘以16是因为可以使用右移4位的方法代替乘法,右移运算比乘法运算更快,第一个内存分段地址为0,0 * 16 = 0,所以第一个内存分段依然从0开始。

操作系统启动后,首先在内存中创建全局描述符表,用于记录每个分段的起始地址、长度、访问属性、和其它信息,之后启用CPU的保护模式。
程序执行时,只能占用操作系统设置好的分段,不能自己创建分段,操作系统会为每个执行的程序创建一个局部描述符表,用于记录此程序占用的内存分段。
指令读写内存单元时只需要指定偏移地址,之后CPU在描述符表中查询段地址,并与偏移地址相加合成内存地址,这样就实现了将程序放在内存的任何位置都能正确执行。

分页管理方式

内存分段管理方式不能设置很小的分段,使用不方便,容易造成浪费,操作系统为程序分配的分段尺寸不一定是程序需要的容量。

为了解决这个问题,从80386开始有了内存分页管理方式,处理器将内存按照4KB的大小分组,每组称为一个页,程序以容量更小的页为单位占用内存,避免浪费,CPU启动后默认以分段方式使用内存,之后启动操作系统,操作系统为进程设置页表后切换到内存分页使用方式。

在32位x86处理器中,启用分页机制后,分段方式依然保留,内存地址依然使用两个数据相加的方式得出,目的是为了形成更大的内存地址,使用容量更大的内存,毕竟一个32位的二进制数据最多只能寻址4GB的内存。
在64位x86-64处理器中,使用64位的内存地址寄存器,64位数据可以寻址足够大的内存空间,启用分页机制后,分段机制将被废弃,不再使用,只使用一个64位的数据指定内存地址即可。

无论是32位处理器还是64位处理器,启用分页机制后,指令使用的内存地址都不再是真实内存地址,而是一个中间地址,称为虚拟地址。

计算机文件有一个文件偏移地址的概念,我更习惯称其为文件内部地址,它的作用是为文件内部数据按存储顺序分配编号,编号从0开始,第一个字节分配编号0、第二个字节编号为1、直到最后一个字节,通过这个编号调用文件数据很方便,无需知道文件存放在哪个位置,就好比使用火车托运货物,你只需要记录火车车厢的编号即可,无论火车走到哪里,你只要告诉管理人员你的货物在几号车厢就能拿走你的货物,至于火车停在哪个轨道上,你无需关心,那是管理人员的事。

虚拟地址的作用就类似文件内部地址,它用于为程序内部数据分配编号,无论程序放在内存中的哪个位置,都可以通过文件内部地址调用其中的数据。

处理器默认以实模式、内存分段管理方式运行,操作系统启动后,首先启用处理器的保护模式,之后启用内存分页管理方式,程序运行时操作系统按页为其分配内存,并为进程创建一个页表,用于记录进程占用了哪些页、每个页的属性信息(比如指令使用此页时需要具备的权限、页是否设置为只读),此时虚拟地址会与内存物理地址建立绑定关系,程序指令通过虚拟地址说明要调用程序内的第几个数据,至于这个虚拟地址对应哪个内存地址,程序不关心,也无需知道,CPU会根据页表中的记录将虚拟地址转换为内存物理地址,之后执行指令,从而实现将程序放在内存中的哪个位置都可以正确执行。

注:
x86-64处理器的内存地址寄存器长度为64位,使用一个64位的二进制数据可以形成非常大的内存地址空间,但实际上个人用户远用不到这么大的内存地址,所以某些处理器只使用其中的48位,这样可以简化虚拟地址的转换步骤,指令执行速度更快,剩余的高16位有两种状态,操作系统内核指令将其全部设置为1(只是单纯设置为1,不参与页表转换),用户程序指令将其全部设置为0,若不是这两种状态则是不规范的虚拟地址,处理器无法使用,而服务器CPU需要使用更大容量内存,某些服务器CPU也会开放高16位中的某些位。

【寄存器】

寄存器按功能可以分为5类:通用寄存器、段地址寄存器、偏移地址寄存器、标志寄存器、控制寄存器。

通用寄存器

通用寄存器可以存储任何数据,又分为多种长度类型,64位寄存器只存在于64位处理器中,但是同时包含32位、16位、8位寄存器。

x86-64处理器的通用寄存器如下:

64位:rax、rbx、rcx、rdx,继承自最早的x86指令集,x86-64将其扩展为64位。
64位:r8、r9、r10、r11、r12、r13、r14、r15,x86-64指令集新增通用寄存器。

32位:eax、ebx、ecx、edx,由64位的rax-rdx拆分形成,不能与对应的64位寄存器同时使用。
32位:r8d、r9d、r10d、r11d、r12d、r13d、r14d、r15d,由64位的r8-r15拆分形成。

16位:ax、bx、cx、dx,由32位的eax-edx拆分形成。
16位:r8w、r9w、r10w、r11w、r12w、r13w、r14w、r15w,由64位的r8-r15拆分形成。

8位:al、bl、cl、dl、ah、bh、ch、dh,由16位的ax-dx拆分形成,ax的低8位为al,高8位为ah。
8位:r8b、r9b、r10b、r11b、r12b、r13b、r14b、r15b,由64位的r8-r15拆分形成。

段地址寄存器

CS,存储指令数据的段地址。
DS,存储数学数据的段地址。
SS,存储栈空间的段地址。
ES、FS、GS,辅助段寄存器,供程序自由安排使用。

启用保护模式后,CS寄存器存储的不再是段地址,而是段选择子,段选择子用于存储了操作系统设置好的内存分段编号、并记录分段内数据的属性信息,比如指令权限级别。

在x86-64处理器中,启用内存分页管理方式后,段地址寄存器将不再使用。

偏移地址寄存器

16位的8086处理器定义了5个偏移地址寄存器:

IP,存储指令数据的偏移地址,CPU通过CS+IP合成指令数据所在地址。
SP,存储栈空间的偏移地址,push、pop指令通过SS+SP合成要操作的内存地址。
BP,存储栈空间的偏移地址,mov指令读写栈空间时使用BP寄存器指定偏移地址,不与push、pop栈指令共用SP偏移地址寄存器,避免混乱。
SI、DI,存储数学数据的偏移地址,与DS寄存器合成要操作的内存地址,服务于读写数组相关指令,比如stosb、movsb。

其中SP、BP、SI、DI也可以当做通用寄存器使用,在x86-64指令集中,SP、BP、SI、DI又可以拆分为4个8位寄存器:SPL、BPL、SIL、DIL,这4个8位寄存器只存在于x86-64指令集中。

在32位x86处理器中,偏移地址寄存器长度为32位,使用32位模式时需要在名称前添加字母E,比如:EIP、EDI。
在64位x86处理器中,偏移地址寄存器长度为64位,使用64位模式时需要在名称前添加字母R,比如DI表示16位模式、EDI表示32位模式、RDI表示64位模式。

标志寄存器

标志寄存器(FLAGS)用于记录指令执行结果、设置处理器某些功能是否启用,标志寄存器使用二进制位存储信息和设置功能,在x86-64中长度扩充为64位,但只使用低32位,常用位如下:

0位,进位标志位(CF),记录运算指令是否发生进位行为。
2位,奇偶标志位(PF),记录运算指令结果的低8位中数字1的数量是双数还是单数,若数量为双数或0则PF存储1,若数量为单数PF存储0。
4位,AF位,服务于BCD数据。
6位,零标志位(ZF),记录数学运算、逻辑运算指令执行结果中是否所有二进制位都为0,若都为0则ZF位存储1,否则存储0,用于判断执行结果是否为0。
7位,符号标志位(SF),记录有符号数运算结果是否为负数,若为负则SF存储1,若为正存储0。
8位,单步中断标志位(TF),设置是否产生单步中断,若为1则每执行一条指令就产生一个中断,用于调试程序。进入中断处理程序前会将TF设置为0。
9位,屏蔽外中断标志位(IF),设置处理器是否接收可被屏蔽的的外中断,若为1则接收,为0不接收。
10位,方向标志位(DF),设置循环读写数据指令(stosb、lodsb、movsb)的读写方向,地址递增或是递减。
11位,溢出标志位(OF),记录有符号数运算是否发生溢出,若溢出则OF设置为1,否则为0。
12-13位,IOPL位,设置指令处于不同权限时,读写IO地址空间的权利。
18位,AC位,设置是否开启地址对齐检查,需要与控制寄存器CR0的AM位共同使用。

其中CF位有三种功能:
1.记录执行无符号数加法运算时结果是否因长度过大导致溢出,若溢出则CF位存储1,否则CF为0。
2.记录执行无符号数减法运算时低位是否向高位借位,若参与减法运算的数据长度超过寄存器长度,处理器将减数分为高低位两部分进行运算,若低位减法发生了向高位借位则CF存储1,否则CF为0,之后进行高位减法时会额外减去CF位的值。
3.记录乘法运算结果是否使用了存储高位的寄存器,执行乘法运算时计算结果使用两个寄存器存储,防止乘法结果长度过大导致溢出,若使用了高位寄存器则CF为1,否则CF为0。

控制寄存器

控制寄存器用于设置处理器工作模式、内存的使用模式、缓存的禁用与启用、虚拟地址的转换、和其它功能。
32位x86处理器有4个控制寄存器:CR0 - CR3,其中CR1保留不用,而x86-64定义了CR0-CR15共16个控制寄存器,但只使用其中的CRO、CR2、CR3、CR4、CR8。

CR0的PE位用于设置是否启用保护模式,若为1则启用保护模式,进入保护模式后不能再回到实模式,PG位用于设置是否启用内存分页管理模式,启用分页模式之前必须首先启用保护模式。

CR3存储正在执行进程使用的页表地址,指令使用内存前CPU会通过CR3存储的地址寻找页表,之后将虚拟地址转换为内存物理地址并执行指令。

【缓存】

内存的读写速度虽然很快,但是依然不能满足CPU的需求,为此CPU设计了缓存,缓存是位于CPU内部的存储器,读写速度比内存更快。
不同处理器的缓存容量以及布局不同,缓存内部的存储单元会进行多级分组,首先分为多个大组,大组再分为多个小组,小组有32字节、64字节、或其它容量,缓存小组也称为缓存行或缓存块,不同的人有不同的称呼,创建内存映射时以缓存小组容量创建。

缓存由CPU自动管理,程序无法直接读写,缓存是内存的映射体,那什么是映射呢,映射表示行为结果的转移,这很像中国古装电影里的一个剧情,制作一个纸人并在上面写上某人的名字,之后做法,即可将纸人变成某人的映射体,对纸人施加伤害会转移到原体中,原体的属性也会转移到纸人中,缓存就是如此,CPU将常用的一组数据从内存读取到缓存,之后在缓存中读写数据,对缓存的操作会转移到内存中,长时间不使用的内存映射体会在缓存中删除。

指令数据与数学数据都会读取到缓存再使用,但是指令数据缓存只涉及读取操作,而数学数据缓存涉及到读取与写入两种操作。

缓存映射内存的方式

读取一个内存地址时CPU会将此数据以及周围的一组数据全部读取到缓存块中(缓存块完全填充满之前指令可以照常执行,无需等待),因为多数情况下之后执行的指令会使用此数据周围的其它数据,之后读取内存时会首先判断缓存是否映射了此内存地址,若有映射则直接读取缓存,若没有映射则重复以上步骤。

向内存地址写入数据时CPU首先判断缓存是否映射了此地址,若有映射则直接将数据写入缓存,之后执行下一条指令,指令无需等待CPU将数据从缓存写入内存,若没有映射则直接将数据写入内存,多核CPU还会涉及到每个核心专用缓存的更新,保证多个核心缓存的一致性,这里不详细讨论此问题。

地址对齐

因为缓存的存在,CPU实际上读取的是缓存,而非内存,内存数据会首先读取到缓存中再使用,CPU在读取内存数据时并非只读取需要的数据,而是将其附近数据一起读取到缓存,对于64位CPU,读取内存时每次可以读取8字节(8*8=64位),此时CPU可以对内存单元按8字节长度进行分组使用,比如地址0-7、8-15、16-23、24-31,然后按此分组将数据从内存读取到缓存,这样每次读取的内存地址低3位都为0,这3个低位值可以无需记录,从而简化缓存内部结构、降低发热量、增加器件运行频率,所以一个数据在内存中存储时就需要尽量放在同一组内存单元中,方便CPU整体读取,此时数据的存储需要满足如下规则:

2字节数据,需要放在地址为2的倍数内存地址中。
4字节数据,需要放在地址为4的倍数内存地址中。
8字节数据,需要放在地址为8的倍数内存地址中。

若有一个长度8字节的数据,放在起始地址为4的8个内存单元中,则CPU需要分2次读取,这种存储方式就是地址不对齐,对于访问非地址对齐数据的行为,不同CPU有不同的执行结果,x86处理器默认只是增加数据的读写时间,降低读写速度,而ARM处理器默认会产生错误和异常。

下面使用C语言代码验证地址对齐方式,计算机使用x86-64处理器、linux操作系统、gcc编译器。

#include <stdio.h>
char a = 1; //长度1字节
int b = 2; //长度4字节
short c = 3; //长度2字节
long long d = 4; //长度8字节
int main()
{
printf("%d\n%d\n%d\n%d\n", a,b,c,d);
return 0;
}

变量a、b、c、d的存储方式如下:

Contents of section .data:
 404028 00000000 00000000 00000000 00000000
 404038 01000000 02000000 03000000 00000000
 404048 04000000 00000000

左边的404028表示虚拟地址(使用16进制),右边的数据为程序全局变量,同样使用16进制表示,2位16进制数字对应一个字节,使用小端序存储方式,实际查看时需要按字节重新排序。

地址404038处存储变量a,变量b并非在404039处,因为此处并非4的倍数,而是在40403c处存储,40403c是4的倍数,之后变量c存储于404040处,最后的变量d需要存储在倍数8的地址中,所以中间空余6个字节,在404048处开始存储。

02. x86处理器运行方式的更多相关文章

  1. ASM:《X86汇编语言-从实模式到保护模式》第10章:32位x86处理器的编程架构

    ★PART1:32位的x86处理器执行方式和架构 1. 寄存器的拓展(IA-32) 从80386开始,处理器内的寄存器从16位拓展到32位,命名其实就是在前面加上e(Extend)就好了,8个通用寄存 ...

  2. 6.3 x86处理器如何处理MSI-X中断请求

    PCIe设备发出MSI-X中断请求的方法与发出MSI中断请求的方法类似,都是向Message Address所在的地址写Message Data字段包含的数据.只是MSI-X中断机制为了支持更多的中断 ...

  3. 分配粒度和内存页面大小(x86处理器平台的分配粒度是64K,内存页是4K,所以section都是0x1000对齐,硬盘扇区大小是512字节,所以PE文件默认文件对齐是0x200)

    分配粒度和内存页面大小 x86处理器平台的分配粒度是64K,32位CPU的内存页面大小是4K,64位是8K,保留内存地址空间总是要和分配粒度对齐.一个分配粒度里包含16个内存页面. 这是个概念,具体不 ...

  4. 中国自主X86处理器工艺跃进:国产28nm升级16nm(上海兆芯)

    提到X86处理器,世人皆知Intel.AMD,殊不知还有个VIA(威盛),在Intel反垄断世纪大战中VIA公司作为Intel霸权的受害者也最终确认了X86授权,不过VIA与前面两家的实力相差太远,X ...

  5. [转帖]年经贴: ARM将为苹果开发高性能CPU核心 取代笔记本x86处理器?

    ARM将为苹果开发高性能CPU核心 取代笔记本x86处理器? https://www.cnbeta.com/articles/tech/899421.htm . 之前苹果的哥们说过 谁特别在意自己的软 ...

  6. [转帖]兆芯发布国产X86处理器KX-6000和KH-30000,性能提升达50%,附详情介绍

    兆芯发布国产X86处理器KX-6000和KH-30000,性能提升达50%,附详情介绍 2019-06-20 09:56:38作者:linux人稿源:快科技 https://ywnz.com/linu ...

  7. 【转帖】国产x86处理器KX-6000发布

    国产最先进x86处理器KX-6000发布:8核3.0GHz 力压酷睿i5处理器 https://www.cnbeta.com/articles/tech/858981.htm 全网所有的网页都写错了 ...

  8. [转帖]又一国产x86处理器可大规模上市:Intel至强核心 安全监测管控

    又一国产x86处理器可大规模上市:Intel至强核心 安全监测管控 https://www.cnbeta.com/articles/tech/850525.htm 不知道是不是有一起汉芯事件 国产CP ...

  9. 【X86】---X86处理器大小端的数据存储验证

    之前也关注过大小端的存储,可能时间久了,加之又之前的电脑抽象换成了当前的处理器寄存器的值判断,导致自己总是有点蒙圈.看Spec手册的时候,有时会无法与手册中某个Bit的值与RU/RW工具读出来的对应上 ...

  10. Linux从头学09:x86 处理器如何进行-层层的内存保护?

    作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...

随机推荐

  1. Scala 模式匹配拓展

    1 package chapter08 2 3 object Test03_MatchTupleExtend { 4 def main(args: Array[String]): Unit = { 5 ...

  2. 03-【HAL库】STM32实现SYN6288模块语音播报.md

    一.什么是SYN6288模块 1.概述 ​ SYN6288 中文语音合成芯片是北京宇音天下科技有限公司于2010 年初推出的一款性/价比更高,效果更自然的一款中高端语音合成芯片.SYN6288 通过异 ...

  3. ET介绍——浅谈AI框架

    AI框架 1. 几种AI的设计 AI在游戏中很多,但是为什么大家总是感觉ai编写起来十分困难,我后来思考了一番,主要原因是使用的方法不当.之前大家编写ai主要有几种方案: a. 状态机 我是不知道谁想 ...

  4. USACO 4.1

    目录 洛谷 2737 麦香牛块 分析 代码 洛谷 2738 篱笆回路 分析 代码 麦香牛块洛谷传送门,麦香牛块USACO传送门,篱笆回路洛谷传送门,篱笆回路USACO传送门 洛谷 2737 麦香牛块 ...

  5. #差分约束,Floyd#洛谷 2474 [SCOI2008]天平

    题目 分析 非传统差分约束?? 注意只有结果保证惟一的选法才统计在内 这就为差分约束提供了依据 以左边重为例,假设现在选择的砝码为\(i,j\), 那么\(\because A+B>i+j\th ...

  6. 机器学习服务活体检测算法荣获CFCA权威安全认证

    随着人脸识别技术在金融.医疗等多个领域的加速落地,网络安全.信息泄露等问题愈为突出,用户对应用稳定性和安全性的要求也更为严格.为保障各行业高效稳定的开展业务,提前发现和应对潜在安全风险,HMS Cor ...

  7. Ubuntu SVN 需要证书及密码验证问题

    问题概览 问题一 Ubuntu 20.04 下使用 SVN ,会报错 SVN 的证书错误,无论是选择接受 t 还是永久接受 p,下次都会要求再次接受:在 kali 或者 Windows 上没有出现该问 ...

  8. c# 框架系列 ———— EFCore 模型篇 [一]

    前言 简单介绍一下EfCore 的模型篇 正文 内容来源: 配置模型 配置模型的方式,一种是fluent api 还一种是属性的方式. public class Blog { public int B ...

  9. 重新点亮linux 命令树————网络管理[十一二]

    前言 简单整理一下网络管理. 正文 网络管理需要掌握: 网络状态查看 网络配置 路由命令 网络故障排除 网络服务管理 常用网络配置文件 网络状态的查看: 1.net-tools ---->1.i ...

  10. 部署iis7和vs2010低版本项目遇到的一些问题

    前提 本人一直用iis10然后用的是vs2015,项目框架也用的是高版本的,所以后来接触了一个项目,部署iis7遇到的一些问题,按顺序总结出来,希望有所帮助. 正文 按顺序来: 1.HTTP错误 40 ...