day3 ARM

news2024/12/22 20:55:01

【昨日作业】

.text .global start _start: mov r0,#0 @存放sum mov r1,#1 @存放相加的数值 loop: cmp r1,#100 bhi wh add r0,r0,r1 add r1,r1,#1 b loop wh: b wh .end

【内存读写指令】

通过内存读写指令可以实现向内存中写入指定数据或者读取指定内存地址的数据

c语言内存访问方式是通过指针实现 int a=10; int *p=&a; //从内存中获取a的数值 int b= *p; //向内存中写 *p=100;

关于调试时如何查看内存数据:

关于可用内存查看:

1.单寄存器内存读写指令

将一个寄存器中的数值写入到内存,或者从内存中读取数据放在某一个指定寄存器中

1.1 指令码和功能

1.向内存中写: str{条件码} 目标寄存器,[目标地址]:将目标寄存器的4字节数值写入到目标地址为首地址的空间中 strh{条件码} 目标寄存器,[目标地址]:将目标寄存器的2字节数值写入到目标地址为首地址的空间中 strb{条件码} 目标寄存器,[目标地址]:将目标寄存器的1字节数值写入到目标地址为首地址的空间中 2.从内存中读: ldr{条件码} 目标寄存器,[目标地址]:从目标地址为首地址的空间中读取4字节数据存放在目标寄存器中 ldrh{条件码} 目标寄存器 ,[目标地址]:从目标地址为首地址的空间中读取2字节数据存放在目标寄存器中 ldrb{条件码} 目标寄存器 ,[目标地址]:从目标地址为首地址的空间中读取1字节数据存放在目标寄存器中

1.2 示例

.text .global start _start: mov r0,#0XFFFFFFFE mov r1,#0X40000000 @R1保存内存地址 @将r0的值写入到r1对应的地址空间 str r0,[r1] @从r1对应的地址空间中读取数据保存在r2中 ldr r2,[r1] wh: b wh .end

1.3 单寄存器内存索引方式

前索引方式

