汇编语言程序设计-2-访问寄存器和内存

news2025/2/27 22:55:55

2. 访问寄存器和内存

文章目录

  • 2. 访问寄存器和内存
    • 2.0 导学
    • 2.1 寄存器及数据存储
    • 2.2 mov和add指令
    • 2.3 确定物理地址的方法
    • 2.4 内存的分段表示法
    • 2.5 Debug的使用
    • 2.6 【代码段】CS、IP与代码段
    • 2.7 【代码段】jmp指令
    • 2.8 【数据段】内存中字的存储
    • 2.9 【数据段】用DS和[address]实现字的传送
    • 2.10 【数据段】DS与数据段
    • 2.11 【栈段】栈及栈操作的实现
    • 2.12 关于“段”的总结

  • 参考视频:烟台大学贺利坚老师的网课《汇编语言程序设计系列专题》,或者是B站《汇编语言程序设计 贺利坚主讲》,大家一起看比较热闹。
  • 中文教材:《汇编语言-第3版-王爽》(课程使用)、《汇编语言-第4版-王爽》(最新版)。
  • 老师的博客:《迂者-贺利坚的专栏-汇编语言》
  • 检测点答案参考:《汇编语言》- 读书笔记 - 各章检测点归档

本篇笔记对应课程第二章(下图倾斜),章节划分和教材对应关系如下。


2.0 导学

本章针对寄存器和内存的使用,开展如下学习内容:

【2.1 寄存器及数据存储】认识两者之间的关系。
【2.2 mov和add指令】通过这两个指令看到在运算中如何使用“寄存器”。
【2.3 确定物理地址的方法】CPU运行过程中,和内存的关系非常密切,所以介绍如何确定“物理地址”。
【2.4 内存的分段表示法】上面会分段使用内存,所以介绍“分段表示法”。
【2.5 Debug的使用】后续会非常频繁的使用Debug工具观察计算机内部状态。下面使用Debug工具观察内存的不同分段。

  • 代码段:【2.6 CS、IP与代码段】【2.7 jmp指令】
  • 数据段:【2.8 内存中字的存储】 【2.9 用DS和[address]实现字的传送】【2.10 DS与数据段】
  • 栈段: 【2.11 栈及栈操作的实现】

【2.12 关于“段”的总结】

2.1 寄存器及数据存储

图2-1 8086CPU的寄存器示意图

  在CPU中,“运算器”进行信息处理、“寄存器”进行信息存储、“控制器”协调各种器件进行工作、“内部总线”实现CPU内各个器件之间的联系。8086CPU所有的寄存器都是16位的,可以存放两个字节,8086CPU有14个寄存器(如上图标红):

  • 通用寄存器:AX(AH/AL)、BX(BH/BL)、CX(CH/CL)、DX(DH/D L)
  • 变址寄存器:SI、DI
  • 指针寄存器:SP、BP
  • 指令指针寄存器:IP
  • 段寄存器:CS、SS、DS、ES
  • 标志寄存器:PSW

而8086上一代CPU中的寄存器都是8位的,为了保证8086与上一代CPU程序兼容,“通用寄存器”均可以分为两个独立的8位寄存器使用。比如下图中,AX可以分为AH、AL:

图2-2 通用寄存器拆分——AX

  注意“字长(word size)”=“CPU的寄存器位宽”。因为8086是16位CPU,所以8086的字长为16bit。一个字(word)的高位字节(byte)存在这个寄存器的高8位寄存器、低位字节(byte)存在这个寄存器的低8位寄存器。但实际上,现代的CPU普遍是64位,此时“字长”就是64。

2.2 mov和add指令

图2-3 mov和add指令——默认十进制

  汇编指令不区分大小写。上图给出了movadd指令所完成的操作。现在假设 ax、bx 的初始值均为 0000H,那么下面两个程序分别展示了汇编指令程序的执行结果:

注意最后一步,左侧程序发生了溢出,最高位直接溢出。右侧程序add al,93H会直接舍弃低8位的进位,AX结果为 0058H;只有add ax,93H才会将低8位的进位保存到高8位中,AX结果为 0158H

