NEMU(RISC-V64)基础知识(一)

news2025/1/12 23:40:06

目录

1、术语和定义

2、CISC和RISC的区别

3、vimtutor指令查看常见VIM使用命令

4、GDB调试

5、x86中寄存器

6、x86中指令的具体行为

7、中断和异常

8、RISC-V的中断

9、一条指令在NEMU中的执行过程

10、NEMU中的输入输出

11、在NEMU的运行时环境中执行程序步骤

12、NEMU中的DiffTest(Differential Testing,差异测试)

13、NEMU实现RISC-V指令

1、术语和定义

  • 计算机(状态机模型视角):
    • 计算机根据当前时序逻辑部件(存储器、计数器、寄存器等)的状态,在组合逻辑部件(加法器等)的作用下,计算并转移到下一时钟周期的新状态
    • 程序运行过程:每执行完一条指令,进行一次确定的状态转移
  • 指令:计算机进行一次状态转移的输入激励

术语

全称

定义

ISA

Instruction Set Architecture

指令集架构,又称指令集或指令集体系,是计算机体系结构中与程序设计有关的部分,包含了基本数据类型,指令集,寄存器,寻址模式,存储体系,中断,异常处理以及外部I/O

MIPS

Microprocessor without Interlocked Pipeline Stages

MIPS指令集,指令长度为32位,有32个寄存器,运算只能存在于寄存器之间

(1)R型指令:op + rs + rt + rd + shamt + funct

rs/rt是源操作数所在寄存器号,rd是目标操作数所在寄存器号,shamt是位移量,funct是功能

(2)I型指令:op + rs + rt + constant or address

rs是源操作数,rt是目标操作数所在寄存器号,constant or address是第二个源操作数

(3)J型指令:op + address

address是转移地址(26位)

CISC

Complex Instruction Set Computer

复杂指令系统计算机,采用复杂指令实现软件功能的硬化。如x86架构

RISC

Reduced Instruction Set Computer

精简指令系统计算机,简化单条指令功能,复杂指令的功能由简单指令的组合来实现。尽量使用寄存器-寄存器操作指令,指令格式力求一致。如ARM、MIPS架构

riscv

RISC-V

第五代精简指令集,开放指令生态

x86

Intel x86 Architecture

含有8个32位通用寄存器

TRM

TuRing Machine

图灵机,有存储器、PC、寄存器、加法器,重复(1)从PC指示的存储器位置取出指令,(2)执行指令,(3)更新PC的过程。

SoC

System of Chip

系统级芯片,是产品级别,包含完整系统并有嵌入软件的全部内容

RTL

Register Transfer Level

寄存器传输级语言,不关注寄存器和组合逻辑的细节,通过描述寄存器到寄存器之间的逻辑功能描述电路的HDL层次

GPR

General Purpose Register

通用寄存器

2、CISC和RISC的区别

CISC

RISC

指令系统

复杂,庞大

简单,精简

指令数目

一般大于200条

一般小于100条

指令字长

不固定

定长

可访存指令

不加限制

只有Load/Store指令

指令执行时间

相差较大

绝大多数在一个时钟周期内完成

指令使用频度

相差很大

都比较常用

通用寄存器数量

较少

目标代码

难以用优化编译生成高效的目标代码程序

采用优化的编译程序,生成代码较为高效

控制方式

绝大多数为微程序控制

绝大多数为组合逻辑控制

指令流水线

可以通过一定方式实现

必须实现

3、vimtutor指令查看常见VIM使用命令

(1)hjkl:分别表示←、↓、↑、→移动
(2)$:指针到达行尾,0:返回到行首w:指针到达下一个词的词首,e:到达当前词的词尾
(3)dd:删除当前行,x:删除当前光标所指字符,dw:删除从光标到下一个单词之间的字符,d$:删除从光标起到该行结束。u:撤回操作,U:撤回整行的操作
(4)r[某字符]:将光标处字符替换为“某字符”
(5)G:到达文档尾部,gg:到达文档首部
(6)先输入冒号,然后有多种指令可以额外设置:

  • set number:显示行号
  • set cursorline:突出显示当前行

  • set hlsearch:高亮显示搜索到的文本

4、GDB调试

