当前位置: 首页 > news >正文

程序的机器级表示part3——算术和逻辑操作

目录

1.加载有效地址

2. 整数运算指令

2.1 INC 和 DEC

2.2 NEG 

2.3 ADD、SUB 和 IMUL

3. 布尔指令

3.1 AND

3.2 OR

3.3 XOR

3.4 NOT

4. 移位操作

4.1 算术左移和逻辑左移

4.2 算术右移和逻辑右移

5. 特殊的算术操作 


1.加载有效地址

指令效果描述
leaq    S, DD ← &S加载有效地址

加载有效地址load effective address )指令leaq是movq指令的变形,在64位系统下地址长度为64位,因此lea指令的大小后缀为q,没有其他变种,其目标操作数必须是一个寄存器

leaq指令非常特别,它的一般格式是 leaq (寄存器)  寄存器,看上去像是从内存中读取数据到寄存器,实际上leaq从不发生内存引用,也就是说leaq指令不访问内存,以下面的程序来说明

int main() 
{int x = 10;int *ptr = &x;return 0;
}00000000004004ed <main>:4004ed:	55                   	push   %rbp4004ee:	48 89 e5             	mov    %rsp,%rbp4004f1:	c7 45 f4 0a 00 00 00 	movl   $0xa,-0xc(%rbp)4004f8:	48 8d 45 f4          	lea    -0xc(%rbp),%rax  // 取a的地址放进%rax4004fc:	48 89 45 f8          	mov    %rax,-0x8(%rbp)400500:	b8 00 00 00 00       	mov    $0x0,%eax400505:	5d                   	pop    %rbp400506:	c3                   	retq   400507:	66 0f 1f 84 00 00 00 	nopw   0x0(%rax,%rax,1)40050e:	00 00 

4004f8:    48 8d 45 f4              lea    -0xc(%rbp),%rax

这条指令在mov指令中表示:以%rbp内存放的值作为基地址,加上偏移量0xc作为地址,再取这个地址处的数据,并将数据传送到寄存器%rax内

但在leaq指令则表示:以%rbp内存放的值作为基地址,加上偏移量0xc作为地址,将这个地址传送到寄存器内,也就是 &x 这一行为

%rbp是帧寄存器,保存着main函数栈帧的栈顶位置

假设%rbp的值是10000,地址1000c处保存的值是10

  • movq指令将10传送到寄存器%rax
  • leaq指令将1000c传送到寄存器%rax

leaq指令完成简单的基地址和偏移量的相加,实际上,leaq指令不光能完成地址的相加,也常用于普通的算术操作,比如下面一条指令

leaq 7(%rdx, %rdx, 4), %rax

假设寄存器%rdx的值为x,这条指令的意思是将 %rax的值设置成 x + 4x +7 ,参考linux下的寻址模式的计算,比如下面的代码

long scale(long x, long y, long z) 
{long t = x + 4 * y + 12 * z;return t;
}/*long scale(long x, long y, long z)x in %rdi, y in %rsi, z in %rdx
*/
scale:leaq (%rdi,%rsi,4), %rax     x + 4*yleaq (%rdx,%rdx,2), %rdx     z + 2*z = 3*zleaq (%rax,%rdx,4), %rax     (x+4*y) + 4*(3*z) = x + 4*y + 12*zret

因此,leaq指令也能完成加法和有限的乘法计算,需要注意的一点是,寻址模式中的比例因子只能是1,2,4,8,说明leaq指令完成乘法时,也只能与1,2,4,8相乘,上面代码中,第二行不能使用 leaq(%rax, %rdx, 12) 一步完成计算,而是要分成两步也正是因为这个原因

2. 整数运算指令

指令效果描述
INC    DD ← D + 1加1
DEC    DD ← D - 1减1
NEG    DD ← - D 取负
NOT    DD ← ~ D 取补
ADD    S, DD ← D + S
SUB    S, DD ← D - S
IMUL    S, DD ← D * S