【检测点2.1】

  1. 写出每条汇编指令执行后相关寄存器中的值。初始值为0000H。
汇编指令寄存器的值
mov ax,62627AX=F4A3H
mov ah,31H AX=31A3H
mov al,23H AX=3123H
add ax,ax AX=6246H
mov bx,826CHAX=6246H, BX=826CH
mov cx,ax AX=6246H, BX=826CH, CX=6246H
mov ax,bx AX=826CH, BX=826CH, CX=6246H
add ax,bx AX=04D8H, BX=826CH, CX=6246H
mov al,bh AX=0482H, BX=826CH, CX=6246H
mov ah,bl AX=6C82H, BX=826CH, CX=6246H
add ah,ah AX=D882H, BX=826CH, CX=6246H
add al,6 AX=D888H, BX=826CH, CX=6246H
add al,al AX=D810H, BX=826CH, CX=6246H
mov ax,cx AX=6246H, BX=826CH, CX=6246H
  1. 最多使用4条addmov指令,编程计算2的4次方。
mov ax,0002H # 2
add ax,ax    # 2+2=4
add ax,ax    # 4+4=8
add ax,ax    # 8+8=16

2.3 确定物理地址的方法

  CPU访问内存单元时要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,这个唯一的地址称为物理地址。但实际上,8086有20位地址总线,可传送20位地址,寻址能力为1M。但8086是16位结构的CPU,所以8086CPU使用两个16位地址(段地址、偏移地址)合成一个20位的物理地址:
物理地址 = 段地址 × 16 + 偏移地址 \bold{物理地址=段地址×16+偏移地址} 物理地址=段地址×16+偏移地址

  • 物理地址:20位。
  • 段地址:16位,相当于一个基础地址。“段地址×16”也就是“左移4位”。
  • 偏移地址:16位,也就是一个相对于基础地址的偏移地址。
图2-4 物理地址的生成方式、地址加法器的工作过程

注意,“段地址”并不是固定的,段地址和物理地址可以任意指定,只要最后的物理地址正确即可。

2.4 内存的分段表示法

  虽然8086使用分段的方式管理内存,但内存是一个完整空间并没有分段,段的划分来自于CPU!“段地址×16”被称为“段的起始地址”,显然“起始地址”一定是16的倍数;而“偏移地址”为16位,所以一个段的长度最大为 216=64K。同一段内存,多种分段方案,于是同一个物理地址也可以由不同的段地址和偏移地址组成,如下图所示:

图2-5 多种分段方案

段地址:用专门的寄存器存放段地址。下面是4个段寄存器:

  • CS - 代码段寄存器
  • DS - 数据段寄存器
  • SS - 栈段寄存器
  • ES - 附加段寄存器

偏移地址:可以用多种方法提供,也就是8086丰富的取址方式,也是汇编语言的重点。

最后补充一点,在8086PC机中,若数据存在内存的 2000H 段中的 1F60H 单元中,则存储单元地址表示为 2000:1F60。也就是 段地址:偏移地址的形式。

【检测点2.2】

  1. 给定段地址为0001H,仅通过变化偏移地址寻址,CPU 的寻址范围为 00010H 1000FH
  2. 有一数据存放在内存 20000H 单元中,现给定段地址为SA,若想用偏移地址寻到此单元。则 SA 应满足的条件是:最小为 1001H,最大为 2000H
    提示,反过来思考一下,当段地址给定为多少,CPU无论怎么变化偏移地址都无法寻到20000H单元?

2.5 Debug的使用

  Debug是DOS系统中的著名的调试程序,也可以运行在windows系统实模式下。使用Debug程序,可以查看CPU各种寄存器中的内容、内存的情况,并且在机器指令级跟踪程序的运行!Debug就是传奇!Debug一共有20多个命令,但下面这6个命令是和汇编学习密切相关的:

  • R命令:查看、改变CPU寄存器的内容
  • D命令:查看内存中的内容
  • E命令:改变内存中的内容
  • U命令:将内存中的机器指令翻译成汇编指令
  • A命令:以汇编指令的格式在内存中写入机器指令
  • T命令:执行机器指令
  • Q命令:退出debug