str{条件码} 目标寄存器,[目标地址,#立即数] //将目标寄存器的数据保存在目标地址+8为起始地址的内存中 ldr{条件码} 目标寄存器,[目标地址,#立即数] //从目标地址+8为起始地址的内存中读取数据保存在目标寄存器

后索引方式

str{条件码} 目标寄存器,[目标地址],#立即数 //将目标寄存器的数据保存在目标地址为起始地址的内存中,接着目标地址自加立即数大小 ldr{条件码} 目标寄存器,[目标地址],#立即数 //从目标地址为起始地址的内存中读取数据保存在目标寄存器,接着目标地址自加立即数大小

自动索引方式

str{条件码} 目标寄存器,[目标地址,#立即数]! //将目标寄存器的数据保存在目标地址+立即数为起始地址的内存中,接着目标地址自加立即数大小 ldr{条件码} 目标寄存器,[目标地址,#立即数]! //从目标地址+立即数大小为起始地址的内存中读取数据保存在目标寄存器,接着目标地址自加立即数大小

2.批量寄存器的内存读写方式

将多个寄存器的数据存放在内存中以及从内存中取出数据保存在多个寄存器中

2.1 指令码以及格式

向内存写: stm 目标地址,{目标寄存器列表} 将列表中各个寄存器的数值保存在目标地址对应的地址空间中 从内存中读取 ldm 目标地址,{目标寄存器列表} 从目标地址对应的地址空间中拿数据保存到寄存器列表中各个寄存器中 注意: 1.寄存器列表中每一个寄存器之间用','分隔,如果寄存器列表中寄存器的编号连续,那么可以用-表示一定范围内的 寄存器,比如 {r1-r5} 2.无论寄存器列表中的寄存器表现形式如何,在存取数据时始终是小编号寄存器对应低地址

2.2 示例

.text .global start _start: mov r0,#0X40000000 mov r1,#1 mov r2,#2 mov r3,#3 mov r4,#4 mov r5,#5 @向内存中写 @stm r0,{r2,r1,r4,r3,r5} stm r0,{r1-r5} @从内存中读取数据 ldm r0,{r6-r10} wh: b wh .end

2.3 批量寄存器的地址增长方式

每次向寄存器保存的地址对应的地址空间中写入一个数据,这个寄存器保存的地址会发生相应的增长变化,这就是批量寄存器的地址增长方式

.text  
.global start 
            

_start:
   mov r0,#0X40000000
   mov r1,#1
   mov r2,#2
   mov r3,#3
   mov r4,#4
   mov r5,#5
   @向内存中写
   stm r0!,{r1-r5}
   
wh: 
    b wh  
    
.end 

内存读写命令后加ia后缀

先向r0数值为起始地址的内存空间中保存一个数据,然后r0数值往高地址方向增长

内存读写命令后加ib后缀

先r0数值往高地址方向增长,然后向r0数值为起始地址的内存空间中保存一个数据

内存读写命令后加da后缀

先向r0数值为起始地址的内存空间中保存一个数据,然后r0数值往低地址方向增长

内存读写命令后加db后缀

先r0数值往低地址方向增长,然后向r0数值为起始地址的内存空间中保存一个数据

3.栈内存的读写

栈指针寄存器:SP/R13 保存栈顶的地址

栈:本质上就是一段内存。在内存中选取一段内存作为栈内存,可以用于保存临时数据。

3.1 栈的类型

增栈:每次压栈结束,SP保存的栈顶地址往高地址方向增栈 减栈:每次压栈结束,SP保存的栈顶地址往低地址方向增栈 空栈:压栈结束后,SP保存的栈顶空间中没有有效数据 满栈:压栈结束后,SP保存的栈顶空间中有有效数据 空增栈(EA)/空减栈(ED)/满增栈(FA)/满减栈(FD) 当前ARM处理器使用的是哪种栈?满减栈

3.2 满减栈压栈出栈操作

1. push {寄存器列表}@压栈 pop {寄存器列表}@出栈 2. .text .global start _start: @初始化栈 ldr 

1.
push {寄存器列表}@压栈
pop {寄存器列表}@出栈

2.   
.text  
.global start 
            

_start:
@初始化栈
   ldr SP,=0X40000020
   mov r1,#1
   mov r2,#2
   mov r3,#3
   mov r4,#4
   mov r5,#5
   @压栈
   stmdb sp!,{r1-r5}
   @出栈
   ldmia sp!,{r6-r10}
wh: 
    b wh  
    
.end 
    
 
 3.
 .text  
.global start 
            

_start:
@初始化栈
   ldr SP,=0X40000020
   mov r1,#1
   mov r2,#2
   mov r3,#3
   mov r4,#4
   mov r5,#5
   @压栈
   stmfd sp!,{r1-r5}
   @出栈
   ldmfd sp!,{r6-r10}
wh: 
    b wh  
    
.end 
    

3.3 栈的应用实例---叶子函数调用过程

当我们在主函数中调用一个函数,被调用的这个函数中没有别的函数调用,那么 这个函数就叫做叶子函数

1.
push {寄存器列表}@压栈
pop {寄存器列表}@出栈

2.   
.text  
.global start 
            

_start:
@初始化栈
   ldr SP,=0X40000020
   mov r1,#1
   mov r2,#2
   mov r3,#3
   mov r4,#4
   mov r5,#5
   @压栈
   stmdb sp!,{r1-r5}
   @出栈
   ldmia sp!,{r6-r10}
wh: 
    b wh  
    
.end 
    
 
 3.
 .text  
.global start 
            

_start:
@初始化栈
   ldr SP,=0X40000020
   mov r1,#1
   mov r2,#2
   mov r3,#3
   mov r4,#4
   mov r5,#5
   @压栈
   stmfd sp!,{r1-r5}
   @出栈
   ldmfd sp!,{r6-r10}
wh: 
    b wh  
    
.end 
    

3.4 栈的应用实例---非叶子函数调用过程

当我们在主函数中调用一个函数,被调用的这个函数中存在别的函数调用,那么 这个函数就叫做非叶子函数

            

_start:
@初始化栈
   ldr SP,=0X40000020
   b main
main:
    mov r1,#3
    mov r2,#4
    bl fun1
    add r3,r1,r2
    b main
fun1:
@压栈保护现场
    stmfd sp!,{r1,r2,lr}
    mov r1,#7
    mov r2,#9
    bl fun2
    sub r4,r2,r1
    @出栈恢复现场
    ldmfd sp!,{r1,r2,lr}
    mov pc,lr   @程序返回
fun2:
    stmfd sp!,{r1,r2}
    mov r1,#4
    mov r2,#8
    mul r4,r2,r1
    @出栈恢复现场
    ldmfd sp!,{r1,r2}
    mov pc,lr   @程序返回
    
.end 

【程序状态寄存器传输指令】

指令的作用实现CPSR寄存器数值的读取以及数值的修改

1.指令码以及格式

格式: msr CPSR,第一操作数 将第一操作数的数值写入到CPSR寄存器中 mrs 目标寄存器,CPSR 读取CPSR数值保存到目标寄存器中

2.实例

.text  
.global _start 
            

_start:
    mrs r1,CPSR  @读取CPSR数值
    @切换到USR模式,取消FIQ和IRQ禁止
    msr CPSR,#0x10
    

.end 
    
 注意:user模式是ARM处理器工作模式中唯一的非特权模式,这种模式下无法通过手动修改CPSR数值切换到异常模式,只要发生对应的异常后才可以切换到异常模式

【软中断指令】

swi 中断号
注意:中断号是一个由24位二进制数组成的一个整数,用于区分不同的中断

1.概念

软中断是从软件层次上模拟的硬件中断,原理和硬件中断一样。软中断触发之后CPU进行异常模式的切换(SVC),紧接着执行软中断对应的异常处理程序。

2.软中断指令码以及使用

swi 中断号 注意:中断号是一个由24位二进制数组成的一个整数,用于区分不同的中断

3.异常处理过程分析

3.1 异常模式和异常源的对应关系

5种异常模式对应7种异常源

异常模式

异常源

解释

FIQ

FIQ类型异常源

一些硬件发生了FIQ异常事件进入FIQ模型

IRQ

IRQ类型异常源

一些硬件发生了IRQ异常事件进入IRQ模型

SVC

复位信号

按键复位/上电复位时产生

swi软中断指令

执行swi指令

undef

未定义异常源

译码器在翻译指令时,遇到无法翻译的指令,指令未定义

abort

data abort

取数据发生异常时

prefetch abort

取指令发生异常时

3.2 异常的处理过程分析(面试重点)

***********异常的处理过程********
当一个异常源产生之后CPU会进行一些工作用于程序的跳转以及异常模式的切换,这个过程分为四大步三小步
1.保存发生异常之前的CPSR的值到对应异常模式下的SPSR寄存器中
2.修改CPSR的数值
    2.1 根据实际情况设置FIQ和IRQ中断禁止  CPSR[7:6]
    2.2 修改处理器工作状态为ARM状态  CPSR[5]
    2.3 修改处理器的工作模式为对应的异常模式 CPSR[4:0]
3.保存主程序的返回地址到对应模式下的LR寄存器中
4.修改PC的值到对应异常模式下的异常向量表中

*********处理完异常之后现场的恢复过程*********
1.恢复CPSR寄存器的值为未发生异常之前的状态
2.修改PC的值为未发生异常之前的下一条指令地址   PC=LR

3.3 异常向量

1.异常向量表是内存空间中的一段内存。这段内存占据了32字节。这个内存被平分为8等份,一份是4字节。每一份内存对应一种异常源,有一份保留,在异常向量表内存里存放的是当前异常源对应的异常处理程序的跳转指令。当发生异常之后,CPU会修改PC的值为对应异常源在异常向量中的位置,执行这个位置中的跳转指令,去处理异常处理程序。
2.每一种异常源在异常向量表中的位置是固定,不能随便修改
3.只要设置了异常向量表的基地址,就可以根据不同异常在一场向量表中的位置找到对应异常的跳转指令

4.软中断异常处理实例

.text  
.global _start 
            

_start:
    @初始化异常向量表
    b main
    b .
    b do_swi
    b .
    b .
    b .
    b .
    b .
    
main:
@初始化栈
    mov sp,#0X40000020
    @切换到USER模式
    MSR CPSR,#0X10
    MOV R1,#1
    MOV R2,#2
    @触发软中断
    SWI 1
    add r3,r1,r2
    b main

do_swi:@异常处理
@保护现场
    stmfd sp!,{r1,r2,lr}
    mov r1,#3
    mov r2,#4
    mul r4,r1,r2
    @恢复现场
    ldmfd sp!,{r1,r2,pc}^  @  ^的作用是修改PC的值的同时将SPSR的值赋值给CPSR
.end 
    

【混合编程】

1.混合编程的意义

所谓的混合编程就是c语言资源和汇编资源的相互调用

  • 一般工程会有汇编启动程序,启动程序完成堆栈的相关初始化,完毕之后才跳转到c语言的main函数
  • c语言中几乎不可以直接操作寄存器,但是有些特定场景下需要c中操作寄存器,这时候就需要c语言中嵌套汇编的语法

2.概述

所谓的混合编程就是c语言资源和汇编资源的相互调用

  • 一般工程会有汇编启动程序,启动程序完成堆栈的相关初始化,完毕之后才跳转到c语言的main函数
  • c语言中几乎不可以直接操作寄存器,但是有些特定场景下需要c中操作寄存器,这时候就需要c语言中嵌套汇编的语法

3.汇编调用C语言的函数

将C语言的函数当作汇编的标签使用

*****汇编文件**********
.text    
.global _start  
            
_start: 

    @ 1. 初始化栈指针,C代码运行必须有栈
    ldr sp, =0x40000820
    
    @ 2. 汇编调用c函数 
    @ 2.1 给C的函数传递实参值
    mov r0, #3   @ a = 3
    mov r1, #4   @ b = 4
    mov r2, #5   @ c = 5
    mov r3, #6   @ d = 6
    
    @ 2.2 汇编调用c的函数
    bl add_func
    
    @ 2.3 函数的返回通过r0返回,查看r0寄存器中的值

loop:   
        b loop  

.end

**********c文件********************
// c代码的函数是一个全局的函数
int add_func(int a, int b, int c, int d) 
{
 return (a+b+c+d);
}

4.c语言调用汇编标签

将汇编的标签当作c语言的函数

********起始汇编文件**********
.text    
.globl _start  
            
_start: 

    @ 1. 初始化栈指针,C代码运行必须有栈
    ldr sp, =0x40000820
    
    @ 2. 汇编调用c,跳转到main函数
    b main
.end

********c文件************
// 使用extern对函数进行声明
extern int add_func(int a, int b, int c, int d);

int sum = 0;
int main()
{
 // 在c代码中调用汇编代码
 sum = add_func(1,2,3,4);
 while(1);
 return 0;
}

********汇编文件**********
.text 
.global add_func  @ 将add_func函数声明为全局
    
    add_func:
        add r0, r0, r1
        add r0, r0, r2
        add r0, r0, r3
        mov pc, lr
.end

5.c语言内联汇编

在某一些特定的场景下需要在c语言中直接使用汇编的语法,此时需要内联汇编。内联汇编的实现需要通过asm关键字进行修饰

5.1 格式

asm volatile(
    "汇编指令模板\n\t"     //"\n\t"表示一条指令的结束
    .....
    :输出列表  //指令结果的输出值
    :输入列表  //指令的数据输入
    :破坏列表  //破坏列表指定我们当前可用的寄存器
);

5.2 实例

********汇编启动文件*******
.text    
.globl _start  
            
_start: 

    @ 1. 初始化栈指针,C代码运行必须有栈
    ldr sp, =0x40000820
    
    @ 2. 汇编调用c,跳转到main函数
    b main
.end
    
 
 **********c语言文件***********
 // 内联汇编 
int add_func2(int a, int b, int c, int d)
{
 int sum = 0;
 // 使用汇编实现求和
 asm volatile(  "add r0, r0, r1\n\t"  "add r0, r0, r2\n\t"  "add r0, r0, r3\n\t"  :"=r"(sum)  :"r"(a),"r"(b),"r"(c),"r"(d)  :"memory" );
 return sum;
}
 //"=r"(sum)表示输出从寄存器中放到变量sum中
// "r"(a) 指定输入从变量a中获取放到通用寄存器
 //"memory"声明使用内存

// 使用extern对函数进行声明
extern int add_func(int a, int b, int c, int d);

int sum = 0;
int main()
{
 // 调用内联汇编的函数 
 sum = add_func2(5,6,7,8);
 
 // 在c代码中调用汇编代码
 sum = add_func(1,2,3,4);
 while(1);
 return 0;
}
 *********汇编文件*************
 .text 
.global add_func  @ 将add_func函数声明为全局
    
add_func:
        add r0, r0, r1
        add r0, r0, r2
        add r0, r0, r3
        mov pc, lr
.end
    

【环境安装】

1.在ubuntu中安装交叉编译工具链

交叉开发:PC端编写代码,开发板上运行代码,这种开发方式叫做交叉开发。 本地开发:PC端编写代码,PC端运行代码,这种开发方式叫做本地开发。

安装交叉编译工具链,需要安装兼容32位库,ubuntu一定需要联网
    sudo apt-get install lib32z1
1. 在ubuntu的家目录下创建toolchain目录
    cd ~
    mkdir toolchain

2. 拷贝交叉编译工具链的压缩包到ubuntu的~/toolchain目录下
    交叉编译工具链的压缩包的路径:
        STM32MP157-学生资料\02_开发工具\02.5_ubuntu版本交叉编译工具链\
        gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf.tar.xz

3. 使用tar命令进行解压缩
    tar -vxf gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf.tar.xz

4. 解压缩成功之后得到一个gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf,修改文件加额名字
    mv gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf gcc-7.5.0

5. 交叉编译工具链的路径为:
    ~/toolchain/gcc-7.5.0/bin

6. 修改PATH环境变量,将交叉编译工具链的路径添加到PATH环境变量中
    /etc/bash.bashrc   --》 对所有的用户都有效
    /etc/profile       --》 对所有的用户都有效
    /etc/environment   --》 对所有的用户都有效
    ~/.bashrc          --》 对当前的用户都有效
    
    修改/etc/bash.bashrc文件,在这个文件的最后一行添加以下内容:
    export PATH=$PATH:/home/ubuntu/toolchain/gcc-7.5.0/bin/
                      修改为自己的交叉编译工具链的路径

7. 使修改后的环境变量立即生效
    source /etc/bash.bashrc

8. 测试是否安装成功 
    arm-linux-gnueabihf-gcc -v   ---> 查看交叉编译工具链的版本号
    
    打印一些结果表示安装成功:
    gcc version 7.5.0 (Linaro GCC 7.5-2019.12) 

9. 安装一个32位软件的兼容库
    9.1 ubuntu必须可以联网
    9.2 配置源 
        打开源的配置文件/etc/apt/sources.list,将https修改为http
    9.3. 更新源
        sudo apt-get update
    9.4 安装lib32z1库
        sudo apt-get install lib32z1

2.安装securetCRT串口工具

1. securetCRT软件包的路径: STM32MP157-学生资料\02_开发工具\02.1_串口工具\securetCRT\scrt-sfx-9.0.0.2430 2. 安装步骤参考《SCRT804安装说明文档.docx》安装文档。

3.M4开发环境搭建

3.1 安装PACK包


【1】安装pack包

参考路径:D:\STM32MP157-学生资料\STM32MP157-学生资料\03_M4资料\03-软件工具\MDK Keil

参考文档:keil安装教程.docx

【2】成功现象

3.2 安装STM32CubMX软件


参考路径:D:\STM32MP157-学生资料\03_M4资料\03-软件工具\STM32CubeMx

参考文档:安装stm32cubeMX软件教程.docx

【1】安装jre-8u271-windows-x64.exe,以管理员身份运行,不能出现中文路径

【2】安装SetupSTM32CubeMX-6.3.0-Win.exe,以管理员身份运行,不能出现中文路径

【3】导入STM32MP1包(可以先不做)

1、打开cubmx软件

2.点击”Help--->manager Embedded software packages”,弹出如下图工作框

【4】导入en.STM32Cube_FW_MP1_V1.4.0_v1.4.0.zip,这个包不需要解压

【5】安装成功的现象

3.3 安装ST-LINK驱动


参考路径:D:\STM32MP157-学生资料\03_M4资料\03-软件工具\ST LINK驱动及教程

参考文档:STLink驱动的安装和固件升级教程.docx

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

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

相关文章

【Python3】【力扣题】231. 2 的幂

【力扣题】题目描述&#xff1a; 此题&#xff1a;n为整数&#xff08;32位有符号整数&#xff09;&#xff0c;x为整数。 2 的幂次方都大于0。若幂为负数&#xff0c;则0<n<1&#xff0c;n不为整数。 因此&#xff0c;n为正整数&#xff0c;x为0和正整数。 若二进制表示…

学为贵雅思写作备考

准确通顺&#xff0c;言之有物 两次读不懂&#xff0c;6分以下&#xff0c; 6分没有印象&#xff0c;味同嚼蜡&#xff0c;但是没错&#xff08;书面语过关&#xff09; 英语比较过关 8-9分&#xff0c;很有见地 6-7单个的句子读得懂&#xff0c;前后是贯通的、逻辑是通顺…

决策式AI与生成式AI

人工智能中深度学习&#xff0c;是一种受人脑的生物神经网络机制启发&#xff0c;并模仿人脑来解释、处理数据的机器学习技术&#xff0c;它能自动对数据进行特征提取、识别、决策和生成。它可以从不同的维度进行划分&#xff0c;如果按模型的特点来划分可分为决策式AI和生成式…

open clip论文阅读摘要

看下open clip论文 Learning Transferable Visual Models From Natural Language Supervision These results suggest that the aggregate supervision accessible to modern pre-training methods within web-scale collections of text surpasses that of high-quality crowd…

我的AIGC部署实践02

我的AIGC部署实践02 上次的教程我们实现了在趋势云平台上创建项目并运行对应的代码。虽然有比较好的结果&#xff0c;不过很多时候我们往往需要根据自己的需要更改代码&#xff0c;那么代码运行及部署的流程是怎么样的呢&#xff1f;让我们继续往下看吧。 1.学习准备 官方代码…

测试工程师面试攻略:教你如何描述项目经验

俗话说的好&#xff0c;知己知彼百战百胜。项目经验说的好不好&#xff0c;直接决定了你值多少钱。满满的干货&#xff0c;先三连再耐心看完。 去面试之前&#xff0c;建议大家把简历写得从业经历和项目经验熟练的背下来&#xff0c;能说出项目经验里的详细的测试情况最好。 一…

工程(十三)——基于激光视觉的SLAM三维重建

博主创建了一个科研互助群Q&#xff1a;772356582&#xff0c;欢迎大家加入讨论。这是一个科研互助群&#xff0c;主要围绕机器人&#xff0c;无人驾驶&#xff0c;无人机方面的感知定位&#xff0c;决策规划&#xff0c;以及论文发表经验&#xff0c;以方便大家很好很快的科研…

了解企业邮箱的外观和功能特点

企业邮箱是什么样子的&#xff1f;企业邮箱不是单一产品&#xff0c;而是由一系列电子邮件服务组成的生态系统。这些服务包括但不限于邮件服务器、客户端、安全解决方案等。这些服务共同构成了企业邮箱的基础设施。 在外观上&#xff0c;企业邮箱和个人邮箱没有太大区别。用户通…

查询优化器:RBO与CBO

SQL查询优化器 1、数据库系统发展简史2、SQL查询优化器3、查询优化器分类4、查询优化器执行过程5、CBO框架Calcite简介 1、数据库系统发展简史 数据库系统诞生于20世纪60年代中期&#xff0c;至今已有近50多年的历史&#xff0c;其发展经历了三代演变&#xff0c;造就了四位图灵…

6个机器学习可解释性框架

1、SHAP SHapley Additive explanation (SHAP)是一种解释任何机器学习模型输出的博弈论方法。它利用博弈论中的经典Shapley值及其相关扩展将最优信贷分配与局部解释联系起来. 举例&#xff1a;基于随机森林模型的心脏病患者预测分类 数据集中每个特征对模型预测的贡献由Shap…

Vscode禁止插件自动更新

由于电脑的vscode版本不是很新。2022.10月份的版本1.7.2&#xff0c;电脑vscode的python插件装的也是2022年4月份的某个版本&#xff0c;但插件经常自动更新&#xff0c;导致python代码无法Debug,解决办法&#xff1a; 点设置&#xff0c;搜autoUpdate, 把红色框选成无

浅析刚入门Python初学者的注意事项

文章目录 一、注意你的Python版本1.print()函数2.raw_input()与input()3.比较符号&#xff0c;使用!替换<>4.repr函数5.exec()函数 二、新手常遇到的问题1、如何写多行程序&#xff1f;2、如何执行.py文件&#xff1f;3、and&#xff0c;or&#xff0c;not4、True和False…

HTML和CSS入门学习

目录 一.HTML 二.CSS 1.CSS作用&#xff1a;美化页面 2.CSS语法 【1】CSS语法规范 【2】如何插入样式表 3.CSS选择器 4.CSS设置样式属性--设置html各种标签的属性 【1】文本属性--设置整段文字的样式 【2】字体属性--设置单个字的样式 【3】链接属性--设置链接的样式…

【Qt绘制小猪】以建造者模式绘制小猪

效果 学以致用&#xff0c;使用设计模式之建造者模式绘制小猪。 代码 接口&#xff1a;申明绘制的步骤 PigBuilder.h #ifndef PIGBUILDER_H #define PIGBUILDER_H#include <QObject> #include <QPainter>class PigBuilder : public QObject {Q_OBJECT public:ex…

行情分析——加密货币市场大盘走势(11.7)

大饼昨日下跌过后开始有回调的迹象&#xff0c;现在还是在做指标修复&#xff0c;大饼的策略保持逢低做多。稳健的依然是不碰&#xff0c;目前涨不上去&#xff0c;跌不下来。 以太昨天给的策略&#xff0c;依然有效&#xff0c;现在以太坊开始回调。 目前来看&#xff0c;回踩…

电动汽车充放电V2G模型

威♥关注“电击小子程高兴的MATLAB小屋”获取更多资料 1主要内容 本程序主要建立电动汽车充放电V2G模型&#xff0c;采用粒子群算法&#xff0c;在保证电动汽车用户出行需求的前提下&#xff0c;为了使工作区域电动汽车尽可能多的消纳供给商场基础负荷剩余的光伏电量&#xf…

【vue3/echarts】vue3中使用echarts/饼图/双轴双数据柱状图

npm下载echarts 引入使用 <script> import Box from "/components/box.vue"; import { onMounted } from vue; import { init } from echarts; export default {components: {Box: Box},setup() {onMounted(() > {// 饼图const charEle document.getElem…

flink的AggregateFunction,merge方法作用范围

背景 AggregateFunction接口是我们经常用的窗口聚合函数&#xff0c;其中有一个merge方法&#xff0c;我们一般情况下也是实现了的&#xff0c;但是你知道吗&#xff0c;其实这个方法只有在你使用会话窗口需要进行窗口合并的时候才需要实现 AggregateFunction.merge方法调用时…

Redis 扩展 RedisBloom 插件,解决缓存击穿、穿透

文章目录 一、概述二、编译准备2.1 升级 make2.2 安装 Python3 三、编译 RedisBloom四、测试 RedisBloom五、应用场景5.1 缓存击穿5.2 缓存穿透5.3 原理总结 六、存在的问题 如果您对Redis的了解不够深入请关注本栏目&#xff0c;本栏目包括Redis安装&#xff0c;Redis配置文件…

计算机基础知识45

JS的RegExp对象(正则) text: 正则校验数据 # T/F match: 匹配 # (3) [s, s, s] //定义 var reg1 new RegExp("^[a-zA-Z][a-zA-Z0-9]{5,11}"); var reg2 /^[a-zA-Z][a-zA-Z0-9]{5,9}$/; //正则校验数据 var res reg1.test(jason666); console.log(res…