这些整数操作随着操作数大小的不同在使用时要加上操作数大小描述符,因而有四种不同的指令

前四条指令inc,dec,neg 和 not的操作数都只有一个,即是源又是目的,因此称为一元操作,这个操作数可以是一个寄存器,也可以是一个内存位置

后三条指令add,sub,imul 的操作数有两个,其中第二个操作数即作为源使用,又作为目的使用,因此称为二元操作

2.1 INC 和 DEC

INC(Increment)指令从操作数中加1,DEC(Decrement)指令从操作数中减1,二者均不影响CF

指令格式

  • inc reg/mem
  • dec reg/mem 

使用下面的代码查看inc和dec指令的功能

#include <stdio.h>int main() {int x = 10;// printf("The value of x before the increment: %d\n", x);    10__asm__ ( "inc %0\n" : "=r" (x) : "0" (x) );                   // printf("The value of x after the increment: %d\n", x);      11// printf("The value of x before the increment: %d\n", x);     11__asm__ ( "dec %0\n" : "=r" (x) : "0" (x) );// printf("The value of x after the increment: %d\n", x);      10return 0;
}
00000000004004ed <main>:4004ed:	55                   	push   %rbp4004ee:	48 89 e5             	mov    %rsp,%rbp4004f1:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%rbp)4004f8:	8b 45 fc             	mov    -0x4(%rbp),%eax4004fb:	ff c0                	inc    %eax             // 把%eax中的值加14004fd:	89 45 fc             	mov    %eax,-0x4(%rbp)400500:	8b 45 fc             	mov    -0x4(%rbp),%eax400503:	ff c8                	dec    %eax             // 把%eax中的值减1400505:	89 45 fc             	mov    %eax,-0x4(%rbp)400508:	b8 00 00 00 00       	mov    $0x0,%eax40050d:	5d                   	pop    %rbp40050e:	c3                   	retq   40050f:	90                   	nop

2.2 NEG 

NEG(negative):将数字转换为对应的二进制补码, 从而求得其相反数,影响的标志位有

进位标志CF、零标志ZF、符号标志SF、溢出标志OF、辅助进位标志AF和奇偶标志PF(结果低8位中,数值1 的个数是否为偶数)。

指令格式

  • neg reg
  • neg mem 

使用下面的代码查看neg指令的功能

int main() 
{int i = 10;i = -i;i = ~i;return 0;
}
00000000004004ed <main>:4004ed:	55                   	push   %rbp4004ee:	48 89 e5             	mov    %rsp,%rbp4004f1:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%rbp)4004f8:	f7 5d fc             	negl   -0x4(%rbp)      // i = -i;4004fb:	b8 00 00 00 00       	mov    $0x0,%eax400500:	5d                   	pop    %rbp400501:	c3                   	retq   400502:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)400509:	00 00 00 40050c:	0f 1f 40 00          	nopl   0x0(%rax)

2.3 ADD、SUB 和 IMUL

ADD(addition):指令将同尺寸的源操作数和目的操作数相加

SUB(subtraction):指令将同尺寸的源操作数和目的操作数相减

IMUL(multiplication):指令将同尺寸的源操作数和目的操作数相乘 

指令格式

  • add 源操作数, 目的操作数
  • sub 源操作数, 目的操作数
  • imul 源操作数, 目的操作数

指令的源操作数可以是:立即数,寄存器,内存位置

指令的目的操作数可以是:寄存器,内存位置

使用下面的代码查看add,sub,和 imul 指令的功能