下面依次来进行演示:

启动Debug】在DOS提示符下输入命令:debug(也就是启动了masm文件夹中的Debug.exe)

用R命令查看、改变CPU寄存器的内容

  • R:查看寄存器内容
  • R 寄存器名:改变指定寄存器内容。可以没有中间的空格。
  • 左下角0000:0000:其实就是CS:IP,表示CPU当前要读取的指令所在的内存地址。
  • 左下角0000CS:IP内存地址中存放的机器码。
  • 下中间ADD [ES+SI],ALCS:IP内存地址中存放的指令的含义。
  • 右下角DS:0000=CD:刚才改变的寄存器值。后面还会介绍。

用D命令查看内存中的内容

  • D:列出从预设地址(CS:IP)开始,128个字节的内容。后续再调用 D会接着上一次的地址。右侧是ASCII码表示对应的字符。
  • D 段地址:偏移地址:列出指定地址开始,128个字节的内容。
  • D 段地址:偏移地址 结尾偏移地址:列出内存中指定地址范围内的内容,最多显示 216 个数据。

用E命令改变内存中的内容

  • E 段地址:偏移地址 数据1 数据2 ...:直接连续修改数据。
  • E 段地址:偏移地址:逐个询问式修改,空格表示继续修改;回车表示结束修改。
汇编指令对应的机器码
mov ax,0123HB8 23 01
mov bx,0003HBB 03 00
mov ax,bx89 D8
add ax,bx01 D8

用U命令将内存中的机器指令翻译成汇编指令

  • e 段地址:偏移地址 数据:写入指令对应的机器码。
  • d 段地址:偏移地址:查看写入的机器码。
  • u 段地址:偏移地址:将相应内存中的内容看作是“指令”,并进行翻译。

用A命令以汇编指令的格式在内存中写入机器指令

  • a 段地址:偏移地址:从指定地址处写入汇编指令。编写汇编程序时常用。
  • d 段地址:偏移地址:查看从指定地址开始的二进制机器码。
  • u 段地址:偏移地址:翻译从指定地址开始的二进制机器码,会根据汇编指令的不同自动切割字节。

用T命令执行机器指令

  • t:从 CS:IP处,逐条执行机器指令。

用Q命令退出Debug

  • q:退出Debug

2.6 【代码段】CS、IP与代码段

  CS为代码段寄存器,IP 为指令指针寄存器,它们是8086CPU中两个最关键的寄存器。从名称上我们可以看出它们和指令的关系。CS:IP指示了CPU当前要读取指令的地址。8086CPU读取指令时,会通过“地址加法器”将要读取的指令地址传输到数据总线,内存会一次性发送完整的一条指令给CPU执行(指令的操作码包含指令长度信息),此时 IP 自动增加当前指令长度,然后继续读取下一指令并执行。如下图:

图2-6 8086CPU读取和执行指令的相关部件

【8086CPU 当前状态】
CS:IP2000H:0000H,内存 20000H~20009H 单元存放着可执行的如下机器码:

  • 地址 20000H~20002H,长度 3Byte,内容 B8 23 01,对应汇编指令 mov ax,0123H
  • 地址 20003H~20005H,长度 3Byte,内容 BB 03 00,对应汇编指令 mov bx,0003H
  • 地址 20006H~20007H,长度 2Byte,内容 89 D8,对应汇编指令 mov ax,bx
  • 地址 20008H~20009H,长度 2Byte,内容 01 D8,对应汇编指令 add ax,bx

笔者注:CS:IP就相当于“计算机组成原理”中的PC(计数器)。

注意到,机器码存储在内存中,既可以是数据、也可以是内存。但是CPU会将 CS:IP指向的内存单元中的内容默认看作指令!

【实证演示】

  1. 写入汇编指令。
  2. 查看汇编指令。
  3. 执行代码。

