贺利坚汇编课程笔记2 访问寄存器和内存

news2024/11/25 20:54:09

贺利坚汇编课程笔记2 访问寄存器和内存

文章目录

  • 贺利坚汇编课程笔记2 访问寄存器和内存
  • 0201 寄存器及数据存储
    • CPU的组成
    • 寄存器是CPU内部的信息存储单元
    • 通用寄存器--以AX为例
    • “字”在寄存器中的存储
  • 0202 mov 和 add指令
  • 0203 确定物理地址的方法
    • 物理地址
    • 8086CPU给出物理地址的方法
    • 例:8086CPU访问地址为123C8H的内存单元
    • “段地址×16+偏移地址=物理地址”的本质含义
  • 0204 内存的分段表示法
    • 用分段的方式管理内存
    • 同一段内存,多种分段方案
    • 用不同的段地址和偏移地址形成同一个物理地址
  • 0205 Debug的使用
    • Debug是什么?
    • Debug能做什么
    • 启动Debug
    • 用R命令查看、改变CPU寄存器的内容
    • 用D命令查看内存中的内容
    • 用E命令改变内存中的内容
    • 用U命令将内存中的机器指令翻译成汇编指令
    • 用A命令以汇编指令的格式在内存中写入机器指令
    • 用T命令执行机器指令
    • 用Q命令退出Debug
  • 0206 CS、IP与代码段
    • 两个关键的寄存器 CS IP
    • 例示:在CS和IP指示下代码的执行
    • 在Debug中实证演示上面的示例
  • 0207 jmp指令
    • 修改CS、IP的指令
    • 转移指令jmp
      • 用Debug实操一下
  • 0301 内存中字的存储
    • 字单元
  • 0302 用DS和[address]实现字的传送
    • 要解决的问题
    • 字的传送
    • 案例
      • debug实操
  • 0303 DS与数据段
    • 对内存单元中数据的访问
    • 例 将123B0H~123BAH的内存单元定义为数据段
    • 用mov指令操作数据
    • 加法add和减法sub指令
    • 用DS和[address]形式访问内存中数据段方法小结
  • 0304 栈及栈操作的实现
    • 栈结构
    • 栈的操作
      • 例:把10000H~1000FH内存当作栈来使用
        • debug验证
      • 栈顶超界问题
    • 栈的小结
  • 0305 关于”段“的总结
    • 三种段
    • 综合示例:按要求设置段
      • debug演示
    • 综合示例:三个段地址可以一样

0201 寄存器及数据存储

CPU的组成

  • 运算器进行信息处理;
  • 寄存器进行信息存储;
  • 控制器协调各种器件进行工作;
  • 内部总线实现CPU内各个器件之间的联系

寄存器是CPU内部的信息存储单元

  • 8086CPU有14个寄存器
    • 通用寄存器:AX BX CX DX
    • 变址寄存器:SI DI
    • 指针寄存器:SP BP
    • 指令指针寄存器:IP
    • 段寄存器:CS SS DS ES
    • 标志寄存器:PSW
  • 共性
    • 8086CPU所有寄存器都是16位的,可以存放两个字节

通用寄存器–以AX为例

  • 一个16位寄存器存储一个16位的数据,能保存的数据的最大值为 2 16 − 1 ( F F F F H ) 2^{16}-1(FFFFH) 2161(FFFFH)

  • 例:在AX中存储18D

    • 12H

    • 10010B

  • 问题 :8086上一代CPU中的寄存器都是8位 的,如何保证程序的兼容性?

    • 通用寄存器均可以分为两个独立的 8位寄存器使用
      • AX可以分为AH和AL
      • BX可以分为BH和BL
      • CX可以分为CH和CL
      • DX可以分为DH和

“字”在寄存器中的存储

  • 8086是16位CPU ; 8086的字长(word size)为16bit :
  • 一个(word)可以存在一个16位寄存器中 ;
    • 这个字的高位字节存在这个寄存器的高8位寄存器 ;
    • 这个字的低位字节存在这个寄存器的低8位寄存器

image-20221129064828494

0202 mov 和 add指令

  • 例1

    看到老师演示windows自带计算器的程序员模式,感觉还挺好玩的

    功能很强大

    居然还有这个 BYTE WORD DWORD QWORD(四字)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    注意溢出

    在这里插入图片描述

  • 例2

    看清楚 l 和 h ,注意溢出

    最后那个158, 1要丢弃