g++ hello.cpp -g -Wall -o helloworld:-Wall表示在编译时启用所有警告,-Werror表示将警告视为错误

  • break line:设置第line行的断点
  • delete line:删除第line行的断点
  • run:开始调试
  • step:执行下一行
  • continue:继续执行
  • watch xx:查看变量xx

5、x86中寄存器

  • x86处理器有8个32位的通用寄存器。E表示Extended的32位寄存器,EAX的低两位字节为AX,AX的高字节为AH,低字节为AL。
  • 汇编格式区别:
    • x86汇编格式中,第一个为目的操作数,第二个为源操作数,方向从右向左。AT&T,第一个为源操作数,第二个为目的操作数,方向从左向右。
    • AT&T汇编格式,寄存器需要加前缀%,立即数需要加前缀$;x86不用。
    • AT&T内存寻址用(),x86用[]

6、x86中指令的具体行为

(1)NEMU中的实现:

instruction_prefix

指令前缀,0或1字节

operand_size prefix

操作数宽度前缀,指示当前指令需要改变的操作数的宽度

opcode

操作码,1或2字节,操作码第二字节为\r表示后面跟着一个ModR/M字节,且ModR/M字节中reg/opcode域解释为通用寄存器的编码,用来表示一个操作数

ModR/M

操作码的补充码,0或1字节,用于确定指令操作数,R/M表示寄存器或内存,为低三位,Reg/Opcode为中三位,Mod取值为3表示为寄存器,否则为内存,为高二位,Opcode决定是否有ModR/M

SIB

对ModR/M的补充,0或1字节,包括Scale,Index,Base,ModR/M决定是否有SIB

displacement

地址偏移量,0,1,2,4字节

immediate

立即数,0,1,2,4字节

address_size prefix(NEMU不用到)

segment override(NEMU不用到)

(2)指令示例:

Opcode

Instruction

描述

88 /r

mov r/m8, r8

/r表示后面跟着一个ModR/M字节,且ModR/M字节中reg/opcode域解释为通用寄存器的编码,用来表示一个操作数,r/m8表示八位寄存器或内存,r8表示8位寄存器。指令表示传送一个8位寄存器的操作数到8位寄存器或内存

89 /r

mov r/m32, r32

指令表示传送一个32位寄存器的双字操作数到32位寄存器或内存

B8 + rd id

mov r32 imm32

+rd表示32位通用寄存器的编码,id表示32位立即数,指令表示传送一个32位立即数到32位寄存器中

A3

mov moffs32, eax

moffs32表示32位的段内偏移量。指令表示将eax寄存器的内容传送到moffs32段内偏移量的地址

7、中断和异常

(1)中断和异常:

  • 异常(内中断):当前指令执行过程中进行检测。CPU执行指令时,由CPU在其内部检测到的、与正在执行的指令相关的同步事件,分为故障(Fault)、陷阱(Trap)和终止(Abort)三类
    • 同步:产生原因能够被精确定位于某条指令
  • 中断(外中断):当前指令执行后进行检测。由外部设备触发的、与当前正在执行的指令无关的异步事件
    • 异步:产生原因不能被精确定位于某条指令

(2)异常分类:

  • 硬件中断:
    • 终止(Abort):指令执行中出现硬件故障,如控制器出错,越权,越级,栈溢出,存储器校验中断,主存故障
    • 外中断:ctrl+c、打印机缺纸
  • 软件中断:
    • 故障(Fault):指令启动后、执行结束前被检测到的异常事件,如缺页、缺段、出现非法操作码、整除0
    • 自陷(Trap):人为设定,在程序中用一条特殊指令或通过某种方式设定特殊控制标志来人为设置一个“陷入”,当执行到“陷入”指令时,CPU进入操作系统系统内核程序执行,完成相应“陷入”类型的处理,再执行自陷指令的下一条指令
      • 自陷可用于实现程序调试时的断点设置和单步跟踪

(3)中断分类:

  • 可屏蔽中断:通过INTR(可屏蔽中断请求线)向CPU发送中断请求信号,可以通过在中断控制器中设置相应的屏蔽字进行屏蔽中断请求信号
  • 不可屏蔽中断:通过NMI(不可屏蔽中断请求线)向CPU发送中断请求信号,不可被屏蔽

