5. ARM_指令集

news2024/11/19 10:42:16

概述

分类

汇编中的符号:

  • 指令:能够编译生成一条32位机器码,并且能被处理器识别和执行
  • 伪指令:本身不是指令,编译器可以将其替换成若干条指令
  • 伪操作:不会生成指令,只是在编译阶段告诉编译器怎么编译

对于不同的CPU,指令和伪指令不同。因为指令和伪指令都由CPU来直接识别。

对于不同的编译器,伪操作不同,因为伪操作是控制编译器编译的。

ARM指令集的分类:

  • 数据处理指令:进行数学运算、逻辑运算
  • 跳转指令:实现程序的跳转,本质就是修改了PC寄存器
  • Load/Store指令:访问(读写)内存
  • 状态寄存器传送指令:用于访问(读写)CPSR寄存器
  • 软中断指令:触发软中断
  • 协处理器指令:操作协处理器的指令

其中数据处理指令、跳转指令、Load/Store指令是通用指令,任何一个CPU都具有该指令。并且这些指令在C语言中都有对应的语句。

指令格式:

汇编语言不区分大小写,但是不要出现一个指令里面既有大写也有小写。比如:可以写MOV或mov,但不要写成Mov 

立即数

什么是立即数:

立即数就是能够写在指令后面的数,例如 " MOV R0 #1 " 这个#1当中的数就是立即数。

立即数的本质就是包含在指令当中的数,属于指令的一部分。

注意:立即数不能写到32位,因为汇编指令转为机器码后是32位,这32位中有几位用来表示指令含义和寄存器含义,因此数据位并没有32位。

立即数与变量的区别:

立即数是指令的一部分,在使用立即数赋值时,CPU直接从机器码中就可以获取数据,不需要从内存中读取相应的值。

变量是存放在内存中,通过变量赋值,CPU必须先从内存中取出,再进行赋值。

32位非立即数却可赋值的情况:

当我们使用MOV R0, #0xFFFFFFFF这个指令时,0xFFFFFFFF是一个32位的数,一定不是一个立即数,但最终编译未出错。具体的编译器处理结果如下:

在这里,编译器将MOV R0, #0xFFFFFFFF 替换成了 MVN R0,#00000000,这个MVN的指令就是CPU可以识别执行的指令,原先的MOV就被称作伪指令。

条件码

条件码就是一个条件,当条件满足时执行这个操作,条件不满足时不执行该操作。

大多数的指令后都可以添加条件,具体示例见"跳转指令" - "2、B"

在使用条件码时,需要先使用CMP进行比较,之后再使用条件码进行条件执行。

条件码如下:

数据处理指令

1、数据搬移指令

1.1 MOV

将指定的数据搬移(赋值)到指定的寄存器中。

格式:

MOV 目标寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源操作数:可以是立即数,也可以是寄存器

示例:

将立即数3搬移到寄存器R1,即:令R1=3

MOV R1, #3     @ #3代表十进制的3,#0x3代表十六进制的3

将R2寄存器的值搬移到寄存器R1,即:令R1=R2

MOV R1, R2

1.2 MVN

将指定的数据按位取反后,搬移(赋值)到指定的寄存器中。

格式: 

MVN 目标寄存器, 源操作数

示例:

将立即数0xFF取反后的值搬移到寄存器R1,即:令R1 = ~0xFF。

注意:这时R1存放的值为0xFFFFFF00,而不是0,因为ARM的寄存器是32位,所以在ARM寄存器中0xFF的存放值是0x000000FF,因此按位取反后为0xFFFFFF00,而不是0。

MVN R1 #0xFF

2、数值运算指令

一般格式:<操作码> <目标寄存器> <第一操作寄存器> <第二操作数>

  • 操作码:执行什么操作,如加减乘除
  • 目标寄存器:用于存放运算结果
  • 第一操作寄存器:必须是一个寄存器,是参与运算的数。
  • 第二操作数:可以是寄存器,也可以是立即数,这也是参与运算的数。

2.1 ADD