int main() 
{int a = 10;int b = a + 10;int c = b - 15;a = a * b;
}00000000004004ed <main>:4004ed:	55                   	push   %rbp4004ee:	48 89 e5             	mov    %rsp,%rbp4004f1:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%rbp)    // int a = 10;4004f8:	8b 45 fc             	mov    -0x4(%rbp),%eax4004fb:	83 c0 0a             	add    $0xa,%eax          // int b = a + 10;4004fe:	89 45 f8             	mov    %eax,-0x8(%rbp)400501:	8b 45 f8             	mov    -0x8(%rbp),%eax400504:	83 e8 0f             	sub    $0xf,%eax          // int c = b - 15;400507:	89 45 f4             	mov    %eax,-0xc(%rbp)40050a:	8b 45 fc             	mov    -0x4(%rbp),%eax40050d:	0f af 45 f8          	imul   -0x8(%rbp),%eax    // a = a * b;400511:	89 45 fc             	mov    %eax,-0x4(%rbp)400514:	5d                   	pop    %rbp400515:	c3                   	retq   400516:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)40051d:	00 00 00 

3. 布尔指令

C语言里存在位操作符

分别对应下面的指令 

指令效果描述
AND    S, DD ← D & S 
OR    S, DD ← D | 1
XOR    S, DD ← D ^ S异或
NOT    DD ← ~ D 取补

3.1 AND

 AND 指令在每对操作数的对应数据位之间执行布尔位“与”操作,并将结果存放在目的操作数中

指令格式

  • AND reg/mem/imm, reg/mem

AND指令总是使得CF=0、OF=0,并依据目的操作数的值修改SF、ZF和PF的值 

参考如下代码 

int main() 
{int x = 10;      // 00000000 00000000 00000000 00001010int y = x & 8;   // 00000000 00000000 00000000 00001000return 0;
}00000000004004ed <main>:4004ed:	55                   	push   %rbp4004ee:	48 89 e5             	mov    %rsp,%rbp4004f1:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%rbp)    // int x = 10;4004f8:	8b 45 fc             	mov    -0x4(%rbp),%eax4004fb:	83 e0 08             	and    $0x8,%eax          // int y = x & 8;4004fe:	89 45 f8             	mov    %eax,-0x8(%rbp)400501:	b8 00 00 00 00       	mov    $0x0,%eax400506:	5d                   	pop    %rbp400507:	c3                   	retq   400508:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)40050f:	00 

3.2 OR

OR 指令在每对操作数的对应数据位之间执行布尔位“或” 操作,并将结果存放在目的操作数中

指令格式

  • OR reg/mem/imm,  reg/mem

OR指令总是使得CF=0、OF=0,依据目的操作数的值修改SF、ZF和PF的值 

参考如下代码 

int main() 
{int x = 10;      // 00000000 00000000 00000000 00001010int y = x | 8;   // 00000000 00000000 00000000 00001000return 0;
}00000000004004ed <main>:4004ed:	55                   	push   %rbp4004ee:	48 89 e5             	mov    %rsp,%rbp4004f1:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%rbp)    // int x = 10;4004f8:	8b 45 fc             	mov    -0x4(%rbp),%eax4004fb:	83 c8 08             	or     $0x8,%eax          // int y = x | 84004fe:	89 45 f8             	mov    %eax,-0x8(%rbp)400501:	b8 00 00 00 00       	mov    $0x0,%eax400506:	5d                   	pop    %rbp400507:	c3                   	retq   400508:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)40050f:	00 

3.3 XOR

XOR 指令在每对操作数的对应数据位之间执行布尔位“异或” 操作,并将结果存放在目的操作数中 

指令格式

  • XOR reg/mem/imm,  reg/mem

OR指令总是使得CF=0、OF=0,依据目的操作数的值修改SF、ZF和PF的值 

参考如下代码 

int main() 
{int x = 10;      // 00000000 00000000 00000000 00001010int y = x ^ 8;   // 00000000 00000000 00000000 00001000return 0;
}00000000004004ed <main>:4004ed:	55                   	push   %rbp4004ee:	48 89 e5             	mov    %rsp,%rbp4004f1:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%rbp)    // int x = 10;4004f8:	8b 45 fc             	mov    -0x4(%rbp),%eax4004fb:	83 f0 08             	xor    $0x8,%eax          // int y = x ^ 8;4004fe:	89 45 f8             	mov    %eax,-0x8(%rbp)400501:	b8 00 00 00 00       	mov    $0x0,%eax400506:	5d                   	pop    %rbp400507:	c3                   	retq   400508:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)40050f:	00 