0203 确定物理地址的方法

物理地址

  • CPU访问内存单元时要给出内存单元的地址。
  • 所有的内存单元构成的存储空间是一个一维的线性空间。
  • 每一个内存单元在这个空间中都有唯一的地址,这个唯一的地址称为**物理地址**。
  • 事实 :
    • 8086有20位地址总线,可传送20位地址,寻址能力为1M。
    • 8086是16位结构的CPU
      • 运算器一次最多可以处理16位的数据,寄存器的最大宽度为16位。
      • 在8086内部处理的、传输、暂存的地址也是16 位,寻址能力也只有64KB!
  • 问题:8086如何处理在寻址空间上的这个矛盾? 👇

8086CPU给出物理地址的方法

  • 8086CPU的解决方法

    • 用两个16位地址(段地址、偏移地址) 合成一个20位的物理地址。
  • 地址加法器合成物理地址的方法

    • 物理地址=段地址×16+偏移地址

      (段地址左移4位)

例:8086CPU访问地址为123C8H的内存单元

老师这里演示的动画非常棒!

  • 段地址:1230,偏移地址:00c8
  • 段地址:123C,偏移地址:0008
  • 段地址:123B,偏移地址:0018
  • 这些都是可以的

“段地址×16+偏移地址=物理地址”的本质含义