加法指令,将指定的两个数进行相加,结果存入指定的寄存器。

格式:

ADD 目标寄存器, 源寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

源操作数:可以是立即数,也可以是寄存器

示例:

已知R2=5,R3=3,实现R1=R2+R3

MOV R2,#5
MOV R3,#3
ADD R1,R2,R3 @ R1 = R2 + R3

已知R2=5,实现R1=R2+5

MOV R2,#5
ADD R1,R2,#5 @ R1 = R2 + 5
注意:这里不能写成ADD R1,#5,R2 对应ADD只有最后一个为源操作数

2.2 ADC

带进位的加法指令,将指定的两个数进行相加,并且会加上CPSR的进位。 

ADC实现64位运算:

实现:

0x00000001 00000002 + 0x00000003 00000004

思路:

将第一个数的低位和高位分别存放在R1、R2;将第二个数的低位和高位分别存放在R3、R4;将结果的低位和高位分别存放在R5、R6

运算代码:

MOV R1,0x00000002
MOV R2,0x00000001
MOV R3,0x00000004
MOV R4,0x00000003

ADDS R5,R1,R3 @将两个低位相加并允许设置CPSR
ADC R6,R2,R4  @将两个高位相加并加上CPSR的C位(溢出进位)

ADCS实现128位运算:

实现:

0x00000001 00000002 00000003 00000004 + 0x00000005 00000006 00000007 00000008

运算代码:

MOV R1,0x00000004
MOV R2,0x00000003
MOV R3,0x00000002
MOV R4,0x00000001

MOV R5,0x00000008
MOV R6,0x00000007
MOV R7,0x00000006
MOV R8,0x00000005

ADDS R9,R1,R5     @将两个低位相加并允许设置CPSR
ADCS R10,R2,R6    @将两个高位相加并加上CPSR的C位(溢出进位)并允许设置CPSR
ADCS R11,R3,R7    @将两个高位相加并加上CPSR的C位(溢出进位)并允许设置CPSR
ADC  R12,R4,R8    @将两个高位相加并加上CPSR的C位(溢出进位)

2.3 SUB

减法指令,将指定的两个数进行相减,结果存入指定的寄存器。

该指令只能实现 "寄存器 - 寄存器" 或者 "寄存器 - 立即数" 但实现不了 "立即数 - 寄存器"

格式:

SUB 目标寄存器, 源寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

源操作数:可以是立即数,也可以是寄存器

注意:SUB减法中有顺序,源寄存器存放的是被减数,源操作数存放的是减数。

示例:

已知R2=5,R3=3,实现R1=R2-R3

MOV R2,#5
MOV R3,#3
SUB R1,R2,R3 @ R1 = R2 - R3

已知R2=5,实现R1=R2-5

MOV R2,#5
SUB R1,R2,#5 @ R1 = R2 - 5
注意:这里不能写成SUB R1,#5,R2 对应SUB只有最后一个为源操作数

2.4 SBC

带借位的减法指令,将指定的两个数进行相减,并且会减去CPSR的借位(C位取反)。

SBC实现64位运算:

实现:

0x00000002 00000001 - 0x00000001 00000002

运算代码:

MOV R1,0x00000001
MOV R2,0x00000002
MOV R3,0x00000002
MOV R4,0x00000001

SUBS R5,R1,R4 @将两个低位相减并允许设置CPSR
SBC R6,R2,R5  @将两个高位相减并减去CPSR的C位取反(借位)

2.5 RSB

逆向减法指令,将指定的两个数进行相减,结果存入指定的寄存器。

该指令通过被减数与减数调换,解决了SUB不能实现"立即数 - 寄存器"的问题。

格式:

RSB 目标寄存器, 源寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

源操作数:可以是立即数,也可以是寄存器

注意:RSB减法中有顺序,源寄存器存放的是减数,源操作数存放的是被减数。这与SUB相反。

示例:

实现R1 = 3 - R2。

RSB R1,R2,#3     @ R1 = 3 - R2

2.6 MUL