2.7 【代码段】jmp指令

  在实际的程序运行过程中,经常会出现程序的跳转,比如程序进入中断时需要跳转到“中断向量入口地址”。上一小节又讲到 CS:IP就是当前指令地址,于是要实现程序跳转本质上就需要修改 CS:IP,有如下方法:

  1. debug的R命令:上一小节用到的方法,但debug只是一个调试工具,而非汇编程序本身!
  2. mov指令:mov CS,2000mov IP,0000,但是8086CPU不支持使用mov指令修改CS和IP。
  3. jmp指令:转移指令,专门用于程序跳转!
  • jmp 段地址:偏移地址:将CS修改为“段地址”,IP修改为“偏移地址”。
  • jmp 寄存器名:只是将IP修改为寄存器中的值,比如 jmp ax相当于 mov IP,ax(实际并不能这样使用mov)。

下面通过一个演示,来验证 jmp指令的作用:

【实证演示】
假设在下图所示的内存中存放相应的指令,并且程序从 2000H 执行,那么执行序列最后会进入死循环。

  此时,我们可以规定某个“段地址”就对应一个“代码段”,这个“代码段”的最大长度为 216=64K 个字节。但注意CPU本身并不会有这样的区分,只是这样规定可以使得代码的存放位置更加清晰。

【检测点2.3】
下面的3条指令执行后,CPU几次修改IP?都是在什么时候?最后IP中的值是多少?

mov ax, bx
sub ax, ax
jmp ax

答:IP 总共改了4次:读取每条指令后IP修改一次;执行 jmp ax再修改一次。最后 IP 中的值是 0 (因为 sub ax,ax后 ax=0000H)。

2.8 【数据段】内存中字的存储

  8086CPU中,一个“”为16位,于是需要两个连续的字节单元存放,被称为“字单元”。高8位放高字节,低8位放低字节,也就是计组中的“小端模式”。于是,一个“单元”存放一个“字节型数据”、一个“字单元”存放一个“字型数据”。下图中,前两种都是小端模式,但是将高地址写在上面方便阅读(中间图):

图2-7 内存中字的存储-小端模式

2.9 【数据段】用DS和[address]实现字的传送

  8086CPU中的内存单元地址都是 段地址:偏移地址的格式,CPU寄存器 CS:IP表示当前的指令地址,于是 DS:[...] 则表示想读取的数据(字单元)的地址。另外,8086CPU不支持将数据直接送入段寄存器(硬件设计的问题),所以段地址写入顺序固定为:数据 -> 一般的寄存器 -> 段寄存器。如下:

  • DS寄存器:存放要访问的数据的段地址。
  • [...]:直接给出16位的偏移地址(16进制),而不是特定的寄存器。

【示例1】将10000H(1000:0)中的数据读到al中

mov bx,1000H
mov ds,bx
mov al,[0]

【示例2】将al中的数据写到10000H(1000:0)中

mov bx,1000H
mov ds,bx
mov [0],al

【实证演示1】按照下图调整数据和内存,注意不同偏移地址的 读出数据

【实证演示2】注意观察写入数据时,也是小端模式。

2.10 【数据段】DS与数据段

  和“代码段”类似,根据数据的内存单元地址为 DS:[偏移地址],我们也可以利用 数据段寄存器DS 将一组内存单元定义为一个“数据段”,而具体的数据单元则由 [偏移地址]给出。同样,“数据段”也是编程时的人为安排,与8086CPU或者内存的物理结构无关。下面是一个利用“数据段”进行编程的示例:

【程序1】累加数据段中的前3个单元中的数据:使用寄存器 ax 的低8位 al。

mov ax, 123BH
mov ds, ax
mov al, 0
add al, [0]
add al, [1]
add al, [2]

【程序2】累加数据段中的前3个字型数据:使用完整的16位寄存器 ax。

mov ax, 123BH
mov ds, ax
mov ax, 0
add ax, [0]
add ax, [2]
add ax, [4]

下面针对 movaddsub这三个指令,给出其支持的指令格式。其他没有提到的指令格式,可以在debug中尝试。