(4)异常和中断响应过程:

  • 关中断:中断允许触发器(IF)实现,IF=1为开中断,表示允许响应中断,IF=0为关中断,表示不允许响应中断
  • 保存断点和程序状态:将程序的断点(返回地址)和程序状态字寄存器(PSWR,Program Status Word Register)保存到栈或特定寄存器
  • 识别异常和中断:
    • 软件识别:异常状态寄存器记录异常原因
    • 硬件识别(向量中断):异常或中断处理程序(ISR,Interrupt Service Routine)的首地址为中断向量,所有中断向量存放在中断向量表中
  • 转到中断处理程序

(5)中断仲裁:存在多个中断优先级的中断源向处理器发起请求,处理器对中断源进行仲裁,划分处理顺序

  • RISC-V中存在四种中断类型:外部中断(External Interrupt)、计时器中断(Timer Interrupt)、软件中断(Software Interrupt)、调试中断(Debug Interrupt),中断优先级由高到低分别为:
    • 外部中断
    • 软件中断
    • 计时器中断
    • 调试中断只有调试器介入调试时才发生

(6)中断嵌套:前一个中断还没响应完,又开始响应新的中断

  • RISC-V硬件无法支持硬件中断嵌套行为,因为响应中断进入异常模式后,中断被全局关闭,无法响应新中断:
    • 进入异常后,mstatus寄存器的MIE域会被硬件自动更新为0,表示中断被全局关闭,无法响应新的中断
    • 退出中断后,MIE域才被硬件根据MPIE域的值恢复成中断发生之前的值,从而再次全局打开中断嵌套
  • 可以通过软件方式,在程序跳入中断服务程序后,强行修改mstatus寄存器的值,将MIE域置1,开启全局中断

8、RISC-V的中断

(1)进入异常:在目录ics2021/nemu/src/isa/riscv64/include中的isa-def.h文件的riscv64_CPU_state结构体定义CSR寄存器,当进入异常时,停止执行当前程序流,从mtvec寄存器定义的PC地址开始执行,同时更新mcause、mepc、mtval、mstatus寄存器

  • mtvec(Machine Trap-Vector Base-Address Register):机器模式异常入口基址寄存器,trap后进入异常的程序PC地址
  • mcause(Machine Cause Register):机器模式异常原因寄存器,定义了异常种类,包括高1位Interrupt域,低31位异常编号域,异常编号决定进一步跳转到具体的异常服务程序
  • mepc(Machine Exception Program Counter):机器模式异常PC寄存器,定义了异常返回地址,在进入异常时,硬件将自动更新mepc寄存器的值为当前遇到异常的指令PC值
  • mtval(Machine Trap Value Reisger):机器模式异常值寄存器,反映引起异常的信息,值为当前异常的存储器访问地址或者指令编码
  • mstatus(Machine Status Register):机器模式状态寄存器,其中MIE域表示在机器模式下控制中断全局使能,MPIE域的值更新为异常发生前MIE域的值,MPP域在异常结束之后,能够使用MPP的值恢复出异常发生之前的工作模式

(2)退出异常:

  • mret指令停止执行当前程序流,从CSR寄存器mpec定义的PC地址开始执行,rtl_j(s, cpu.mepc),并更新mstatus寄存器的某些域,MIE域的值更新为当前MPIE域的值,MPIE域的值更新为1
  • RISC-V规定的进入异常和退出异常机制中没有硬件保存和恢复上下文的操作,因此需要软件明确地使用指令进行上下文的保存和恢复

9、一条指令在NEMU中的执行过程

  • 取指:通过cpu_exec函数获取指令,decode.c文件中的isa_fetch_decode函数中调用了在ifetch.h头文件中定义的instr_fetch函数,该函数实现了从Decode结构体获得当前pc指向的指令,获得指令的opcode
  • 译码:首先执行cpu-exec.c文件的fetch_decode_exec_updatepc函数进行指令译码和更新pc的操作,实际调用fetch_decode函数。decode.c文件中的isa_fetch_decode函数int idx = table_main(s)实现了查表功能,def_INSTR_TAB宏定义了具体的译码工作,在riscv32中NEMU主要实现了I型指令、S型指令和U型指令。同时借助译码辅助函数和译码操作数辅助函数得到具体的操作对象。译码出来的结果作为查表操作,返回标识该指令的唯一ID
  • 执行:根据返回的idx调用对应的执行辅助函数def_EHelper,根据nemu_state.state的状态码判断是否执行成功,成功则输出“HIT GOOD TRAP”用户提示符
  • 更新pc:ifetch.h头文件中定义了instr_fetch函数,执行指令后,通过s->dnpc的赋值来进行更新pc的操作