乘法指令,将指定的两个数进行相乘,结果存入指定的寄存器。

格式:

MUL 目标寄存器, 源寄存器, 源寄存器

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

注意:乘法指令中只能是两个寄存器相乘,不能使用立即数。

示例:

实现R1 = R2 * R3。

MUL R1,R2,R3     @ R1 = R2 * R3

3、位运算指令

3.1 AND

按位与指令,将指定的两个数进行按位与,结果存入指定的寄存器。

格式:

AND 目标寄存器, 源寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

源操作数:可以是立即数,也可以是寄存器

示例:

实现R1 = R2 & R3。

AND R1,R2,R3     @R1 = R2 & R3

3.2 ORR

按位或指令,将指定的两个数进行按位或,结果存入指定的寄存器。

格式:

ORR 目标寄存器, 源寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

源操作数:可以是立即数,也可以是寄存器

示例:

实现R1 = R2 | R3。

ORR R1,R2,R3     @R1 = R2 | R3

3.3 EOR

按位异或指令,将指定的两个数进行按位异或,结果存入指定的寄存器。

格式:

EOR 目标寄存器, 源寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

源操作数:可以是立即数,也可以是寄存器

示例:

实现R1 = R2 ^ R3。

EOR R1,R2,R3     @R1 = R2 ^ R3

3.4 LSL

左移指令,将指定的数左移指定的位,结果存入指定的寄存器。

格式:

LSL 目标寄存器, 源寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

源操作数:可以是立即数,也可以是寄存器

示例:

实现R1 = R2 << 3

方式1:寄存器法
MOV R3,#3
LSL R1,R2,R3 @R1 = R2 << 3

方式2:立即数法
LSL R1,R2,#3 @R1 = R2 << 3

 3.4 LSR

右移指令,将指定的数右移指定的位,结果存入指定的寄存器。

格式:

LSR 目标寄存器, 源寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

源操作数:可以是立即数,也可以是寄存器

示例:

实现R1 = R2 >> 3

方式1:寄存器法
MOV R3,#3
LSR R1,R2,R3 @R1 = R2 >> 3

方式2:立即数法
LSR R1,R2,#3 @R1 = R2 >> 3

3.5 BIC

位清零指令,将指定的位进行清零,结果存入指定的寄存器。

格式:

BIC 目标寄存器, 源寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

源操作数:可以是立即数,也可以是寄存器

注意:清零源操作数为1的位数,为0的位数不进行操作。但源寄存器的数值不进行改变

示例:

已知R2=0xFF,实现将R2低四位清零,并把结果写入到R1中,并且R2值不进行改变。

MOV R2,#0xFF
BIC R1,R2,#0x0F @0x0F的低四位为1,所以R2的低4位被清零,结果存入到R1
                @运算之后R1=0xF0,R2=0xFF(值不改变)

4、其他

4.1 格式扩展

格式扩展示例:

MOV R3, R0, LSL #3 ; 将R0的值左移3位后存入R3

格式扩展指令的看法:

首先这里面有MOV、LSR这两个指令,最前面的MOV是操作码,所以这个整体指令的功能是数据搬移功能,因此R0为第一操作数,LSL #3为第二操作数。

这里的LSL #3并不是一个指令,含义是左移3,操作的数据源就是前面的R0,返回的结果存放在前面的R3。因此最终功能是将R0的值左移3位后存入R3。

4.2 运算影响CPSR

指令后加S影响CPSR:

默认情况下,数据运算不会对CPSR的条件位产生影响。当指令加上后缀 "S" 后,即可影响CPSR

MOV R1,#3
SUB R2,R1,#5   @这计算是一个负数,但没有加S后缀,所以CPSR的N位不置1

MOV R1,#3
SUBS R2,R1,#5  @这计算是一个负数,加了S后缀,所以CPSR的N位置1

跳转指令

1、CMP指令

比较指令,比较两个寄存器值中的关系,比较的结果存储再CPSR的NZCV中。

CMP的本质就是一条减法指令(SUBS),只是没有将运算结果存入寄存器。