表2-1 mov、add、sub 的指令格式
类型mov指令形式例示add指令形式例示sub指令形式例示
寄存器mov 寄存器,数据mov ax, 8add 寄存器,数据add ax, 8sub 寄存器,数据sub ax, 8
mov 寄存器,寄存器mov ax, bxadd 寄存器,寄存器add ax, bxsub 寄存器,寄存器sub ax, bx
mov 寄存器,内存单元mov ax, [0]add 寄存器,内存单元add ax, [0]sub 寄存器,内存单元sub ax, [0]
mov 寄存器,段寄存器mov ax, dsadd 寄存器,段寄存器不支持sub 寄存器,段寄存器不支持
内存单元mov 内存单元,数据不支持add 内存单元,数据不支持sub 内存单元,数据不支持
mov 内存单元,寄存器mov [0], axadd 内存单元,寄存器add [0], axsub 内存单元,寄存器sub [0], ax
mov 内存单元,内存单元不支持add 内存单元,内存单元不支持sub 内存单元,内存单元不支持
mov 内存单元,段寄存器mov [0], dsadd 内存单元,段寄存器不支持sub 内存单元,段寄存器不支持
段寄存器mov 段寄存器,数据不支持add 段寄存器,数据不支持sub 段寄存器,数据不支持
mov 段寄存器,寄存器mov ds, axadd 段寄存器,寄存器不支持sub 段寄存器,寄存器不支持
mov 段寄存器,内存单元mov ds, [0]add 段寄存器,内存单元不支持sub 段寄存器,内存单元不支持
mov 段寄存器,段寄存器不支持add 段寄存器,段寄存器不支持sub 段寄存器,段寄存器不支持

【数据段-小结】

  1. 字在内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放在低地址单元中,高位字节存放再高地址单元中。
  2. mov指令要访问内存单元,可以在 mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中。
  3. [address]表示一个偏移地址为address的内存单元。
  4. 在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器、低地址单元和低8位寄存器相对应。
  5. movaddsub是具有两个操作对象的指令,访问内存中的数据段。jmp是具有一个操作对象的指令,对应内存中的代码段。
  6. 可以根据自己的推测,在Debug中实验指令的新格式。

2.11 【栈段】栈及栈操作的实现

  “”是一种只能在一端进行插入或删除操作的数据结构,符合LIFO(Last In First Out,后进先出)的操作规则。现今的CPU中都有栈的设计,也就是8086CPU提供相关的栈指令,支持用栈的方式访问内存空间,并且寄存器 SS:SP始终指向栈顶元素的地址。下面是 SS:SP以及 栈操作指令:

  • 栈段寄存器SS:存放栈顶的段地址,同时也默认为最小的栈顶地址。
  • 栈顶指针寄存器SP:存放栈顶的偏移地址,初始值为栈的大小(可以理解为栈底)。
  • push ax:将ax中的数据送入栈中,SP自动减2(以字为单位)。
  • pop ax:从栈顶取出数据送入ax,SP自动加2(以字为单位)。

【实例演示】使用pushpop交换ax和bx中的内容。

  • 初始栈顶始终不存储任何有效元素。
  • 第一个元素存储在初始栈顶指针SP的上一个字。

  若不断的调用 push或者pop指令,就会导致 SP 指针超出栈的范围,也就是“栈顶超界问题”。遗憾的是,8086CPU只知道栈顶在何处(SS:SP),却不知道程序安排的栈空间有多大,8086CPU不保证对栈的操作不会超界。为了防止超界,汇编语言程序员需要格外小心。

2.12 关于“段”的总结

  由于内存地址为 段地址:偏移地址,所以每一种“段”的起始地址都是16的倍数。目前我们学习了三种段:

  1. 数据段:将段地址放在 DS 中。用mov、add、sub等访问内存单元的指令时,CPU将我们定义的数据段中的内容当作数据段来访问。
  2. 代码段:将段地址放在 CS 中,将段中第一条指令的偏移地址放在 IP 中。CPU将执行我们定义的代码段中的指令。
  3. 栈段:将段地址放在 SS 中,将栈顶单元的偏移地址放在 SP 中。CPU在需要进行栈操作(push、pop)时,就将我们定义的栈段当作栈空间来用。