10、NEMU中的输入输出

  • 访问设备 = 读出数据 + 写入数据  + 控制状态
    • 端口I/O(Port-Mapped I/O):设备寄存器地址进行编号,CPU用专门的I/O指令映射设备端口号对设备进行访问
    • x86中,in指令将设备寄存器中的数据传输到CPU寄存器,out指令将CPU寄存器中的数据传输到设备寄存器
    • 内存映射I/O(Memory-Mapped I/O,MMIO):通过不同的物理内存地址给设备编址,将一部分物理内存的访问重定向到I/O地址空间中
    • 控制状态本质上是对读/写设备寄存器的操作
  • 设备的输入输出通过CPU寄存器进行数据交互,输入输出对程序的影响仅仅体现在输入时会进行一次不能提前确定的状态转移

11、在NEMU的运行时环境中执行程序步骤

  • 步骤一:gcc编译AM(与架构相关的运行时环境)下的源文件为目标文件,通过Makefile文件中的ar命令将目标文件打包为静态链接库am-riscv64-nemu.a文件
  • 步骤二:在Makefile文件中定义gcc、g++等交叉编译,将程序源码编译成目标文件
  • 步骤三:在Makefile文件通过gcc和ar将程序依赖的运行库klib(kernel library,封装了与结构无关的库函数)等编译为静态链接文件
  • 步骤四:根据Makefile文件riscv64-nemu.mk文件的指示,ld链接脚本linker.ld将上述目标文件和静态链接文件链接成为可执行文件(LD各ELF文件,executable and linkable format,跨平台的标准文件格式)
  • 步骤五:通过汇编文件start.S定义了栈顶元素,主程序入口,跳转到trm.c文件的_trm_init()函数执行,进行TRM相关的初始化工作
  • 步骤六:执行_trm_init()函数中的main()函数执行程序的主体功能
  • 步骤七:程序执行结束,则调用halt()函数结束运行
  • 附注:文件位置如下:
    • Makefile:/home/Dengqy/ics2021/abstract-machine/Makefile
    • am-riscv64-nemu.a:/home/Dengqy/ics2021/abstract-machine/am/build/am-riscv64-nemu.a
    • riscv64-nemu.mk:/home/Dengqy/ics2021/abstract-machine/scripts/riscv64-nemu.mk
    • linker.ld:/home/Dengqy/ics2021/abstract-machine/scripts/linker.ld
    • start.S:/home/Dengqy/ics2021/abstract-machine/am/src/riscv/nemu/start.S
    • trm.c:/home/Dengqy/ics2021/abstract-machine/am/src/platform/nemu/trm.c

12、NEMU中的DiffTest(Differential Testing,差异测试)

(1)定义:提供一个和DUT(Design Under Test,测试对象)功能相同但实现方式不同的REF,二者接受相同有定义的输入,观测它们的行为是否相同。
(2)在NEMU中检查执行每一条指令后DUT和REF(其他的全真系统模拟器)的状态(二元组S=<R, M>)是否一致,定义的API:

  • difftest_regcpy:获取及设置REF的寄存器状态到DUT
  • dlsym函数:根据动态链接库操作句柄与符号,返回符号对应的地址
  • difftest_memcpy:在DUT host memory的buf和REF guest memory的dest间拷贝n个字节
  • difftest_exec:REF执行n条指令
  • difftest_step:让REF执行和nemu相同的指令,然后独处REF中的寄存器,进行对比
  • difftest_checkregs:把通用寄存器和PC从DUT中读出的寄存器的值进行比较,并返回布尔值
  • difftest_skip_dut:跳过dut的指令检查,因为dut的单步执行可能会执行多条指令
  • difftest_skip_ref:ref跳过无法与nemu产生一致行为的指令

13、NEMU实现RISC-V指令