哈哈哈,老师举的这个姚明的例子还挺好玩的

  • 要解决的问题
    • 用两个16位的地址(段地址、偏移地址), 相加得到一个20位的物理地址
  • 本质含义
    • CPU在访问内存时,用一个基础地址(段地址×16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址

0204 内存的分段表示法

用分段的方式管理内存

同一段内存,多种分段方案

  • 段地址×16 必然是 16的倍数,所以一个段的起始地址也一定是16的倍数

  • 偏移地址为16位,16 位地址的寻址能力为 64K,所以一个段的长度最大为64K

起始地址(基础地址)为10000H,段地址为1000H,大小为100H

[

段地址取前16位

起始地址(基础地址)为10000H和10080H,段地址为1000H和1008H,大小均为80H

用不同的段地址和偏移地址形成同一个物理地址

0203 里面已经举过例子

  • 再举个例子 物理地址:21F60H

    段地址偏移地址
    2000H1F60H
    2100H0F60H
    21F0H0060H
    21F6H0000H
    1F00H2F60H
    • 在8086PC机中存储单元地址的表示方法

    下面两种说法等价

  • 偏移地址16位,变化范围为0~FFFFH,用偏移地址最多寻址64KB

    • 例:给定段地址2000H,寻址范围是20000H~2FFFFH,共64KB
  • 段地址非常重要

  • 偏移地址可以用多种方法提供——8086丰富的取址方式

0205 Debug的使用

Debug是什么?

医学中的内窥镜

Debug能做什么

  • 用R命令查看、改变CPU寄存器的内容
  • 用D命令查看内存中的内容
  • 用E命令改变内存中的内容
  • 用U命令将内存中的机器指令翻译成汇编指令
  • 用A命令以汇编指令的格式在内存中写入机器指令
  • 用T命令执行机器指令
  • … and so on

启动Debug

  • 把debug所在的路径挂载到c上面,然后敲入debug

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

  • r:查看寄存器内容
  • r 寄存器名(r和寄存器中可以没有空格):改变指定寄存器内容

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

  • D 列出预设地址内存处的 128个字节的内容
  • D 段地址:偏移地址 列出内存中指定地址处的内容

  • D 段地址:偏移地址 结尾偏移地址 列出内存中指定地址范 围内的内容

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

  • E 段地址:偏移地址 数据1 数据2 ...
  • E 段地址:偏移地址

    • 逐个询问式修改

    • 空格 - 接受,继续

    • 回车 - 结束

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

    • 有汇编指令

      • mov ax 0123H

      • mov bx, 0003H

      • mov ax, bx

      • add ax, bx

    • 对应的机器码为

      • B8 23 01
      • BB 03 00
      • 89 D8
      • 01 D8
    • e 地址 数据 - 写入

    • d 地址 - 查看

    • u 地址 - 查看代码

神奇捏 可以看作指令 也可以看作数据

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

    • 有汇编指令

      mov ax, 0123H 
      mov bx, 0003H 
      mov ax, bx 
      add ax, bx 
      
    • 对应的机器码为

      B8 23 01 
      BB 03 00 
      89 D8 
      01 D8
      
    • a 地址 - 写入汇编指令

      写入cs:ip处

      a 073F:0100
      
    • d 地址 - 查看数据

    • u 地址 - 查看代码

用T命令执行机器指令

  • t - 执行CS:IP处的指令

用Q命令退出Debug

  • q - 退出Debug

0206 CS、IP与代码段

两个关键的寄存器 CS IP

  • CS:代码段寄存器
  • IP: 指令指针寄存器
  • CS:IP:CPU将内存中CS:IP 指向的内容当作指令执行

例示:在CS和IP指示下代码的执行

  • 8086CPU当前状态:CS中内容为2000H,IP中内容为0000H

  • 内存20000H~20009H处存放着可执行的机器代码

https://www.bilibili.com/video/BV1pi4y1P76P?p=13&spm_id_from=pageDriver&vd_source=0e8431ba6fd78bb2215c36307a75ac1a
视频 P13 5min处 的演示动画 好棒!

  • 8086PC工作过程的简要描述
    1. 从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器
    2. IP = IP + 所读取指令的长度,从而指向下一条指令
    3. 执行指令。转到步骤1,重复此过程

在Debug中实证演示上面的示例

上面那个图

  • 先把CS改为2000, IP改为0

    r cs
    :2000
    r ip
    :0
    r
    
  • 用A命令把代码写入 , U命令查看代码

    mov ax, 0123H
    mov bx, 0003H
    mov ax, bx
    add ax, bx
    
  • t执行cs:ip处的代码

  • 前面的问题, 当指令使用还是当数据使用?

    d命令显示的是“狭义”的数据

    u显示了“广义”的数据:数据和指令

    • 取决于程序员,如果是当指令使用, 那设置为CS:IP指向这一段, CPU就会把这一段当作指令使用

0207 jmp指令

修改CS、IP的指令

  • 执行何处的指令,取决于CS:IP

  • 可以通过改变CS、IP中的内容,来控制CPU要执行的目标指令 :

  • 那么如何改变CS、IP的值?

    • 方法1:Debug 中的 R 命令可以改变寄存器的值——rcs, rip

      • Debug是调试手段,并非程序方式
    • 方法2:用指令修改

    - 方法3 👇
    • jmp指令

转移指令jmp

  • 可以同时修改cs、ip的内容

    jmp 段地址:偏移地址

    jmp 2AE3:3
    jmp 3:0B16
    

    功能:用指令中给出的段地址修改CS,偏移地址修改IP

  • 也可以仅修改ip的内容

    jmp某一合法寄存器

    jmp ax
    jmp bx
    

    (类似于mov IP,ax,但是注意mov IP,ax是不允许的!)

  • 从20000H开始,执行的指令序列是

    mov ax,6622H
    jmp 1000:3
    mov ax,0000
    mov bx,ax
    jmp bx ;修改IP IP变为0
    mov ax,0123H
    ;转到第(3)步mov ax,0000执行  开始循环
    

用Debug实操一下

  • 环境准备

  • 执行指令

0301 内存中字的存储

  • 对8086CPU,16位作为一个字

    • 问题:16位的字存储在一个16位的寄存器中,如何存储?
      • 回答:高8位放高字节,低8位放低字节 :
    • 问题: 16位的字在内存中需要2个连续字节存储,怎么存放?
      • 回答 ; 低位字节存在低地址单元,高位字节存在高地址单元
  • 例:20000D(4E20H)存放0、1两个单元,18D (0012H)存放在2、3两个单元

    书中一般是最左边那个,

    注意描述方式 0012H的起始地址是2 4E20H的起始地址是0

字单元

  • 字单元:由两个地址连续的内存单元组成,存放一个字型数据(16位)

    • 框出来的方式都可以组成一个字单元

  • 原理:在一个字单元中,低地址单元存放低位字节,高地址单元存放高位字节 ; 在起始地址为0的单元中,存放的是4E20H ; 在起始地址为2的单元中,存放的是001

  • 问题:
    • (1)0地址单元中存放的字节型数据是(20H)
    • (2)0地址字单元中存放的字型数据是(4E20H)
    • (3)2地址单元中存放的字节型数据是(12H)
    • (4)2地址字单元中存放的字型数据是(0012H )

0302 用DS和[address]实现字的传送

要解决的问题

  • 要求 :CPU要读取一个内存单元的时候,必须先给出这个内存单元的地址;
  • 原理 ;:在8086PC中,内存地址由段地址偏移地址组成(段地址:偏移地址)
  • 解决方案:DS和[address]配合
    • DS寄存器存放要访问的数据的段地址
    • 偏移地址用[…]形式直接给出
  • 例1 将10000H(1000:0)中的数据读到al中

    mov bx,1000H
    mov ds,bx
    mov al,[0] ;[0]这种方式给出,段地址默认在DS
    
  • 例2 将al中的数据写到10000H(1000:0)中

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

cs:ip是执行,ds:[address] 是拿数据。

字的传送

  • 8086CPU可以一次性传送一个字(16位的数据)

  • mov bx, 1000H 
    mov ds, bx 
    mov ax, [0] ;1000:0处的字型数据送入ax 
    mov [0], cx ;cx中的16位数据送到1000
    

案例

debug实操

  • 准备数据和指令

    写入之后

  • 执行指令

0303 DS与数据段

对内存单元中数据的访问

  • 对于8086PC机,可以根据需要将一组内存单元定义为一个段

    • 物理地址=段地址×16+偏移地址
    • 将一组长度为N(N≤64K)、地址连续、起始地址为16的倍数的内存单元当作专门存储数据的内存空间,从而定义了一个数据段
  • 例:用123B0H~123B9H的空间来存放数据

    • 段地址:123BH 起始偏移地址:0000H 长度:10字节

    • 段地址:1230H 起始偏移地址:00B0H 长度:10字节

    • and so on …

      将哪段内存当作数据段,段地址如何定,在编程时安排

  • 处理方法:(DS)😦[address])

    • 用DS存放数据段的段地址
    • 用相关指令访问数据段中的具体单元,单元地址由[address]指出
      • mov add sub等

例 将123B0H~123BAH的内存单元定义为数据段

  • 例:累加数据段中的前3个单元中的数据

    mov ax, 123BH
    mov ds, ax
    mov al,0    ;al清零
    add al,[0]
    add al,[1]
    add al,[2]
    
  • 例:累加数据段中的前3个字型数据

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

用mov指令操作数据

指令形式示例
mov 寄存器,数据mov ax, 8
mov 寄存器,寄存器mov ax, bx
mov 寄存器,内存单元mov ax, [0]
mov 内存单元,寄存器mov [0], ax
mov 段寄存器,寄存器mov ds, ax
  • 学习方法:大胆假设,小心求证

    推测1~3 可以,推测4不行

加法add和减法sub指令

段寄存器不能参与add运算

两个内存单元也不能直接相加

用DS和[address]形式访问内存中数据段方法小结

mov ax,1000H
mov ds,ax
mov ax,11316
mov [0],ax
mov bx,[0]
sub bx,[2]
mov [2],bx
  • 字在内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放在低地址单元中,高位字节存放在高地址单元中

  • 用mov指令要访问内存单元,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中

  • [address]表示一个偏移地址为address的内存单元

  • 在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器、低地址单元和低8位寄存器相对应

  • mov、add、sub是具有两个操作对象的指令,访问内存中的数据段

    (对照:jmp是具有一个操作对象的指令,对应内存中的代码段)

  • 可以根据自己的推测,在Debug中实验指令的新格式

0304 栈及栈操作的实现

栈结构

  • 栈是一种只能在一端进行插入或删除操作的数据结构。
  • 栈有两个基本的操作:入栈和出栈
  • 入栈:将一个新的元素放到栈顶
  • 出栈:从栈顶取出一个元素
  • 栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。
  • 栈的操作规则:LIFO(Last In First Out,后进先出)
  • CPU提供的栈机制
    • 现今的CPU中都有栈的设计。
    • 8086CPU提供相关的指令,支持用栈的方式访问内存空间。
    • 基于8086CPU的编程,可以将一段内存当作栈来使用。

栈的操作

  • PUSH(入栈)和 POP(出栈)指令
    • push ax:将ax中的数据送入栈中
    • pop ax:从栈顶取出数据送入ax (以字为单位对栈进行操作)

例:把10000H~1000FH内存当作栈来使用

  • 视频里很棒的动画演示

    没有问题,栈(地址)增长方向和内存单元地址增长方向相反,且8086为小端存储,低位放到低地址

  • However,CPU如何知道一段内存空间被当作栈使用的捏?

    moreover,执行push和pop的时候,如何知道哪个单元是栈顶单元?

    • 栈段寄存器SS:存放栈顶的段地址

    • 栈顶指针寄存器SP:存放栈顶的偏移地址

    • 任意时刻,SS:SP指向栈顶指针

  • push ax 时发生了啥

    • SP = SP - 2
    • 将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶

    这里一开始有个疑惑,可能是来自于最早开始学栈的时候,拿一个框子举例子,先放进去一本书,再放进去一本书,书越堆越高,让我会有种误解,越往上去地址越高,

    但是栈地址增加的方向和内存单元地址增长方向是相反滴! 记住这一点就ok啦

    push 就是栈地址增加,那么就是内存地址减少 ,所以SP是减

  • pop ax时又发生了啥

    pop是栈地址减少,那么就是内存地址增加,所以SP是加

    • 将SS:SP指向的内存单元处的数据送入ax中
    • SP=SP+2, SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶

debug验证

实现了AX和BX的数据交换

栈顶超界问题

  • 问题来了,如何保证在入栈、出栈时,栈顶不超出栈空间?
    • 哦莫,得编程时自己小心

在这里插入图片描述

栈的小结

  • push、pop 实质上就是一种内存传送指令,可以在寄存器和内存 之间传送数据,与mov指令不同的是,push和pop指令访问的内 存单元的地址不是在指令中给出的,而是由SS:SP指出的。

  • 执行push和pop指令时,SP 中的内容自动改变

  • 8086CPU提供的栈操作机制:

    • 在SS,SP中存放栈顶的段地址和偏移地址,入栈和出栈指 令根据SS:SP指示的地址,按照栈的方式访问内存单元。
    • push指令的执行步骤:
      • SP=SP-2
      • 向SS:SP指向的字单元中送入数据
    • pop指令的执行步骤:
      • 从SS:SP指向的字单元中读取数据
      • SP=SP+2。

0305 关于”段“的总结

  • 编程时,可以根据需要一组内存单元定义为一个段。

  • 可以将起始地址为16的倍数,长度为 N(N ≤64K )的一组地址连续的内存单元,定义为一个段。

    • 物理地址=段地址×16+偏移地址
    • 段的最大长度为64K
  • 将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元——在程序中可以完全由程序员安排

三种段

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

综合示例:按要求设置段

mov bx,1000H
mov ds,bx
mov bx,1001H
mov ss,ax
mov sp,10H
mov ax,[0]
mov bx,[2]
push ax
push bx
pop ax
pop bx
mov [0],ax
mov [2],bx

debug演示

  • 用a写入指令,用u查看

综合示例:三个段地址可以一样

image-20221201193330280

mov bx,1000H
mov ds,bx
mov bx,1001H
mov ss,ax
mov sp,10H
mov ax,[0]
mov bx,[2]
push ax
push bx
pop ax
pop bx
mov [0],ax
mov [2],bx

写入指令

执行指令

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

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

相关文章

pytorch模型网页部署——Flask

一、Flask用法 Flask是python的轻量级web框架,可用来做简单的模型部署。Flask的基本用法如下: step1:定义Flask类的对象,即创建一个基于Flask的服务器 step2:定义公开的路由及路由对应的调用函数 step3&#xff1a…

分享新零售系统商城小程序开发制作功能介绍_商城小程序开发好处

小编主要专注于新零售系统开发商城的领域,新零售系统开发商业模式有哪些: ① 多种销售模式:邀请有奖、销售业绩奖、团队业绩奖、区域分红,分销模式等。 ② 团队协作功能:立即邀约分销模式,清楚搜索直属代…

大型ERP生产制造管理系统源码

🍓🍓【淘源码】:一个专业提供高品质源码免费下载的资源共享平台🍓🍓 👇👇👇以下是博主整理的淘源码网站内大家都比较感兴趣的一些源码,需要源码学习的朋友可以私信博主哦…

Exception | ShardingSphere | ShardingSphere引发的IndexOutOfBoundsException

ShardingSphere引发的IndexOutOfBoundsException一、异常二、 原因三、解决方法四、总结一、异常 ### Error querying database. Cause: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 ### The error may exist in file [D:\JetBrains\Idea\workspace\zohe\bjxz\ru…

N-gram和NNLM语言模型

背景: one-hot:缺点:1.高维稀疏,2.不能体现句子中词的重要性,3.不能体现词与词之间的关系。 embedding:1.解决了高维稀疏 tf-idf:2.解决了one-hot中不能体现句子中词的重要性这一特点。 语言模型:3.解决不能…

【20221201】【每日一题】划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。 注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。 返回一个表示每个字符串片段的长度的列表。 思路&…

协程Part1-boost.Coroutine.md

首先,在计算机科学中 routine 被定义为一系列的操作,多个 routine 的执行形成一个父子关系,并且子 routine 一定会在父 routine 结束前结束,也就是一个个的函数执行和嵌套执行形成了父子关系。 coroutine 也是广义上的 routine&a…

网页JS自动化脚本(五)修改文字元素的内容和大小

今天的网页打开全是灰色的,顺便缅怀一下伟人,那么我我们今天定位换成按钮文字 window.onloadfunction(){var theElementdocument.querySelector("input[typesubmit]");theElement.value"爱我中华";theElement.style"font-size:25px"; }这一次的…

提分必练!中创教育PMP全真模拟题分享来喽

湖南中创教育每日五题分享来啦,“日日行,不怕千万里;常常做,不怕千万事。”,每日五题我们练起来! 1、一个项目正在实行敏捷方法,在迭代过程中,团队成员互相合作,解决了一…

【机器学习】核函数

核方法 核技巧 非线性分类问题是指通过利用非线性模型才能很好地进行分类的问题。如图 111 所示,“●”表示正样本,“”表示负样本,显然无法用直线(线性模型)将正负样本正确分开,但是可以用一条椭圆曲线&…

记一次大事务优化历程(短信发送)

问题背景 短信服务数据库连接数告警,grafana查看数据库连接池被打满。 问题分析 在这段时间内,通过链路分析,发现最终调用第三方短信发送服务偶然耗时过长,分析了原有发送逻辑的代码,该实现在入口send处加了事务&am…

leetcode4. 寻找两个正序数组的中位数python_二分查找和递归(困难)

题目 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log (mn)) 。 示例 1: 输入:nums1 [1,3], nums2 [2] 输出:2.00000 解释…