实际在编写汇编语言程序时,为了逻辑清晰,可以对不同的段进行分区,可以将三个段全部分开或者放在一起。但注意“段”的划分只取决于汇编语言程序员,与CPU设计无关。

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

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

相关文章

傻瓜化备份/恢复K8S集群Etcd数据

前言: 备份重要数据,简化重复操作,让一指禅、点点点也能完成运维任务。 脚本呈现界面如下: 1、查看Etcd版本 rootmaster:~# cat /etc/kubernetes/manifests/etcd.yaml | grep image: | awk {print $2} registry.aliyuncs.com/goo…

企业运维背后的故事:TASKCTL带你了解日常工作与技术演进

今天,作为一名经验丰富、从业多年经常与运维人员打交道的人,我想与大家聊聊运维的日常工作、部门协调以及未来发展,希望能为即将转行或正在从事运维工作的你,提供一些新的视角和启发。 运维的日常工作:挑战与乐趣并存 …

【密评】 | 商用密码应用安全性评估从业人员考核题库(11)

字母频率分析法对()算法最有效。 A.置换密码 B.单表代换密码 C.多表代换密码 D.序列密码 GM/Z4001《密码术语》中,保证信息不被泄露给非授权的个人、进程等实体的性质称为密码的()。 A.真实性 B.完整性 C.机密性 D.不…

LCD和OLED的区别

这里写目录标题 什么是LCD?什么是LED/OLEDLED和OLED的发光原理LCD的缺陷OLED屏幕的优势OLED屏幕的劣势 什么是LCD? LCD 英文全称 Liquid Crystal Display ,中文翻译为液晶显示器。LCD 的构造是在两片平行的玻璃基板当中放置液晶盒&#xff0…

Visual Studio Community : The prerelease has expired

最近使用旧版的离线安装包安装社区版Visual Studio2022(Visual Studio Community 2022),安装完成后显示:The prerelease has expired。使用自己的微软账号登录还是一样的情况,只能强制退出。经过摸索后发现了一个解决方…

tab 滑动小案例

效果&#xff1a; 代码&#xff1a; <template><view class"content"><view class"tab"><view v-for"(item,index) in dataList" :key"index" class"tab_item" click"slideTab(index)">…

爱普生MCU系列语音芯片S1C31D41

随着科技的发展和产品的集成化&#xff0c;语音芯片已经逐渐替代了多种语音设备应用在各场合。语音芯片主要特性是功耗低&#xff0c;抗干扰能力强&#xff0c;外围器件少&#xff0c;控制简单&#xff0c;语音保存时间久(某些语音芯片可以保存内容100年)&#xff0c;掉电不丢失…

java 解决跨域时遇到问题,怎么来做一个跨域环境

今天遇到一个问题&#xff1a; 关于#java#的问题&#xff1a;java 解决跨域时遇到问题&#xff1a;为什么跨域访问时配置的CorsFilter没有进入&#xff1f;直接访问请求地址时进入了配置的CorsFilter 由于没有实际的跨域环境&#xff0c;因此打算在本机建一个跨域环境&#xff…

钉钉对接打通金蝶云星空获取流程实例(宜搭)接口与付款单新增接口

钉钉对接打通金蝶云星空获取流程实例&#xff08;宜搭&#xff09;接口与付款单新增接口 对接系统钉钉 钉钉&#xff08;DingTalk&#xff09;是阿里巴巴集团专为中国企业打造的免费沟通和协同的多端平台&#xff0c;提供PC版&#xff0c;Web版和手机版&#xff0c;有考勤打卡、…

如何安全高效地进行4S店文件分发,保护核心资产?

4S店与总部之间的文件分发是确保双方沟通顺畅、信息共享和决策支持的重要环节。4S店文件分发涉及到以下文件类型&#xff1a; 销售报告&#xff1a;4S店需要定期向总部提交销售报告&#xff0c;包括销售数量、销售额、市场份额等关键指标。 库存管理文件&#xff1a;包括车辆库…