格式:

CMP 源寄存器1 源寄存器2

当源寄存器1 == 源寄存器2时,CPSR中的 Z = 1。

当源寄存器1 != 源寄存器2时,CPSR中的 Z = 0。

当源寄存器1 < 源寄存器2时,CPSR中的 C = 0。

当源寄存器1 <= 源寄存器2时,CPSR中的 C = 0 或者 Z = 1。

当源寄存器1 > 源寄存器2时,CPSR中的 C = 1 且 Z = 0(相等时也不产生借位)。

当源寄存器1 >= 源寄存器2时,CPSR中的 C = 1。

示例:

实现1~100求和,结果存入R2。 

2、B

跳转到指定的位置。跳转指令的本质就是修改PC指向。

注意:默认情况下LR不会自动保存下一条指令的地址,加上后缀 "L" 可以允许LR保存下一条指令的地址。

B称为不带返回的跳转指令,BL称为带返回的跳转指令。

格式:

B 条件码 标签

条件码可以不写,当不写时为无条件跳转,当写时为有条件跳转。 条件码如下:

示例:

1、无返回跳转到FUNC标号下的第一条指令位置。

当执行 " B FUNC " 之后,PC将指向 "MOV R6,#6" 并在下一次执行该指令。

2、有返回跳转到FUNC标号下的第一条指令位置,执行之后再返回。

当执行 " BL FUNC " 之后,PC将指向 "MOV R6,#6" 并且 LR存储了 "MOV R4,#4"的位置。

当执行 " MOV PC,LR "之后,PC将指向 "MOV R4,#4" 实现了返回。

 3、条件跳转,当R1=R2时,跳转到FUNC

当指向 "BEQ FUNC" 后,因为R1==R2不成立,所以不跳转,继续执行 "MOV R3,#3" 指令

4、跳转到自身

指令 "B ." 代表跳转到自身。

比如 "B ." 存在0x00000004处,执行完该指令后PC依旧指向0x00000004

Load/Store指令

1、单寄存器内存访问

1.1 STR

将指定寄存器中的数据存储到指定的内存地址中。

指令与存放数据的字节数:

  • STR   -- 4字节
  • STRH -- 2字节
  • STRB -- 1字节

格式:

STR 源寄存器 [目标寄存器]

目标寄存器中存放内存的地址

注意:源寄存器中数据为多少字节,那么目标寄存器存放的地址就得为多少的整数倍。

示例:

将R1的数据写入到R2存放的地址的位置。

这里R2存放的0x40000000为内存,这是因为地址映射时规定了这个地址是内存的起始地址。

这里R1的数据为0xFF000000是4字节,因此R2存放的地址应该为4的整数倍,所以如果R2的值为0x40000001,这就是错误的地址。

1.2 LDR

将指定的内存地址中的数据读取到指定寄存器中。

指令与取出数据的字节数:

  • LDR   -- 4字节
  • LDRH -- 2字节
  • LDRB -- 1字节

 格式:

LDR 目标寄存器 [源寄存器]

源寄存器存放的是所需取数据的数据地址。

示例:

将R2中存放的地址的数据读出来,存放到R3当中。 

该代码运行结束后,R3就存放了0xFF000000

2、多寄存器内存访问

2.1 STM

将多个寄存器中的数据存储到指定的内存地址中。

格式:

STM 目标地址 {源寄存器}

源寄存器:当寄存器连续时,使用 "-"链接;当寄存器不连续时,使用 ","分隔。

如 "STM R11,{R1-R4}" 这操作的时R1、R2、R3、R4

如 "STM R11,{R1,R4}" 这操作的时R1、R4

示例:

将R1~R4寄存器的值存放到以某个地址为起点的地址空间

这里的R11没有加 "[ ]",但它的数据含义代表地址

列表顺序并不是真正的存储顺序, 存储顺序一定是小编号的寄存器存低地址数据。

如上述STM指令写成 "STM R11,{R1,R4,R2,R3}",存储顺序依旧是和 "STM R11,{R1-R4}"一致,而不是0x40000020存放R1,0x40000024存放R4....