(1)RISC-V定义了32个通用寄存器,其中x0寄存器值恒为0,可使用x0寄存器作为操作数,来完成相同功能的操作。指令长度固定,为32位。共有六种基本指令。

  • 字长(word length):ALU正常处理的信息量的大小
  • 每一个元素被称为一个字(word)

  • rd为目的操作寄存器(destination register),指定保存执行结果的寄存器
  • opcode为操作码,区分指令的类别
  • funct3和funct7分别为区分某类指令下的具体指令的三位功能码和七位功能码
  • rs1是第一个源操作数寄存器(source register),rs2为第二个源操作数寄存器
  • imm为立即数(immediate)

(2)寄存器:

寄存器

ABI名称

说明

x0

zero

0值寄存器,硬编码为0,写入数据忽略,读取数据为0

x1

ra

用于返回地址(return address)

x2

sp

用于栈指针(stack pointer)

x3

gp

用于通用指针(global pointer)

x4

tp

用于线程指针(thread pointer)

x5

t0

存放临时数据或备用链接寄存器

x6-x7

t1-t2

存放临时数据寄存器

x8

s0/fp

需要保存的寄存器或帧指针寄存器

x9

s1

需要保存的寄存器

x10-x11

a0-a1

函数传递参数寄存器或函数返回值寄存器

x12-x17

a2-a7

函数传递参数寄存器

x18-x27

s2-s11

需要保存的寄存器

x28-x31

t3-t6

存放临时数据寄存器

PC:RISC-V当前PC值即当前指令的地址

(3)不同类型指令解析

  • rs1是第一个源操作数寄存器(source register),rs2为第二个源操作数寄存器
  • imm为立即数(immediate)
  • R型指令:定义了“寄存器-寄存器”的运算指令
    • opcode:0110011
    • funct3和funct7:add为0000000、000;sub为0100000、000;sll为0000000、001;slt为0000000、010;sltu为0000000、011;xor为0000000、100;srl为0000000、101;sra为0100000、101;or为0000000、110;and为0000000、111。
    • 包括指令:add、sub、sll(逻辑左移,shift left logical)、srl(逻辑右移,shift right logical)、sra(算术右移,shift right arithmetic)、slt(三元运算符,set less than)、sltu(无符号比较三元运算符,set less than unsigned)、xor(异或,exclusive or)、or(或)、and(与)
    • op rd, rs1, rs2,即rd ← (rs1) op (rs2)
  • I型指令:定义了短立即数-寄存器指令和读内存load指令
    • 短立即数-寄存器指令
      • opcode:0010011
      • funct3:addi为000、slti为010、sltiu为011、xori为100、ori为110、andi为111、slli为001、srli为101、srai为101
      • funct7:slli为0000000、srli为0000000、srai为0100000
      • 包括指令:addi、slti、sltiu、xori、ori、andi、slli、srli、srai
      • op rd, rs1, imm,即rd ← (rs1) op imm
    • 读内存load指令,从存储器读出数据装入寄存器
      • opcode:0000011
      • funct3:lb为000,lbu为100,lh为001,lhu为101,lw为010
      • 包括指令:lb(将值作为地址,取出该地址所对应的内存中的8位数值)、lh(内存中取出16位数值)、lw(内存中取出一个字,即32位数值)、lbu(内存中取出8位无符号数值)、lhu(内存中取出16位无符号数值)
      • op rd, rs1, imm,即rd ← M[(rs1) + imm]
  • S型指令:访存写入Sotre(byte、halfword、word),将寄存器的数据存入存储器
    • opcode:0100011
    • funct3:sb为000,sh为001,sw为010
    • 包括指令:sb(写入低8位)、sh(写入低16位)、sw(写入低32位)
    • op rs2, imm(rs1),即(rs2) → M[imm + (rs1)]
  • B型指令:定义了分支转移,条件满足,(PC) + imm → PC,否则(PC) + 4 → PC
    • opcode:1100011
    • func3:beq为000,bne为001,blt为100,bge为101,bltu为110,bgeu为111
    • 包括指令:beq(a1==a2则跳转,branch on equality)、bne(a1!=a2则跳转,branch on not equality)、blt(a1<a2则跳转,branch on less than)、bge(a1≥a2,branch on greater than or equal)、bltu(branch on less than unsigned)、bgeu(branch on greater than or equal unsigned)
  • U型指令:定义了长立即数
    • opcode:lui为0110111,auipc为0010111
    • 包括指令:lui(得到立即数的高二十位,低位补零,装入寄存器,load upper immediate)、auipc(组装32位相对偏移地址,得到立即数的高二十位,低位补零,与PC值相加,装入寄存器,add upper immediate to pc)
  • J型指令:定义了无条件跳转,过程调用和返回
    • opcode:jal为1101111,jalr为1100111
    • funct3:jalr为000
    • 包括指令:过程调用jal(jal x1, label:将下一条指令的地址(返回地址)保存到x1寄存器,程序跳转到label,jump and link)、返回jalr(跳转到存储在x1中的地址,jump and link register)
    • jalr:rd ← PC + 4, PC ← (rs1) + imm,jal:pc ← (PC) + imm

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

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

