《深入理解计算机系统(CSAPP)》第3章 程序的机器级表示 - 学习笔记

news2024/11/24 20:24:52

写在前面的话:此系列文章为笔者学习CSAPP时的个人笔记,分享出来与大家学习交流,目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记,在复习回看时发现部分内容存在一些小问题,因时间紧张来不及再次整理总结,希望读者理解。


《深入理解计算机系统(CSAPP)》第3章 程序的机器级表示 - 学习笔记_友人帐_的博客-CSDN博客

《深入理解计算机系统(CSAPP)》第5章 优化程序性能 - 学习笔记_友人帐_的博客-CSDN博客

《深入理解计算机系统(CSAPP)》第6章 存储器层次结构 - 学习笔记_友人帐_的博客-CSDN博客

《深入理解计算机系统(CSAPP)》第7章 链接- 学习笔记_友人帐_的博客-CSDN博客

《深入理解计算机系统(CSAPP)》第8章 异常控制流 - 学习笔记_友人帐_的博客-CSDN博客

《深入理解计算机系统(CSAPP)》第9章虚拟内存 - 学习笔记_友人帐_的博客-CSDN博客


第三章 程序的机器级表示

1. 代码编译过程

gcc -Og -o hello source1.c source2.c ...

gcc -Og -S -fno-if-conversion source.c  // 优化等级低,便于理解

注:①-Og为代码优化等级;②-o表示生成可执行文件,-s可以生成汇编代码;③生成实际可执行的代码需要对一组目标代码文件运行链接器,而这一组目标代码文件中必须含有一个main函数;④有时会在末尾(return后)有90 nop指令,目的是为了使函数代码变为16字节,使得存储器能更好地放置下一个代码块,提高性能。

源代码转化为可执行代码:

①C预处理器:扩展源代码,插入所有用#include命令指定的文件,并扩展所有#define声明指定的宏;

②编译器:生成源文件的汇编代码,后缀.s;

③汇编器:将汇编代码转化为二进制目标代码文件,后缀.o;

④链接器:将目标代码文件与实现库函数的代码合并,填入全局值的地址,生成可执行代码文件。

GDB调试指令
在这里插入图片描述

2. 反汇编

反汇编:将可执行二进制文件翻译为汇编语言

objdump -d target.o
objdump -S target.o > target.txt    (在反汇编中加入C代码,且重定向输出到target.txt)
cat target.txt   查看

3. 汇编相关(AT&T格式)

3.1 伪指令

所有以.开头的指令都是指导汇编器和链接器工作的伪指令;

3.2 汇编代码后缀

在这里插入图片描述

3.3 寄存器

(1)通用寄存器:
在这里插入图片描述

规则:生成1字节和2字节数字的指令会保持剩下的字节不变;生成4字节数字的指令会把高位4个字节置为0。

(2)段寄存器

在这里插入图片描述

(3)指令指针寄存器EIP/PC

在这里插入图片描述

(4)EFLAGS寄存器

在这里插入图片描述

在这里插入图片描述

(5)系统寄存器

在这里插入图片描述

(6)浮点单元FPU

在这里插入图片描述

3.4 操作数指示符

操作数类型:

①立即数:用$符号表示,代表常数值;

②寄存器:直接访问寄存器的值;

③内存寻址: I m m ( R b , R i , S ) = I m m + R b + R i ∗ S Imm(R_b,R_i,S)=Imm+R_b+R_i*S Imm(Rb,Ri,S)=Imm+Rb+RiS,其中, I m m Imm Imm表示立即数偏移, R b R_b Rb表示基址寄存器, R i R_i Ri表示变址寄存器, S S S为比例因子,仅能取值1,2,4,8。计算得到的为一个地址,相当于解引用操作。

3.5 mov指令

在这里插入图片描述

注意:

①两个操作数不能同时指向内存位置。

②寄存器部分的大小必须与指令最后一个字符(‘b’,‘w’,‘l’,‘q’)指定的大小匹配。大多数情况,MOV指令只会更新目的操作数指定的寄存器字节或内存位置,但当movl指令以寄存器作为目的时,会把该寄存器的高4位设置为0(任何为寄存器生成32位值的指令都会把该寄存器的高位部分置为0)。

③不要给%rsp赋值(系统保留)。

在这里插入图片描述

扩展 - 零扩展(movz)、符号扩展(movs)+大小指示符(源,目的)
在这里插入图片描述

条件传送

cmovcc src, dst

cc表示条件,使用EFLAGS中的条件码实现条件判断