2.2 LDM

将指定的内存地址中的数据读取到多个寄存器中。

格式:

LDM 读取起始地址 {目标寄存器}

目标寄存器:当寄存器连续时,使用 "-"链接;当寄存器不连续时,使用 ","分隔。

如 "LDM R11,{R6-R9}" 这操作的时R6、R7、R8、R9

如 "LDM R11,{R6,R9}" 这操作的时R6、R9

示例:

将某个地址为起点的地址空间的数据读取到R6~R9寄存器中

这里的R11没有加 "[ ]",但它的数据含义代表地址

列表顺序并不是真正的存储顺序, 存储顺序一定是小编号的寄存器存低地址数据。

如上述LDR指令写成 "LDR R11,{R6,R9,R7,R8}",存储顺序依旧是和 "LDR R11,{R6-R9}"一致。

状态寄存器传送指令

该指令常用于操作系统内部,比如刚上电时,初始化系统时使用该指令。

1、MRS

将CPSR的值读取到指定寄存器

格式:

MRS 目标寄存器 CPSR

示例: 

2、MSR

将指定数据写入到CPSR中

注意:特权模式下可以只写改变CPSR的值,User模式下不能直接改变CPSR的值。

 格式:

MSR CPSR 源操作数

示例:

软中断指令

1、SWI

该指令常用于操作系统内部,比如在User模式下调用系统调用时,Linux就会写一个SWI的指令将User模式转换成SVC模式,从而有足够的权限处理硬件。这个过程其实就是使用SWI指令将用户态切换到内核态。

格式:

SWI #参数

参数:这个值用于区分不同的硬件。用户态切换到内核态都是调用SWI来实现,但究竟调用哪一个硬件CPU并不清楚,此时CPU就需要该参数来得知调用哪一个硬件。

2、模拟实现软中断处理过程

流程描述:

  • 当程序复位,PC指向0x00处,0x00处存放了异常向量表Reset,跳转到MAIN函数。
  • 执行MAIN函数到SWI语句,产生了软中断异常。软中断异常是由SVC模式进行处理,所以CPU自动拷贝CPSR到SPSR_svc中,并且修改CPSR、保存返回地址到LR_svc,最后将PC指向异常向量表对应位置。对于软中断,对应地址为0x80,因此PC跳转到0x80。
  • PC到达0x80后执行跳转指令,跳转到中断处理函数。
  • 中断处理函数也是一个函数,因此需要先入栈保存现场,之后进行相关的操作,最后出栈恢复现场。在出栈时,加上 "^" 符号可以自动将SPSR_svc的数据拷贝到CPSR恢复现场,同时出栈数据可以直接写到PC中,一步实现出栈、恢复现场、跳转。

实验代码如下:

.text
.global _start
_start:

	@异常向量表
	B MAIN				@Reset 			0x00
	B .					@Undef			0x04
	B SWI_Handler		@SWI			0x08
	B .					@Prefetch Abort	0x0C
	B .					@Data Abort		0x10
	B .					@Reserved		0x14
	B .					@IRQ			0x18
	B . 				@FIQ			0x20

	@MAIN中实现R3=R1+R2,并调用一次SWI
MAIN:
	MOV SP,#0x40000020 	@初始化SP,这里是SVC模式下的SP
	MSR CPSR,#0x10	  	@将模式改为User模式,IRQ/FIQ使能
	MOV R1,#1
	MOV R2,#2
	SWI #1				@调用SWI,#1用于区分硬件
	ADD R3,R1,R2
	B STOP

	@SWI_Handler是SWI的中断处理函数,这里也实现R3=R1+R2的功能
SWI_Handler:
	STMFD SP!,{R1,R2,LR}		@入栈保护现场
	MOV R1,#20
	MOV R2,#30
	ADD R3,R1,R2
	LDMFD SP!,{R1,R2,PC}^	@将LR的数据出栈到PC,并把SPSR的值拷贝到CPSR(^的作用)

STOP:
	B STOP