相关文章

HarmonyOS使用ArkUI绘制圣诞树

一、前言 起因我参加了 “挑战代码画颗圣诞树” 活动&#xff0c;又因为本次推出一个“圣诞定制勋章”活动&#xff0c;一个是传资源&#xff0c;一个是写文章&#xff0c;为了更好的把知识传递给大家&#xff0c;所以我又出了这篇文章&#xff0c;大家进来一起学习一下吧。 二…

Linux- 系统随你玩之--操作文件和目录

文章目录1、前言2、文件、目录相关的指令2.1、当前所在目录2.2、当前目录所有的文件和目录2.3、切换当前工作目录2.4、 创建目录与文件2.6 、拷贝文件3 、文本查看3.1、cat 查看文件内容3.2、head 查看前n行内容3.3、tail 查询后n行内容4、文本编辑4.1、vi 指令4.2、more 指令4…

华为三层交换机做中继,WinServer2012当DHCP服务器

ENSP桥接一台 Windows Server&#xff0c;当DHCP服务器 1、拓扑图 2、汇聚交换机设置 <Huawei>sys# 关闭消息提示 [Huawei]undo in en[Huawei]sys SW1# 批量创建 VLAN [SW1]vlan batch 10 20 30 100# 设置 VLAN 为 Trunk [SW1]int g0/0/1 [SW1-GigabitEthernet0/0/1]p…

【电商】电商后台---FMS财务管理系统

文章对电商财务系统进行了系统的介绍&#xff0c;希望通过此文能够加深你对电商系统的认识。 目前互联网电商公司的系统非常多、系统间的关系也非常复杂&#xff0c;最近各公司都热衷于中台&#xff0c;应用的技术也相当之多&#xff0c;技术实力弱点的公司只能借助于各平台加快…

uAvionix获得FAA合同,部署和演示多个无人机同时飞行的C波段频率分配管理(FAM)

uAvionix宣布&#xff0c;它已赢得美国联邦航空管理局(FAA)的合同&#xff0c;作为uAvionix SkyLine™指挥和控制通信服务提供商(C2CSP)管理平台的组件&#xff0c;对频率分配管理器(FAM)进行多次端到端演示。 这次大规模演示将使运营SkyLine平台的频率管理组织(FMO)能够将国际…

基于STM32与TB6600的机械臂项目(代码开源)

前言&#xff1a;本文为手把手教学STM32的机械臂项目——Robot Arm&#xff0c;本次项目采用的是STM32作为MCU。该机械臂的基础模型为国外开源项目&#xff0c;诸多前辈经过长时间的验证与改进&#xff0c;其机械臂精度可以满足日常需求。本项目机械臂为三自由度机械臂&#xf…

mongodb-9.数据库连接,集合创建

文章目录数据库连接集合创建查询删除查询显示指定字段限制查询条数 limit &#xff0c;skip排序索引创建聚合查询数据库连接 mongodb URL mongodb://[username:password]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]语法说明如下&#xff1a;…

JSP ssh网络点餐系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 JSP ssh网络点餐系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式 开发。开发环境为TOMCAT7.0,Mye…

vue3 antd项目实战——input输入框限制输入内容和长度,Form表单动态校验规则

input输入框设置只能输入中文&#xff0c;输入长度为20&#xff0c;输入不能为空知识调用场景复现解决方案1.下方有提示文字2.限制输入内容只能是中文3.限制输入长度为204.动态校验规则&#xff08;必填项&#xff09;input源代码&#xff08;按需调整即可&#xff09;知识调用…

【区块链 | EVM】深入理解学习EVM - 深入理解EVM操作码,让你写出更好的智能合约