对于无符号数,使用a,b,e,b,c分别表示大于、小于、等于、否定、进位

对于有符号数,使用g,l,e,n,o分别表示大于、小于、等于、否定、溢出

3.6 栈操作

栈向下增长,栈顶为低地址。

指令:

在这里插入图片描述

示意:
在这里插入图片描述

3.7 算术和逻辑操作

在这里插入图片描述

注意:

leaq并不是取源S的地址放入寄存器D,而是将有效地址放入,例如若%rdx值为x,则指令leap 7(%rdx, %rdx, x) %rax将寄存器%rax的值设置为5x+7

特殊的算数操作:八字

在这里插入图片描述

3.8 调试常用指令

  1. 编译:./mak64 try64
  2. 调试:gdb ./try64
  3. 设置断点:b _start
  4. 打开源代码窗口:layout src

layout split - 上方源代码,下方汇编

  1. 打开寄存器观察窗口:tui r g r表示register,g表示general,通用寄存器

  2. 运行:r

  3. 在断点处停止后,单步运行:n

4. IA32的内存管理

4.1 实地址模式

在这里插入图片描述

实地址模式:存储内容为真实物理地址。

内存分段:16位地址线不能直接表示20位地址,采用内存分段方式,使用两个16位地址来表示。表示为段地址:段内偏移量;约定段地址低4为为0,便可以用16位地址表示段地址,如此将内存空间划分为64KB的段。而实际地址可以采用实际地址 = 段地址0 + 段内偏移量计算得到(段地址后补 0 16 0_{16} 016)。

在这里插入图片描述

4.2 保护模式

将段描述符(8字节,段的相关信息)在段描述符表中的索引值存放在段寄存器(2字节)中。而在段描述符表中的每一行(每一个段描述符),都保存了段的相关参数、访问权限等信息。

在这里插入图片描述

在这里插入图片描述

GDT(全局描述符表)和LDT(局部描述符表)都用来存放各种描述符,例如段描述符,但这掩盖不了它们也是内存段的事实。简单地讲,他们也是段。但是,因为它们用于系统管理,故称为系统的段或者系统段。GDT是唯一的,整个系统中只有一个,所以只需要用GDTR寄存器(CPU中)存放其线性基地址和段界限即可。其中存储了操作系统使用的代码段、数据段、堆栈段的描述符以及各个程序的LDT段;但LDT不同,每个程序有一个独立的LDT,存放了对应程序的代码段、数据段、堆栈段的描述符等信息。当要使用这些LDT时,可以用它们的选择子来访问GDT,将LDT描述符加载到LDTR寄存器。

全局描述符表寄存器GDTR(48位)指向GDT在内存中的地址。局部描述符表寄存器LDTR(16位)指向LDT段在GDT中的索引。

在段选择器(保护模式下的段寄存器)中:

在这里插入图片描述

(1)平坦分段模式

而在段描述符表中:(16进制)所有段被映射到32位物理地址空间,程序至少分为代码段和数据段两个段。

全局描述符表GDT:

基址(32位)指向段的起始地址(图示中指向0000 0000,很低的地址空间为操作系统所用);

界限指该段的长度,其中,0040是相对值,要在后方加上000(乘以4k),即0040 000,也说明了段的大小都是4k的倍数。
在这里插入图片描述

(2)多段模式

局部描述符表LDT:

在这里插入图片描述

保护模式下的段寻址总结:

(3)内存分页

在这里插入图片描述

5. 控制(条件、循环、分支)

5.1 条件码

CF:进位标志。最高有效位有进位(无符号溢出)置为1,否则置0。

ZF:零标志。最近的操作得出的结果为0。

SF:符号标志。最近的操作得到的结果为负数。

OF:溢出标志。最近的操作导致一个补码溢出(正溢出或负溢出)

除了leaq指令,其余算术和逻辑操作都伴随着进位标志的设置。

还有一些指令只用于设置条件吗而不改变任何其他寄存器。

在这里插入图片描述

SET指令:可以通过条件码的组合来进行各种条件操作(指令的后缀表示不同的条件而不是操作数大小)。目的操作数是低位单字节寄存器元素之一,或是一个字节的内存位置,指令会将这个字节设置为0或1。

在这里插入图片描述

cmp指令

cmpq src1, src2计算src2-src1的值和0比较,仅用结果设置条件码,而不改变目的操作数。

test指令

testq src2, src1根据src2 & src1 的数值来设置条件码,结果并不保存,通常将其中一个操作数看作是一个掩码。