.end

协处理器指令

协处理器指令的分类可以分为:

  • 数据运算指令CDP
  • 存储器访问指令STC、LDC
  • 寄存器传送指令MRC、MCR,用于在协处理器和ARM处理器中的寄存器进行数据交互。

伪指令

1、NOP

NOP是让程序什么都不干,暂停一个机器周期。最终编译之后NOP会被编译成MOV R0,R0

2、LDR

LDR的格式不同,含义也不同。当为 "LDR R1,[R2]" 这种格式时,LDR是一个指令;伪指令的情况有以下情况:

1、赋值任意32位数

当为 "LDR R1,=0x12345678" 这种格式时,LDR是一个伪指令,代表R1=0x12345678。该伪指令可以将任意32位数搬移到寄存器。LDR R1,=0x12345678的转换过程如下:

  • 0x12345678将作为一个不被执行的机器码存放到内存中,这条机器码被存放在全部有效指令之后,在下图中存放在0x58处,因为0x54是最后一条有效指令。
  • LDR的指令将被译码为 "LDR R1,[PC,#偏移值]" 这种格式,在下图中指令被存放在0x30,因为三级流水线的原因,此时PC=0x30+8,因此偏移值 = 0x20。
  • 最终拿到的值是0x58地址当中的数据,就是0x12345678,实现了任意32位数据的赋值。

2、通过标号将地址写入寄存器

当为 "LDR R1,=STOP" 这种格式时,LDR是一个伪指令,代表将STOP标号的地址值存入R1中。

编译后的指令同样是转换成PC加偏移量模式,PC偏移量计算与LDR R1,=0x12345678这种计算方法一样。

3、通过标号将地址当中的值写入寄存器

当为 "LDR R1,STOP" 这种格式时,LDR是一个伪指令,代表将STOP标号的地址当中的值存入R1中。

编译后的指令同样是转换成PC加偏移量模式,PC偏移量计算与LDR R1,=0x12345678这种计算方法一样。

伪操作

伪操作通常以 "." 开头。

1、全局/局部声明

格式:

.global <符号名> 

.local <符号名> 

作用:

将符号声明为全局/局部。

当声明为全局时,所有.s都能访问;当声明为局部时,只有当前.s能访问。

2、宏

格式:

.equ <宏名>,值

作用:

与C语言的#define一样,原值替代。

3、语句封装

格式:

.macro <符号>

@汇编语句

.endm

作用:

类似函数,函数名就是.macro后面跟的符号

4、条件编译

格式:

.if

@汇编语句

.endif

作用:

类似#if #endif,条件满足时才进行编译。

5、重复编译

格式:

.rept <次数>

@汇编语句

.endr

作用:

将区域中的汇编语句重复编译指定次数。

6、弱化符号

格式:

.weak <符号>

作用:

弱化指定的符号,当使用到该符号但未定义该符号时,编译器依旧不报错。

当弱化了符号,并且符号未定义时,编译器会将调用该符号的指令变为NOP,即:一个空操作。

7、申请空间

格式:

.word <初始化值>         @32位,一个字

.byte <初始化值>         @8位,一个字节
.align <以多少字节对齐>  @写3,代表以2^3对齐

.space <申请字节数> <初始化值> @申请指定字节存放数据

.word作用:

在当前指令的地址位置申请空间,并初始化。

.byte作用:

注意:.byte申请空间后,需要再申请冗余空间来进行地址对齐。

.space作用:

注意:.space申请空间后,不一定需要.align来对齐,比如上述是12给字节空间,申请之后地址就是对齐的。

8、标注

格式:

.arm             @告诉编译器这之后是arm指令
@ARM汇编指令

.thumb           @告诉编译器这之后是thumb指令
@Thumb汇编指令    

.text            @告诉编译器这之后是代码段

.end             @告诉编译器汇编代码已结束

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

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

相关文章

WPF MVVM框架