3.4 NOT

NOT 指令将一个操作数的所有数据位取反 

指令格式

  • NOT reg/mem

NOT 指令不修改任何状态标志 

参考如下代码 

int main() 
{int x = 10;      // 00000000 00000000 00000000 00001010int y = ~x;      // 11111111 11111111 11111111 11110101return 0;
}00000000004004ed <main>:4004ed:	55                   	push   %rbp4004ee:	48 89 e5             	mov    %rsp,%rbp4004f1:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%rbp)    // int x = 10;4004f8:	8b 45 fc             	mov    -0x4(%rbp),%eax4004fb:	f7 d0                	not    %eax               // ~x;4004fd:	89 45 f8             	mov    %eax,-0x8(%rbp)    // int y = ~x;400500:	b8 00 00 00 00       	mov    $0x0,%eax400505:	5d                   	pop    %rbp400506:	c3                   	retq   400507:	66 0f 1f 84 00 00 00 	nopw   0x0(%rax,%rax,1)40050e:	00 00 

4. 移位操作

C语言中移位操作符分为左移操作符(<<)和右移操作符(>>),而移位操作又分左移和右移

指令效果描述
SAL    k, DD ← D << k算术左移
SHL    k, DD ← D << k

逻辑左移

(等同SAL)

SAR    k, DD ← D >> k算数右移
SHL    k, DD ← D >> k逻辑右移

移位操作

  1. 第一个操作数是移位量k,也就是二进制位移动的位数
  2. 第二个操作数是要移位的数

注意:移位量可以是一个立即数,或者放在单字节寄存器%cl中(规定了只能放在这里) 

%cl长8位,可表示0~255,因此移位量的最大可以达到255位,但是显然没有这么长的数据类型,因此实际上移位操作是根据要移动的数的位数来决定取%cl的哪些值的,

x86-64中,移位操作对w位长的数据值进行操作,移位量是由%cl寄存器的低m位决定的,这里2的m次方等于w,高位会被忽略 

比如此时%cl内是0xFF

%cl1111 1111

对于不同的数据类型

  • char类型的数据,长8位,取%cl中的低三位 111,因此会移动7位
  • short类型的数据,长16位,取%cl中低四位 1111,因此会移动15位
  • int类型的数据,长32位,取%cl中低五位 11111,因此会移动31位

4.1 算术左移和逻辑左移

SAL(Arithmetic Left Shift):对目的操作数执行逻辑左移操作,低位填0 ,移出的最高位送CF

SHL(Logic Left Shift):与SAL指令等价

指令格式

  • sal imm8/CL, reg/mem
  • shl imm8/CL, reg/mem

参考如下代码 

int main() 
{int x = 10;      // 00000000 00000000 00000000 00001010int y = x << 2;  // 00000000 00000000 00000000 00101000return 0;
}00000000004004ed <main>:4004ed:	55                   	push   %rbp4004ee:	48 89 e5             	mov    %rsp,%rbp4004f1:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%rbp)     // int x = 10;4004f8:	8b 45 fc             	mov    -0x4(%rbp),%eax4004fb:	c1 e0 02             	shl    $0x2,%eax           // x << 24004fe:	89 45 f8             	mov    %eax,-0x8(%rbp)     // int y = x << 2;400501:	b8 00 00 00 00       	mov    $0x0,%eax400506:	5d                   	pop    %rbp400507:	c3                   	retq   400508:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)40050f:	00 

4.2 算术右移和逻辑右移

SHR(Logic Shift Right ):对目的操作数执行逻辑右移操作,移出的数据位以0 填充,最低位被送到CF中 

指令格式 

  • shr imm8/CL, reg/mem

SAL(Arithmetic Right Shift):用最高位填充空出的位,最低位拷贝至CF

指令格式 

  • sar imm8/CL, reg/mem

参考如下代码(这里算术右移最特殊,只演示算术右移)