第二证券|疫情扰动叠加需求不足,11月制造业PMI回落至48%

国家统计局周三称,11月,受国内疫情点多面广频发,世界环境更趋复杂严峻等多重要素影响,我国制造业收购经理人指数(PMI)较上月回落1.2个百分点至48.0%。制造业PMI接连两个月低于临界点,制造业下行…

第4季2:并口、MIPI、LVDS的简介

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。 一、并口的简介 1、并口的含义 并口的含义,可以从AR0130或OV9712的原理图中形象地理解。 如下图所示,AR0130采用12bit的并口向SoC传输图像数据信息,而SoC和AR0130…

b站黑马JavaScript的Ajax案例代码——评论列表案例

目标效果: 1.在表单界面输入评论人和内容,点击发表评论按钮,可以在页面下面看到自己刚刚输入的内容 2.发表评论成功之后,用DOM对象的reset方法:重置表单为其默认值 e.g.1初始状态:【下面的评论内容会因为…

STC 51单片机48——数码管显示外部中断次数

#include<reg52.h> #include<intrins.h> #include "math.h" #define uchar unsigned char #define uint unsigned int #define ulong unsigned long //共阴字形码表【实验】数码管实验时&#xff0c;一定要将点阵模块跳针放到VCC上&#xff01;&…

【C语言】哈夫曼树,再来一次解剖

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录一、定义结构1.1 定义结点权值的数据类型1.2 定义单个结点信息1.3 字符指针数组中存储的元素类…

C++ Reference: Standard C++ Library reference: Containers: list: list: list

C官网参考链接&#xff1a;https://cplusplus.com/reference/list/list/list/ 公有成员函数 <list> std::list::list C98 默认构造函数 (1) explicit list (const allocator_type& alloc allocator_type()); 填充构造函数 (2) explicit list (size_type n,…

将整个网站变为黑白色

目录 效果&#xff1a; 代码&#xff1a; 兼容性写法&#xff1a; 原理&#xff1a; 效果&#xff1a; ps&#xff1a;实测淘宝也是用的这种方式&#xff0c;有兴趣可以去看看 代码&#xff1a; 使用方式就是找到根标签&#xff0c;将里面的两行代码放进去即可 html {filte…

手写Redux(二):实现React-redux

在React中&#xff0c;组件和组件之间通过props传递数据的规范&#xff0c;极大地增强了组件之间的耦合性&#xff0c;而context类似全局变量一样&#xff0c;里面的数据能被随意接触就能被随意修改&#xff0c;每个组件都能够改context里面的内容会导致程序的运行不可预料。 …