一、MVVM简介 MVC Model View Control MVP MVVM即Model-View-ViewModel&#xff0c;MVVM模式与MVP&#xff08;Model-View-Presenter&#xff09;模式相似&#xff0c;主要目的是分离视图&#xff08;View&#xff09;和模型&#xff08;Model&#xff09;&#xff0c;具有低…

Java-03 深入浅出 MyBatis - 快速入门(无 Spring) 增删改查 核心配置讲解 XML 与 注解映射

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

Spring Cloud Alibaba [Gateway]网关。

1 简介 网关作为流量的入口&#xff0c;常用功能包括路由转发、权限校验、限流控制等。而springcloudgateway 作为SpringCloud 官方推出的第二代网关框架&#xff0c;取代了Zuul网关。 1.1 SpringCloudGateway特点: &#xff08;1&#xff09;基于Spring5&#xff0c;支持响应…

Debezium-EmbeddedEngine

提示&#xff1a;一个嵌入式的Kafka Connect源连接器的工作机制 文章目录 前言一、控制流图二、代码分析 1.构造函数2.完成回调3.连接器回调4.RUN总结 前言 工作机制&#xff1a; * 独立运行&#xff1a;嵌入式连接器在应用程序进程中独立运行&#xff0c;不需要Kafka、Kafka C…

阿里斑马智行 2025届秋招 NLP算法工程师

文章目录 个人情况一面/技术面 1h二面/技术面 1h三面/HR面 20min 个人情况 先说一下个人情况&#xff1a; 学校情况&#xff1a;211本中9硕&#xff0c;本硕学校都一般&#xff0c;本硕都是计算机科班&#xff0c;但研究方向并不是NLP&#xff0c;而是图表示学习论文情况&…

社交电商的优势及其与 AI 智能名片小程序、S2B2C 商城系统的融合发展

摘要&#xff1a;本文深入分析了社交电商相较于传统电商的优势&#xff0c;包括门槛低、易操作、更生活化和可团队化运作等特点。同时&#xff0c;探讨了 AI 智能名片小程序和 S2B2C 商城系统在社交电商发展中的作用&#xff0c;以及它们与社交电商融合所带来的新机遇和发展前景…

自动化运维-检测Linux服务器CPU、内存、负载、IO读写、机房带宽和服务器类型等信息脚本

前言&#xff1a;以上脚本为今年8月1号发布的&#xff0c;当时是没有任何问题&#xff0c;但现在脚本里网络速度测试py文件获取不了了&#xff0c;测速这块功能目前无法实现&#xff0c;后面我会抽时间来研究&#xff0c;大家如果有建议也可以分享下。 脚本内容&#xff1a; #…

3D Streaming 在线互动展示系统:NVIDIA RTX 4090 加速实时渲染行业数字化转型

随着科技的飞速发展&#xff0c;实时渲染正逐步成为游戏与实时交互领域的重要驱动力。与离线渲染不同&#xff0c;实时渲染需要极高的计算性能&#xff0c;对硬件设备尤其是GPU的性能要求极高。随着 RTX 4090 显卡的问世&#xff0c;其强大的算力和创新技术&#xff0c;为实时渲…

南京邮电大学《智能控制技术》课后作业

一、问题一 复现二输入单输出模糊控制系统&#xff0c;改动其中一到两个环节&#xff08;隶属度设置、规则等&#xff09;&#xff0c;对比修改前后控制效果。 定义模糊 %Fuzzy Control for water tank clear all; close all;anewfis(fuzz_tank);%Fuzzy Inference System stru…

2.5D视觉——Aruco码定位检测

目录 1.什么是Aruco标记2.Aruco码解码说明2.1 Original ArUco2.2 预设的二维码字典2.3 大小Aruco二维码叠加 3.函数说明3.1 cv::aruco::detectMarkers3.2 cv::solvePnP 4.代码注解4.1 Landmark图说明4.2 算法源码注解 1.什么是Aruco标记 ArUco标记最初由S.Garrido-Jurado等人在…

栈Stack和队列Queue