int main()
{int x1 = 10;       // 00000000 00000000 00000000 00001010int y1 = x1 >> 2;  // 00000000 00000000 00000000 00000010int x2 = -10;      // 11111111 11111111 11111111 11110110int y2 = x2 >> 2;  // 11111111 11111111 11111111 11111101return 0;
}00000000004004ed <main>:4004ed:	55                   	push   %rbp4004ee:	48 89 e5             	mov    %rsp,%rbp4004f1:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%rbp)4004f8:	8b 45 fc             	mov    -0x4(%rbp),%eax4004fb:	c1 f8 02             	sar    $0x2,%eax          // 算术右移,以0填充4004fe:	89 45 f8             	mov    %eax,-0x8(%rbp)400501:	c7 45 f4 f6 ff ff ff 	movl   $0xfffffff6,-0xc(%rbp)400508:	8b 45 f4             	mov    -0xc(%rbp),%eax40050b:	c1 f8 02             	sar    $0x2,%eax          // 算术右移,以1填充40050e:	89 45 f0             	mov    %eax,-0x10(%rbp)400511:	b8 00 00 00 00       	mov    $0x0,%eax400516:	5d                   	pop    %rbp400517:	c3                   	retq   400518:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)40051f:	00 

由于算术右移会对有符号数和无符号数进行区分,因此使用算术右移对补码进行操作可以代替一部分的整数运算,对于下面的arith函数

long arith(long x, long y, long z)
{long t1 = x ^ y;long t2 = z * 48;long t3 = t1 & 0x0F0F0F0F;long t4 = t2 - t3;return t4;
}

对应的汇编为 

/*
long arith(long x, long y, long z)
x in %rdi, y in %rsi, z in %rdx
*/arith:xorq %rsi, %rdi             t1 = x ^ yleaq (%rdx,%rdx,2), %rax    3*zsalq $4, %rax               t2 = 16 * (3*z) = 48*zandl $252645135, %edi       t3 = t1 & 0x0F0F0F0Fsubq %rdi, %rax             Return t2 - t3ret

这里用salq $4, %rax 代替乘法,可以加快运算

5. 特殊的算术操作 

两个64位有符号数或者无符号数相乘得到的乘积需要128位来表示。x86-64指令集对128位数的操作提供了一定程度上的支持,Intel将16字节的数称为8字(oct word)

下表是支持产生两个64位数字的全128位乘积以及整数除法的指令

指令效果描述
imuq    SR[ %rdx ]:R[ %rax ] ← S × R[ %rax ] 有符号乘法
mulq    SR[ %rdx ]:R[ %rax ] ← S × R[ %rax ] 

无符号乘法

cqtoR[ %rdx ]:R[ %rax ] ← SignExtend(R[ %rax ])转化为八字
idivq    S

R[ %rdx ] ← R[ %rdx ]:R[ %rax ]mod S

R[ %rax ] ← R[ %rdx ]:R[ %rax ]÷ S

有符号除法
divq    S

R[ %rdx ] ← R[ %rdx ]:R[ %rax ]mod S

R[ %rax ] ← R[ %rdx ]:R[ %rax ]÷ S

无符号除法

两个寄存器%rdx(64位)和%rax(64位)组成一个128位的八字,根据乘积中高部分是否为0设置或清楚CF、OF

对于无符号乘法(mulq)和有符号乘法(imulq)而言,二者都是单操作数乘法指令,都需要将一个参数存放在寄存器%rax中,而另一个则作为指令的源操作数给出,乘积放在寄存器%rdx和%rax中

%rdx(64位)%rax(64位)

下面是一个示例,其中细节见CASPP原书3.5.5小节

#include <inttypes.h>typedef unsigned __int128 uint128_t;void store_uprod(uint128_t *dest, uint64_t x, uint64_t y)
{*dest = x * (uint128_t)y;
}
/*
void store_uprod(uint128_t *dest, uint64_t x, uint64_t y)
dest in %rdi, x in %rsi, y in %rdx
*/store_uprod:movq %rsi, %rax Copy x to multiplicandmulq %rdx Multiply by ymovq %rax, (%rdi) Store lower 8 bytes at destmovq %rdx, 8(%rdi) Store upper 8 bytes at dest+8ret