HTML满屏漂浮爱心

目录 写在前面 满屏爱心 代码分析 系列推荐 写在最后 写在前面 小编给大家准备了满屏漂浮爱心代码&#xff0c;一起来看看吧~ 满屏爱心 文件heart.svg <svg xmlns"http://www.w3.org/2000/svg" width"473.8px" height"408.6px" view…

SpringBoot设置默认文件大小

1、问题发现 有个需求&#xff0c;上传文件的时候&#xff0c;发现提示了这个错误&#xff0c;看了一下意思是说&#xff0c;文件超过了1M。 看我们文件的大小&#xff1a; 发现确实是&#xff0c;文件超出了1M&#xff0c;查了一下资料&#xff0c;tomcat默认上传文件大小为1M…

什么是工具? 从语言模型视角的综述

24年3月CMU和上海交大的论文“What Are Tools Anyway? A Survey from the Language Model Perspective”。 到底什么是工具&#xff1f; 接下来&#xff0c;工具在哪里以及如何帮助语言模型&#xff1f; 在综述中&#xff0c;对语言模型使用的外部程序工具进行了统一定义&…

天机学堂—项目总览和基建

总览 天机学堂是一个基于微服务架构的生产级在线教育项目。 项目亮点 技术架构 环境搭建 为了模拟真实开发环境&#xff0c;我们准备了一台虚拟机&#xff0c;在其中安装了各种各样的公共服务和组件。 Jenkins 是一个开源的持续集成&#xff08;Continuous Integration&…

【opencv】信用卡号识别实验

实验环境&#xff1a;anaconda、jupyter notebook&#xff08;其它的ide也行&#xff09; 实验用的包&#xff1a;numpy、matplotlib、opencv 实验目标&#xff1a; 识别信用卡的卡号 信用卡图片&#xff1a; 数字模板图片&#xff1a; 一、包引入 import cv2 import matplo…

02-WPF_基础(一)

1、基础 各模块类型 链接&#xff1a;如何&#xff1a;向 Viewbox 的内容应用 Stretch 属性 - WPF .NET Framework | Microsoft Learn WPF基础以及事件绑定与数据绑定的情况&#xff0c;&#xff0c;在学习XAML&#xff0c;数据结构以及一个项目学习平台来练手&#xff0c;网络…

windows10安装WSL2及使用

1、安装 安装步骤见官网&#xff1a;https://learn.microsoft.com/zh-cn/windows/wsl/install-manual 2、调整WSL占用内存和空间 装完WSL后&#xff0c;查看任务管理器时发现vmmem进程占用内存过高。WSL内存默认值是电脑内存的一半&#xff0c;CPU默认值是电脑处理器个数&am…

vue3 中 使用 antd中的select 组件的带搜索框 展开后可对选项进行筛选搜索功能

鼠标进入以后下拉显示&#xff1a; 输入字符串以后&#xff1a; 可以看出对数据进行了筛选。 具体代码&#xff1a; 结构上&#xff1a;<a-selectv-model:value"formState.formFlow"show-searchallowClearplaceholder"输入选择流程":options"op…

生产透明化,交付无烦恼

生产进度总延误 质量把控总失守 计划赶不上变化 沟通不畅易误解 ...... 这些问题可能在一些工厂管理中几乎每天都在上演。 在如今快速变化的市场环境中&#xff0c;企业的生产效率和交付能力成为了衡量其竞争力的关键指标。而要实现高效、准确的生产和交付&#xff0c;透明化的…

无人机的用途

无人机&#xff0c;即无人驾驶飞机&#xff0c;其用途广泛且多样&#xff0c;涉及到多个领域。 在农业领域&#xff0c;无人机通过搭载各种传感器和相机&#xff0c;可以对农田进行空中巡视&#xff0c;收集农田数据&#xff0c;如土壤含水量、气温、湿度等&#xff0c;以及植…