那些非典型的开销导致经典的软件设计模式在合约编程语言中看起来既低效又奇怪。如果想要识别这些模式并理解他们导致效率变高/低的原因&#xff0c;你必须首先对以太坊虚拟机&#xff08;即 EVM&#xff09;有一个基本的了解。 你的一些编程“好习惯”反而会让你写出低效的智能…

Linux当中的Sersync实时同步服务及其实战举例

目录 一、实时同步 1.定义 2.原理 3.实时同步场景 4.实时同步工具 &#xff08;1&#xff09;sersync &#xff08;2&#xff09;Lysncd 二、实时同步实例 1.环境规划 2.配置思路 NFS存储服务如下&#xff1a; &#xff08;1&#xff09;安装NFS &#xff08;2&am…

40. 使用块的网络(VGG)

虽然AlexNet证明深层神经网络卓有成效&#xff0c;但它没有提供一个通用的模板来指导后续的研究人员设计新的网络。 在下面的几个章节中&#xff0c;我们将介绍一些常用于设计深层神经网络的启发式概念。 与芯片设计中工程师从放置晶体管到逻辑元件再到逻辑块的过程类似&#x…

Node.js--》三大常见模块的使用讲解

目录 fs文件系统模块 fs.readFile()方法 fs.writeFile()方法 readFile与writeFile的使用 fs模块路径动态拼接问题 path路径模块 path.join()方法 path.basename() path.extname() path.parse() http模块 req请求对象 res响应对象 解决中文乱码问题 响应不同内容…

Python实现猎人猎物优化算法(HPO)优化支持向量机回归模型(SVR算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 猎人猎物优化搜索算法(Hunter–prey optimizer, HPO)是由Naruei& Keynia于2022年提出的一种最新的优…

计算机系统基础实验 - 同符号浮点数加法运算/无符号定点数乘法运算的机器级表示

实验3 同符号浮点数加法运算/无符号定点数乘法运算的机器级表示 实验序号&#xff1a;3 实验名称&#xff1a;同符号浮点数加法运算/无符号定点数乘法运算的机器级表示 适用专业&#xff1a;软件工程 学 时 数&#xff1a;2学时 一、实验目的 1.掌握定点数乘法溢出的判定方法…

Kafka触发Rebalance的场景分析

文章目录前言触发Rebalance的原因1. 消费者成员发生变化2. 分区数发生变化3. 订阅Topic发生变化Rebalance全流程介绍场景一&#xff1a;新成员入组场景二&#xff1a;成员主动离组场景三&#xff1a;成员崩溃离组场景四&#xff1a;组成员提交位移前言 所谓Rebalance就是让Con…

Python小工具-复制嵌套目录下的多个word文档到指定目录

文章目录Python小工具-复制嵌套目录下的多个word文档到指定目录需求原始数据工具实现思路代码实现1-6 配置项目7 定义file_type_to_reduce_dir函数完成文件复制或移动8 定义list_dir_by_level函数完成遍历调用函数并执行待改进地方完整代码自我反省Python小工具-复制嵌套目录下…

全志 Linux 系统启动优化 启动优化速度方式 优化启动流程 优化uboot 优化kernel等

文章目录1 概述2 启动速度优化简介2.1 启动流程2.2 测量方法2.2.1 printk time2.2.2 initcall_debug2.2.3 bootgraph.2.2.4 bootchart2.2.5 gpio 示波器.2.2.6 grabserial.2.3 优化方法2.3.1 boot0启动优化2.3.1.1 非安全启动.2.3.1.2 安全启动2.3.2 uboot启动优化2.3.2.1 完全…

07、SpringCloud 系列:Alibaba - 介绍

SpringCloud 系列列表&#xff1a; 文章名文章地址01、Eureka - 集群、服务发现https://blog.csdn.net/qq_46023503/article/details/12831902302、Ribbon - 负载均衡https://blog.csdn.net/qq_46023503/article/details/12833228803、OpenFeign - 远程调用https://blog.csdn.…

一套ASP.NET优惠券领取微信小程序源码(前台+后台)

ASP.NET优惠券领取微信小程序源码&#xff08;前台后台&#xff09; 源码免费分享&#xff01;需要源码学习可私信我。 一、源码特点 1、这是一个微信小程序对接淘宝的淘宝客api自助搜索优惠券领取程序&#xff0c;简单易学。 2、后台采用asp.netMvc框架开发、实现了调用阿里妈…