相关文章:

程序的机器级表示part3——算术和逻辑操作

目录 1.加载有效地址 2. 整数运算指令 2.1 INC 和 DEC 2.2 NEG 2.3 ADD、SUB 和 IMUL 3. 布尔指令 3.1 AND 3.2 OR 3.3 XOR 3.4 NOT 4. 移位操作 4.1 算术左移和逻辑左移 4.2 算术右移和逻辑右移 5. 特殊的算术操作 1.加载有效地址 指令效果描述leaq S, DD…...

基于YOLOV5的钢材缺陷检测

数据和源码见文末 1.任务概述 数据集使用的是东北大学收集的一个钢材缺陷检测数据集,需要检测出钢材表面的6种划痕。同时,数据集格式是VOC格式,需要进行转化,上传的源码中的数据集是经过转换格式的版本。 2.数据与标签配置方法 在数据集目录下,train文件夹下有训练集数据…...

Session与Cookie的区别(三)

中场休息 让我们先从比喻回到网络世界里&#xff0c;HTTP 是无状态的&#xff0c;所以每一个 Request 都是不相关的&#xff0c;就像是对小明来说每一位客人都是新的客人一样&#xff0c;他根本不知道谁是谁。 既然你没办法把他们关联&#xff0c;就代表状态这件事情也不存在。…...

七大设计原则之接口隔离原则应用

目录1 接口隔离原则介绍2 接口隔离原则应用1 接口隔离原则介绍 接口隔离原则&#xff08;Interface Segregation Principle, ISP&#xff09;是指用多个专门的接口&#xff0c;而不使用单一的总接口&#xff0c;客户端不应该依赖它不需要的接口。这个原则指导我们在设计接口时…...

【Shell1】shell语法,ssh/build/scp/upgrade,环境变量,自动升级bmc

文章目录1.shell语法&#xff1a;shell是用C语言编写的程序&#xff0c;是用户使用Linux的桥梁&#xff0c;硬件>内核(os)>shell>文件系统1.1 变量&#xff1a;readonly定义只读变量&#xff0c;unset删除变量1.2 函数&#xff1a;shell脚本传递的参数中包含空格&…...

JavaScript HTML DOM - 改变CSS

JavaScript 是一种动态语言&#xff0c;它可以动态地修改网页的外观&#xff0c;并且使用HTML DOM&#xff08;文档对象模型&#xff09;可以更方便地控制HTML元素的样式。 JavaScript 通过在HTML DOM中更改CSS属性来更改样式&#xff0c;这些CSS属性包括颜色、位置、字体大小…...

mycat连接mysql 简单配置

mycat三个配置文件位于conf下 可通过Notepad操作 首先配置service.xml中的user标签&#xff0c;设置用户名&#xff0c;密码&#xff0c;查询权限&#xff0c;是否只读等 只是设置了root用户&#xff0c;有所有权限 配置schema.xml <?xml version"1.0"?&g…...

Spring常用注解

文章目录一、Bean交给Spring管理1、Component2、Bean3、Controller4、Service5、Repository6、Configuration7、ComponentScan二、作用域1、Lazy(false)Scope三、依赖注入1、Autowired2、Resource3、Qualifier四、读取配置文件值1、Value一、Bean交给Spring管理 1、Component …...

I.MX6ULL内核开发9:kobject-驱动的基石

目录 一、摘要 二、重点 三、驱动结构模型 四、关键函数分析 kobject_create_and_add()函数 kobject_create()函数 kobject_init&#xff08;&#xff09;函数 kobject_init_internal(&#xff09;函数 kobject_add&#xff08;&#xff09;函数 kobject_add_varg&am…...

Docker-harbor私有仓库