5.2 跳转指令jump

jump指令会导致执行切换到程序中一个全新的位置。在汇编中,这些跳转的目的地通常用一个标号(label)指明。

在这里插入图片描述

直接跳转:jmp .L1 直接跳转到L1标号位置

间接跳转:jmp *%rax 以%rax中的值作为读地址,从内存中读出跳转目标

在这里插入图片描述

注:跳转条件为1表示无条件跳转。

跳转指令的编码

PC相对跳转

绝对地址跳转

5.3 用条件控制来实现条件分支

将if转化为goto类型,直接对应于汇编。

在这里插入图片描述

if-else的通用转换模板

// if-else版本
if (test-expr)
	then-statement
else
	else-statement
	
// goto版本
	t = test-expr;
	if (!t)
		goto false;
	then-statement
	goto done;
false:
	else-statement
done:

使用数据的条件转移来实现条件分支的好处:

在这里插入图片描述

(将未知的跳转转换为已知的计算,消除不确定性)

可以使得CPU的流水线中充满了待执行的指令,避免条件预测逻辑(猜测每条跳转指令是否会执行)预测错误而导致浪费CPU的时钟周期,以提高流水线性能。

条件传送指令:

在这里插入图片描述

5.4 循环

用条件测试和跳转组合起来实现循环(do-while、while、for)

// do-while通用形式
do
	body-statement
	while (test-expr);
	
// goto形式
loop:
	body-statement
	t = test-expr;
	if (t)
		goto loop;

/* ----------------- */
// while 通用形式
while (test-expr)
    body-statement
   
// while goto形式1 - 跳转到中间
    goto test;
loop:
	body-statement
test:
	t = test-expr;
	if (t)
        goto loop;

// while goto形式2 - guarded-do
// 先翻译为do-while,再翻译为goto
t = test-expr;
if (!t)
    goto done;
loop:
	body-statement
    t = test-expr;
	if (t)
        goto loop;
done:

/* ----------------- */
// for 通用形式
for (init-expr; test-expr; update-expr)
    body-statement
   
// for转化为while
init-expr;
while (test-expr) {
    body-statement
    update-expr;
}

5.5 switch语句

连续性较好的switch语句用跳转表,不好的用决策树(一堆if else)

switch使用跳转表(一个数组),表项 i i i是一个代码段的地址,这个代码段实现当switch索引值等于 i i i时程序所执行的指令。当switch情况比较多时(>4),并且值的范围跨度比较小时,就会使用跳转表。跳转表的优点是执行语句的时间与情况数量无关。

跳转表对重复情况的处理就是简单地使用相同的代码标号,而对于缺失的情况的处理就是使用默认情况的标号(loc_def)

6. 函数(过程)

6.1 过程机制

**传递控制:**调用时转到调用过程代码的起始位置,结束时回到返回点。

**传递数据:**过程参数与返回值的传递。

**内存管理:**过程运行期间申请内存,返回时解除分配。

该机制全部由机器指令实现。

6.2 栈

栈的结构:
在这里插入图片描述

注意:①%rsp始终指向栈顶元素的位置。②向低地址生长。

栈的操作

入栈指令pushq src

从src取操作数 → 将%rsp减8 → 将操作数写到%rsp指向的位置

出栈指令popq dst

从%rsp中保存的地址处读取数值 → 将%rsp加8 → 将数值保存到dst(dst必须为寄存器或内存操作数)

6.3 过程控制流

过程调用

call func_label

执行操作:

①将返回地址入栈(返回地址即为紧随call指令的下一条指令的地址)

②跳转到func_label(函数名字就是函数代码段的起始地址)

过程返回

ret

执行操作:

从栈中弹出返回地址,放入%rip里(pc)

参数传递

在这里插入图片描述

返回值:%rax

局部变量:仅在需要时申请栈空间

6.4 栈帧

栈的分配单位为帧,保存单个过程实例的状态数据(参数、局部变量、返回地址等)

管理:进入过程时申请空间(生成代码,构建栈帧,包括call指令产生的push操作),返回时解除申请(结束代码,清理栈帧,包括ret指令产生的pop操作)

在这里插入图片描述

寄存器保存约定

寄存器组是唯一被所有过程共享的资源,必须确保当一个过程调用另一个过程时,被调用者不会覆盖调用者稍后会使用的寄存器值。

①调用者保存Caller Saved

调用者在调用前,在它的栈帧中保存临时值(寄存器)。

②被调用者保存Callee Saved