目录 一、栈 &#xff08;1&#xff09;用数组实现 &#xff08;2&#xff09;用单链表实现 &#xff08;3&#xff09;用标注尾结点的单链表实现 &#xff08;4&#xff09;用双向链表实现 2、栈的实际应用 &#xff08;1&#xff09;改变元素的序列 &#xff08;2&am…

Tailscale 自建 Derp 中转服务器

文章目录 为什么要建立 Derp 中转服务器&#xff1f;安装 Go 环境通过 Go 安装 Derp处理证书文件自签一个域名启动 DerpIPV6 的支持防止 Derp 被白嫖以上的操作命令合集自建 Headscale 添加 Derp参考 为什么要建立 Derp 中转服务器&#xff1f; Tailscale 使用的算法很有趣: 所…

RPC安全可靠的异常重试

当调用方调用服务提供方&#xff0c;由于网络抖动导致的请求失败&#xff0c;这个请求调用方希望执行成功。 调用方应该如何操作&#xff1f;catch异常再发起一次调用&#xff1f;显然不够优雅。这时可以考虑使用RPC框架的重试机制。 RPC框架的重试机制 RPC重试机制&#xff1…

AutoDL部署视觉大模型llama3.2-vision,从视频中寻找特定目标

注&#xff1a; windows11系统。示例为此项目&#xff1a;https://github.com/win4r/VideoFinder-Llama3.2-vision-Ollama 在当今的人工智能领域&#xff0c;深度学习模型的计算需求日益增长&#xff0c;特别是在处理复杂的视觉任务时&#xff0c;强大的算力往往是实现高效应用…

【大语言模型】ACL2024论文-16 基于地图制图的罗马尼亚自然语言推理语料库的新型课程学习方法

【大语言模型】ACL2024论文-16 基于地图制图的罗马尼亚自然语言推理语料库的新型课程学习方法 目录 文章目录 【大语言模型】ACL2024论文-16 基于地图制图的罗马尼亚自然语言推理语料库的新型课程学习方法目录摘要&#xff1a;研究背景&#xff1a;问题与挑战&#xff1a;如何解…

golang调用模组程序实现交互输入自动化,获取imei及iccid

应用场景&#xff1a;在openwrt下调用移远的测试程序&#xff0c;并实现输入自动话&#xff0c;获取imei rootOpenWrt:~# ql-api-test Test groups:0: ql_dsi1: ql_nw2: ql_sim3: ql_dev4: ql_voice5: ql_sms6: ql_adc7: ql_i2c8: …

【数据分享】2022年我国10米分辨率茶树种植分布栅格数据

小麦、玉米、水稻、茶树等各类农作物的种植分布数据在农业、环境、国土等很多专业都经常用到&#xff01; 本次给大家分享的是我国2022年10米分辨率茶树种植分布栅格数据&#xff01;数据格式为TIFF格式。数据坐标为GCS_WGS_1984。数据格式为TIFF格式。数据坐标为GCS_WGS_1984…

【弱监督视频异常检测】2024-ESWA-基于扩散的弱监督视频异常检测常态预训练

2024-ESWA-Diffusion-based normality pre-training for weakly supervised video anomaly detection 基于扩散的弱监督视频异常检测常态预训练摘要1. 引言2. 相关工作3. 方法论3.1. 使用扩散自动编码器进行常态学习3.2. 全局-局部特征编码器3.2.1 局部块3.2.2 全局块3.2.3 协同…

vue实现展示并下载后端返回的图片流

// 点击下载 downLoadCode() {const image new Image();image.setAttribute("crossOrigin", "anonymous");image.onload () > {const canvas document.createElement("canvas");canvas.width image.width;canvas.height image.height;c…

STL关联式容器之平衡二叉搜索树

平衡二叉搜索树 在STL关联式容器介绍-CSDN博客中对二叉搜索树做了简要的描述&#xff1b;但是因为没有对二叉搜索树对数的深度及插入后树的结构进行调整&#xff0c;二叉搜索树可能失去平衡&#xff0c;造成搜寻效率低落的情况。如下所示&#xff1a; 所谓树形平衡与否&#xf…