一、Harbor概述 1、Harbor的概念 • Harbor是VMware公司开源的企业级Docker Registry项目&#xff0c;其目标是帮助用户迅速搭建一个企业级的Docker Registry服务 • Harbor以 Docker 公司开源的Registry 为基础&#xff0c;提供了图形管理UI、基于角色的访问控制(Role Base…...

Java之动态规划之子序列问题

目录 0.动态规划问题 一.最长递增子序列 1.题目描述 2.问题分析 3.代码实现 二.最长递增子序列 1.题目描述 2.问题分析 3.代码实现 三.最长重复子数组 1.题目描述 2.问题分析 3.代码实现 4.代码的优化(滚动数组) 四.最长公共子序列 1.题目描述 2.问题分析 3.代…...

java ArrayList

目录 一.简单介绍 二.ArrayList的底层结构 2.1ArrayList的底层结构和操作分析 2.ArrayList 底层源码分析 三.ArrayList 方法 四.代码使用方法 一.简单介绍 ArrayList 类是一个可以动态修改的数组&#xff0c;与普通数组的区别就是它是没有固定大小的限制&#xff0c;我们…...

前端——周总结系列四

1 JS变量与常量 概述 变量&#xff1a;在后续编码过程中会被重新赋值&#xff0c;是不断变化的。常量&#xff1a;固定不变的数据&#xff0c;日常生活比如性别男&#xff0c;代码层面是在编码过程中不会变化的固定数据。 命名规则 变量 可以包含数字&#xff0c;字母&…...

Linux重定向符、管道符讲解

目录 重定向 将命令与文件进行互动 输出重定向 输入重定向 管道符 将命令与命令互动起来 重定向 将命令与文件进行互动 重定向分类 一般情况下&#xff0c;Linux命令运行时都会打开一下三个文件 标准输入文件&#xff1a;stdin文件&#xff0c;文件描述符为0&#xff0c;Li…...

【C++】多态

多态一、多态的概念及定义1.1 虚函数1.2 虚函数重写的特殊情况1.3 override 和 final二、抽象类2.1 概念2.2 用处三、多态的原理3.1 虚函数表3.1.1 虚函数与虚表的位置3.2 多态的原理3.3 静态绑定和动态绑定四、单/多继承的虚函数表4.1 单继承的虚函数表4.2 多继承的虚函数表一…...

分布式项目-品牌管理(5、6)

【今日成果】&#xff1a; //使用阿里云OSS服务&#xff1a; //使用v-if如果地址没有就不显示 &#xff0c; 如果地址错误图片就显示不出来&#xff1b; 【快速回顾】&#xff1a; 任何数据的删除都不要使用物理上的删除&#xff0c;应当使用逻辑上的删除&#xff01;&…...

自定义ESLint规则开发与使用

自定义eslint及使用 项目结构 |-eslint-plugin-demo //自定义eslint插件项目 | |-demo-app // 使用自定义eslint的测试应用 |-README.md 项目效果&#xff1a; github项目地址 自定义ESLint环境准备 安装脚手架 执行下列命令来安装开发eslint的脚手架。 yo(y…...

【JavaScript】35_包装类与垃圾回收机制

10、包装类 在JS中&#xff0c;除了直接创建原始值外&#xff0c;也可以创建原始值的对象 通过 new String() 可以创建String类型的对象 通过 new Number() 可以创建Number类型的对象 通过 new Boolean() 可以创建Boolean类型的对象 但是千万不要这么做 包装类&#xff1…...

【CS224W】(task3)NetworkX工具包实践

note 节点可以为任意可哈希的对象&#xff0c;比如字符串、图像、XML对象&#xff0c;甚至另一个Graph、自定义的节点对象。通过这种方式可以自由灵活地构建&#xff1a;图为节点、文件为节点、函数为节点&#xff0c;等灵活的图形式。暂时省略&#xff1a;【B5】计算机网络图…...

ansible的模块详解

ansible 的概述 什么是ansible Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。 它用Python写成&#xff0c;类似于saltstack和Puppet&#xff0c;但是有一个不同和优点是我们不需要在节点中安装任何客户端。 它使用SSH来和节点进行通信。Ansible基于 Python…...