被调用者要先在自己的栈帧中保存,然后再使用寄存器。返回到调用者之前,恢复这些保存的值。

在这里插入图片描述

在这里插入图片描述

一个过程运行的示例

long caller()
{
	long arg1 = 534;
	long arg2 = 1057;
    long sum = swap_add(&arg1, &arg2);
    long diff = arg1 - arg2;
    return sum * diff;
}

对应汇编代码:
在这里插入图片描述
在这里插入图片描述

7. 数组

C语言可以产生指向数组中元素的指针,并对这些指针进行运算。在机器代码中,这些指针会被翻译成地址计算。

7.1 数组规则

T A[N];来声明数组(数据类型T,整型常数N)。会在内存中分配一个L·N字节的连续空间(L为数据类型T的字节大小),用A来作为指向数组开头的指针的标识符。数组元素i会被存放在地址 x A + L ⋅ i x_A+L·i xA+Li的地方。

在这里插入图片描述在这里插入图片描述

7.2 指针运算

在这里插入图片描述

7.3 二维数组

在这里插入图片描述
在这里插入图片描述

8. 结构体和联合

8.1 结构体

结构体的所有字段都存放在内存中一段连续的区域内,而指向结构体的指针就是结构体第一个字节的地址。使用字段相对于起始地址的偏移量来维护各个字段的信息。

字段的顺序必须与声明一致,即便其他顺序能使得内存更加紧凑也不行。

由编译器来决定总的尺寸和和字段的位置。

对齐

对齐后的数据:基本数据类型需要K字节,地址必须是K的倍数。

对其数据的动机:内存按4字节或8字节(对齐的)块来访问(4\8取决于系统),当一个数据跨越2个页面时,虚拟内存比较棘手,不能高效地装载或存储跨越四字边界的数据。

编译器在结构体中插入空白,以确保字段的正确对齐。
在这里插入图片描述

结构体内部:满足每个元素的对齐要求。

结构体整体的对齐存放:

​ K = 所有元素的最大对齐要求值

​ 则起始地址和结构体长度必须是K的倍数。

空间的节省:大尺寸数据类型在前。

8.2 联合

允许以多种类型来引用一个对象,用不同的字段来引用相同的内存块。一个联合的总的大小等于它最大字段的大小。若一个数据结构中的两个不同字段的使用是互斥的,那么将这两个字段声明为联合的一部分会减小分配空间的总量。

访问位模式

联合可以用来访问不同数据类型的位模式。在联合中,以一种数据类型来存储联合中的参数,又以另一种数据类型来访问,结果是他们会具有一样的位表示,包括符号位字段、指数和尾数。

此时字节顺序问题变得很重要,在小端与大端机器中对相同的位模式解读不同。

9. 浮点数

寄存器

YMM是256位,32字节

XMM是128位,16字节

在这里插入图片描述

支持操作

①标量操作:单精度/双精度

②SIMD操作:单指令多数据操作,允许多个操作以并行模式执行,对多个不同的数据并行执行同一个操作。
在这里插入图片描述

内存引用

参数传递:浮点型参数用YMM\XMM寄存器

使用不同的mov指令在YMM\XMM寄存器之间、或内存和YMM\XMM寄存器之间传送数值。

10.高级主题

10.1 理解指针

  1. 每个指针都对应一个类型

    通常如果对象类型位T,则指针的类型为T*

    特殊的void *类型代表通用指针,可以通过显式强转或者赋值等隐式强转来将其转换成一个有类型的指针。

  2. 每个指针都有一个值

​ 这个值是某个指定类型的对象的地址,特殊的NULL(0)值表示该指针没有指向任何地方。

  1. 指针用’&'运算符创建

    对应于机器代码的leaq指令

  2. 数组与指针紧密联系

    一个数组的名字可以像一个指针变量一样引用,但是不能修改。数组引用(a[3])与指针运算和间接引用(*(a+3))有一样的效果。

  3. 指针强转

​ 将指针从一种类型强制转换成另一种类型,只改变它的类型,而不改变它的值。效果是改变指针运算的伸缩。

  1. 指针可以指向函数

​ 函数名为指针。可以将指针赋值为函数,并且用指针来调用函数。

​ 函数指针的值是该函数机器代码表示中第一条指令的地址。

10.1 内存布局

在这里插入图片描述

堆中:大变量在高地址,小变量在低地址,便于内存的回收与释放,减少内存碎片

10.2 缓冲区溢出 buffer overflow

C对于数组引用不进行任何边界检查,而且局部变量和状态信息(保存的寄存器值和返回地址等)都存放在栈中。对越界的数组元素的写操作会破坏存储在栈中的状态信息,当程序使用被破坏的状态,试图重新加载寄存器或执行ret指令时就会出现很严重的错误。

安全隐患

一种常见的状态破坏称为缓冲区溢出,通常在栈中分配某个字符数组来保存一个字符串,但是字符串的长度超出了为数组分配的空间。

缓冲区溢出的一个更加致命的使用就是让程序执行它本来不愿意执行的函数。这是一种最常见的通过计算机网络攻击系统安全的方法。通常,输入给程序一个字符串,这个字符串包含一些可执行代码的字节编码,称为攻击代码(exploit code),另外,还有一些字节会用一个指向攻击代码的指针覆盖返回地址。那么,执行ret指令的效果就是跳转到攻击代码。

在一种攻击形式中,攻击代码会使用系统调用启动一个shell程序,给攻击者提供一组操作系统函数。在另一种攻击形式中,攻击代码会执行一些未授权的任务,修复对栈的破坏,然后第二次执行ret指令,(表面上)正常返回到调用者。

防护

  1. 避免溢出漏洞

​ 使用fgets代替gets: char *fgets(char *str, int n, FILE *stream)

​ 一般用fgets(buf, sizeof(buf), stdin)

​ 使用strncpy代替strcpy

​ 在scanf函数中别用%s:使用fgets读入字符串,或用%ns代替%s,其中n是一个合适的整数

  1. 使用系统级的防护

​ ①随机栈偏移(地址空间布局随机化技术的一部分):程序启动后,在栈中分配随机数量的空间,将移动整个程序使用的栈空间地址,每次程序执行,栈都重新定位,很难预测插入代码的起始地址。

​ ②非可执行段:标记存储区为“只读”或“可写”,但不给予“执行”权限,将stack标记为不可执行。

  1. 编译器使用“栈金丝雀”(stack canaries) / 哨兵值(guard value)

​ 在栈中buffer之后的位置放置特殊的值——金丝雀(canary),退出函数之前,检查是否被破坏。编译器默认开启。
在这里插入图片描述

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

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

相关文章

MySQL 数值函数

文章目录 数值函数1. abs(num)2. ceil(num)3. floor(num)4. mod(num1,num2)5. rand()6. round(num,n)7. truncate(num,n)8. sqrt(num) 数值函数 数值函数用来处理数值方面的运算,能够提高用户的工作效率。常用的数值函数如下表所示,函数括号内为输入的参…

牛客网基础语法11~20题

前言:今天是咱们第二期刷牛客网上的题目。 目标:对输入输出的格式,方法,类型掌握熟练,对double,float理解深入,编程思想更进一步。 鸡汤:人活着,再苦再累,都别…

16-Vue技术栈之常用的 Composition API

目录 1、什么是组合式 API?2、拉开序幕的setup3、ref函数4、reactive函数5、Vue3.0中的响应式原理5.1 vue2.x的响应式5.2 Vue3.0的响应式 6、reactive对比ref7、setup的两个注意点8、计算属性与监视8.1 computed函数8.2 watch函数8.3 watchEffect函数 9、 生命周期1…

防雷接地的施工工艺与防雷施工方案

雷电是自然界的一种强大而危险的自然现象,经常造成重大财产损失和人员伤亡。为了保护建筑物和人员免受雷电的危害,防雷接地系统的设计和施工至关重要。本文将介绍防雷接地的施工工艺和防雷施工方案,强调专业和符合国家标准的方法,…

chatgpt赋能python:Python中乘方运算符号:用于数学计算和科学计算

Python中乘方运算符号:用于数学计算和科学计算 简介 乘方运算是Python中常用的数学运算符,通常在数学计算和科学计算中使用。在Python中,乘方运算符用**表示。该运算符用于计算数字的指数幂。 用法 乘方运算符可以用于两个数字之间的计算…

vue开发环境搭建-win7

vue开发环境搭建-win7 1. 安装node,js2. 设置node global(全局)和cache(缓存)路径3. 配置环境变量4. 基于 Node.js 安装cnpm(淘宝镜像)5. 安装vue6. 安装vue脚手架 vue-cli7. 项目创建8. 添加相关依赖9. 修改端口号10. 运行项目 1. 安装node,js 下载no…

docker版jxTMS使用指南:python服务之内置自动机