《Terraform 101 从入门到实践》 Functions函数

《Terraform 101 从入门到实践》这本小册在南瓜慢说官方网站和GitHub两个地方同步更新&#xff0c;书中的示例代码也是放在GitHub上&#xff0c;方便大家参考查看。 Terraform的函数 Terraform为了让大家在表达式上可以更加灵活方便地进行计算&#xff0c;提供了大量的内置函数…...

使用kubeadm快速部署一个K8s集群

wkubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。 这个工具能通过两条指令完成一个kubernetes集群的部署&#xff1a; # 创建一个 Master 节点 $ kubeadm init# 将一个 Node 节点加入到当前集群中 $ kubeadm join <Master节点的IP和端口 >1. 安装要求 …...

初探富文本之CRDT协同算法

初探富文本之CRDT协同算法 CRDT的英文全称是Conflict-free Replicated Data Type&#xff0c;最初是由协同文本编辑和移动计算而发展的&#xff0c;现在还被用作在线聊天系统、音频分发平台等等。当前CRDT算法在富文本编辑器领域的协同依旧是典型的场景&#xff0c;常用于作为…...

Dubbo和Zookeeper集成分布式系统快速入门

文件结构 代码部分 1、新建provider-server导入pom依赖 <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.3</version></dependency><dependency>&l…...

大数据工具Maxwell的使用

1.Maxwell简介 Maxwell 是由美国Zendesk公司开源&#xff0c;用Java编写的MySQL变更数据抓取软件。它会实时监控Mysql数据库的数据变更操作&#xff08;包括insert、update、delete&#xff09;&#xff0c;并将变更数据以 JSON 格式发送给 Kafka、Kinesi等流数据处理平台。 官…...

freesurfer如何将组模板投影到个体空间——如投影 Schaefer2018 到个体空间

freesurfer如何将组模板投影到个体空间——如投影 Schaefer2018 到个体空间 freesurfer如何将组模板投影到个体空间? freesurfer如何将组模板投影到个体空间——如投影 Schaefer2018 到个体空间freesurfer的整理流程freesurfer的安装freesurfer对结构像分割流程及批处理代码fr…...

Matlab傅里叶谱方法求解二维波动方程

傅里叶谱方法求解基本偏微分方程—二维波动方程 二维波动方程 将一维波动方程中的一维无界弦自由振动方程推广到二维空间上, 就得到了描述无界 (−∞<x,y<∞)(-\infty<x, y<\infty)(−∞<x,y<∞) 弹性薄膜的波动方程: ∂2u∂t2a2(∂2∂x2∂2∂y2)u(1)\frac…...

【深度学习】卷积神经网络

1 卷积神经网络&#xff08;CNN&#xff09;可以做什么&#xff1f; 检测任务分类与检索超分辨率重构&#xff1a;将图像训练的更清晰医学任务等无人驾驶人脸识别 2 用GPU&#xff1a;图像处理单元 比CPU块一百倍以上 3 卷积神经网络与传统神经网络的区别 传统神经网络&…...

【C++】六个默认成员函数——取地址重载,const成员函数

&#x1f345; 初始化和清理 拷贝复制 目录 ☃️1.取地址重载 ☃️2.const取地址操作符重载 这两个运算符一般不需要重载&#xff0c;使用编译器生成的默认取地址的重载即可&#xff0c;只有特殊情况&#xff0c;才需要重载&#xff0c;比如想让别人获取到指定的内容&#xf…...

Win11浏览器无法上网,秒杀网上99.9%教程—亲测完胜

前言 例如&#xff1a;网上的教程 列如&#xff1a; 关闭代理服务器、QQ微信可以登录&#xff0c;但浏览器无法上网、Win11、Win10无法上网、重启网络、重启电脑、去掉代理服务器等等。 一系列教程&#xff0c;要多鸡肋就多鸡肋。 我是用我2020年在CSDN上发布的第一篇文章&…...