本文讲解4.0版的jxTMS中python服务的内置自动机,整个系列的文章请查看:docker版jxTMS使用指南:4.0版升级内容 docker版本的使用,请参考:docker版jxTMS使用指南 4.0版jxTMS中python服务是一个采集前端数据的接口机。其…

【FreeMarker】学习笔记

【FreeMarker】学习笔记 【一】FreeMarker概述【1】FreeMarker概念【2】FreeMarker特性(1)通用目标(2)强大的模板语言(3)通用数据模型(4)为Web准备(5)强大的X…

opencv_c++学习(三十)

一、加载深度神经网络模型 Net cv:dnn::readNet(const String & model, const String & config "", const String & framework "")model:模型文件名称 config:配置文件名称 framework:框架种类 Net类中的函数名称以及作用: 向…

Eplan使用过程中的知识点1

一、新建时的几种标准模板 EPLAN中的符号库符合国际标准,分为单线图和原理图符号库。 符号库符合GB(国标)、IEC(国际标准)、NFPA(美国标准)和GOST(俄罗斯标准)4大标准。…

排水管网监测预警系统:全面感知管网运行态势

城市排水管网是城市基础设施系统中至关重要的一部分,它负责将雨水和废水排出城市,维持城市的正常运行。然而,随着管网的老化和城市扩张,排水管网出现了越来越多的问题,如泄漏、堵塞和损坏,给城市环境和公共…

一、机器人传动方式

1、齿轮传动 齿轮的最重要属性就是它的齿数。齿轮是根据齿数分类的。齿轮通常不会单独使用,齿 轮的基本属性就是可以将运动从一根轴传到其它轴上。 利用齿轮改变转速 利用齿轮改变转动方向 将旋转运动改变为直线运动 带自锁的涡轮蜗杆传动 齿轮可以用来传递力、增加…

Python中打印彩色信息的方法

在Python中,可以使用print()函数打印出彩色信息。在使用print()打印之前,需要调用os标准库对系统进行设置。 1 os标准库 1.1 简介 os是Operating System的简写,即“操作系统”。os标准库是一个操作系统接口模块,提供了使用操作…

关于Addressable打包图集与图片都打进去造成冗余

1)关于Addressable打包图集与图片都打进去造成冗余 ​2)Unity如何计算Root动画旋转 3)IL2CPP编译的Protobuf反射类运行时报空 4)为什么Active Constraints会出现过高的现象 这是第337篇UWA技术知识分享的推送,精选了UW…

配置 ssh key 后 git 拉取代码一直提示输入用户名、密码问题

中间过程比较碎碎念,涉及到一些错误的方案以及和 gpt 对线 可以直接跳到结论部分 0 场景 我有一个项目,仓库里已经配置了 ssh 公钥,但是每次 pull 或者 push 代码依旧提示输入用户名、密码 -1 失败的方案 -1.1 失败的方案1:全…

迅为国产化RK3588开发板在安防前后端应用解决方案

K3588是瑞芯微推出的一款高性能处理器,针对安防领域的应用具备强大的计算能力和图像处理能力。下面是关于RK3588的安防前后端应用解决方案的介绍: 前端摄像头端: 高清视频采集:利用RK3588处理器的高性能图像处理能力,…

MySQL 对字符串使用 STR_TO_DATE() 函数

文章目录 STR_TO_DATE() 函数1. 待转换字符串中出现数字以外的,自动去除字符,然后添加0至8位转换为日期2. 如果格式字符串仅包含日期,则待转字符串至少需要 8 位数字3. 转换后日期时间必须有效,否则返回结果为 null4. 如果被转字符…

视频怎么加水印?如何录制带水印的视频?

案例:如何给视频添加水印? 【我发布在短视频平台的视频,总是被别人盗用,我想给自己的视频添加水印。有没有视频添加水印的方法?在线等!】 很多视频制作者或者爱好者,都希望自己的视频作品得到…

OSPFv2特殊区域---NSSA区域

NSSA区域原理 NSSA区域 no-so-stub-area,次末梢区域。 NSSA区域能够将外部路由引入并传播到整个OSPF自治域中,同时又不会学习来自OSPF网络其它区域的5类LSA OSPF规定Stub区域是不能引入外部路由的,这样可以避免大量外部路由对Stub区域路由器…

我“Hack”了一款精酿啤酒

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 产品统筹 / bobo 联合制作 / 声网、CBCE 2023 录音间 / 声湃轩北京站 今天这位嘉宾的爱好非常广泛,除了自己是一位网络安全领域的从业者之外,平时还爱好攀…