KEIL 编译器高级使用与调试技巧【一】 手工编译、编译选项、预处理分析

article/2025/7/29 7:32:23

一、手工编译bin文件

1.1 KEIL 自带的编译组件

ARM v6编译器(Arm Compiler for Embedded)包含以下几个工具:

armclang

编译器和汇编器,可对 C、C++ 汇编文件进行编译和汇编

armlink

链接器,用于将目标文件和库文件进行链接,形成可执行文件。

fromelf

文件转换工具,可将可执行文件转换成二进制格式、HEX 格式,也可生成反汇编文件,包含代码、数据大小信息的文件

armar

归档工具,可将多个 ELF 格式的目标文件进行归档或者集合成库文件,从而避免每次都重新编译或者公开源码。

1.2 手工编译过程

  1. 使用编辑器编写 C/C++ 源文件,使用 armclang 编译器进行编译,生成相应的目标文件。
  2. 使用编辑器编写汇编文件,使用 armclang 进行汇编,生成对应的目标文件。
  3. 使用 armlink 将所有的目标文件和库一起链接,形成最终的可执行文件(ELF格式)。
  4. 如需要,可使用 fromelf 进行文件转换,生成二进制文件格式,或者显示代码和数据的使用信息。

1.3 手动编译开始

1.3.1 配置环境变量

首先确保环境变量包括 keil 下的 armclang 目录,这里找自己的 keil 安装目录下的 ARMCLANG 即可。

1.3.2 新建目录与文件

新建两个文件,目录结构与内容如下:

 hello.c 内容如下:

int main (void) {for (;;) {}return 0;
}

start.c 内容如下: 

int main (void);void start (void) {main();
}

1.3.3 执行编译命令

之后在这个目录执行:

armclang --target=arm-arm-none-eabi -mcpu=cortex-m3 -c .\start.c
armclang --target=arm-arm-none-eabi -mcpu=cortex-m3 -c .\hello.c
armlink start.o hello.o -o hello.axf

上述代码工作流程如下: 

  • 将 start.c 编译为目标代码,并使用默认名称 start.o 保存。
  • 将 hello.c 编译为目标代码,并使用默认名称 hello.o 保存。
  • 链接目标文件 start.o 和 hello.o,生成名为 hello.axf 的可执行文件。

之后该目录下就多了 hello.axf、hello.o 和 start.o 三个文件

 

1.3.4 执行编译命令

选项描述

-c

执行编译步骤,但不进行链接。

-x

指定后续源文件的语言,例如 -xc inputfile.s 或 -xc++ inputfile.s。

-std

指定要编译的语言标准,例如 -std=c90,其它可用选项如c99等等。

--target=arch-vendor-os-abi

为选定的执行状态(AArch32 或 AArch64)生成代码,例如 --target=aarch64-arm-none-eabi 或 --target=arm-arm-none-eabi。

-march=name

为指定的架构生成代码,例如 -march=armv8-a 或 -march=armv7-a。

-march=list

显示所选执行状态支持的所有架构列表。

-mcpu=name

为指定的处理器生成代码,例如 -mcpu=cortex-a53、-mcpu=cortex-a57 或 -mcpu=cortex-a15。

-mcpu=list

显示所选执行状态支持的所有处理器列表。

-marm

请求编译器针对仅由32位指令组成的A32指令集生成代码。例如,--target=arm-arm-none-eabi -march=armv7-a -marm。此选项强调性能。

-mthumb

请求编译器针对由16位和32位指令组成的T32指令集生成代码。例如,--target=arm-arm-none-eabi -march=armv8-a -mthumb。此选项强调代码密度。

-mfloat-abi

指定是否使用硬件指令或软件库函数进行浮点运算。

-mfpu

指定目标FPU架构。

-g (armclang)

生成与DWARF 4标准兼容的DWARF调试表。

-e

仅执行预处理步骤。

-o (armclang)

指定输出文件的名称。

-Onum

指定编译源文件时使用的性能优化级别。

-Os

在代码大小与速度之间取得平衡。

-Oz

针对代码大小进行优化。

-S

输出编译器生成的机器代码的反汇编代码。

-###

显示调用编译器和链接器时将使用的选项的诊断输出,但不执行编译或链接步骤。

1.3.5 反汇编输出

可以查看反汇编文件,执行以下命令:

fromelf --text -c hello.axf

至此,编译器就给我们输出了反汇编文件:

PS C:\Users\P793\Desktop\new> fromelf --text -c hello.axf========================================================================** ELF Header InformationFile Name: hello.axfMachine class: ELFCLASS32 (32-bit)Data encoding: ELFDATA2LSB (Little endian)Header version: EV_CURRENT (Current version)Operating System ABI: noneABI Version: 0File Type: ET_EXEC (Executable) (2)Machine: EM_ARM (ARM)Image Entry point: 0x00008001Flags: EF_ARM_HASENTRY + EF_ARM_ABI_FLOAT_SOFT (0x05000202)ARM ELF revision: 5 (ABI version 2)Conforms to Soft float procedure-call standardBuilt withComponent: ARM Compiler 6.16 Tool: armlink [5dfeaa00]Header size: 52 bytes (0x34)Program header entry size: 32 bytes (0x20)Section header entry size: 40 bytes (0x28)Program header entries: 1Section header entries: 9Program header offset: 7728 (0x00001e30)Section header offset: 7760 (0x00001e50)Section header string table index: 8========================================================================** Program header #0 (PT_LOAD) [PF_X + PF_W + PF_R + PF_ARM_ENTRY]Size : 416 bytes (320 bytes in file)Virtual address: 0x00008000 (Alignment 4)========================================================================** Section #1 'ER_RO' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]Size   : 320 bytes (alignment 4)Address: 0x00008000$t!!!main__main0x00008000:    f000f802    ....    BL       __scatterload ; 0x80080x00008004:    f000f82c    ..,.    BL       __rt_entry ; 0x8060!!!scatter__scatterload__scatterload_rt2__scatterload_rt2_thumb_only0x00008008:    a00a        ..      ADR      r0,{pc}+0x2c ; 0x80340x0000800a:    e8900c00    ....    LDM      r0,{r10,r11}0x0000800e:    4482        .D      ADD      r10,r10,r00x00008010:    4483        .D      ADD      r11,r11,r00x00008012:    f1aa0701    ....    SUB      r7,r10,#1__scatterload_null0x00008016:    45da        .E      CMP      r10,r110x00008018:    d101        ..      BNE      0x801e ; __scatterload_null + 80x0000801a:    f000f821    ..!.    BL       __rt_entry ; 0x80600x0000801e:    f2af0e09    ....    ADR      lr,{pc}-7 ; 0x80170x00008022:    e8ba000f    ....    LDM      r10!,{r0-r3}0x00008026:    f0130f01    ....    TST      r3,#10x0000802a:    bf18        ..      IT       NE0x0000802c:    1afb        ..      SUBNE    r3,r7,r30x0000802e:    f0430301    C...    ORR      r3,r3,#10x00008032:    4718        .G      BX       r3$d0x00008034:    000000fc    ....    DCD    2520x00008038:    0000010c    ....    DCD    268$t!!handler_zi__scatterload_zeroinit0x0000803c:    2300        .#      MOVS     r3,#00x0000803e:    2400        .$      MOVS     r4,#00x00008040:    2500        .%      MOVS     r5,#00x00008042:    2600        .&      MOVS     r6,#00x00008044:    3a10        .:      SUBS     r2,r2,#0x100x00008046:    bf28        (.      IT       CS0x00008048:    c178        x.      STMCS    r1!,{r3-r6}0x0000804a:    d8fb        ..      BHI      0x8044 ; __scatterload_zeroinit + 80x0000804c:    0752        R.      LSLS     r2,r2,#290x0000804e:    bf28        (.      IT       CS0x00008050:    c130        0.      STMCS    r1!,{r4,r5}0x00008052:    bf48        H.      IT       MI0x00008054:    600b        .`      STRMI    r3,[r1,#0]0x00008056:    4770        pG      BX       lr.ARM.Collect$$libinit$$00000000__rt_lib_init0x00008058:    b51f        ..      PUSH     {r0-r4,lr}.ARM.Collect$$libinit$$00000002.ARM.Collect$$libinit$$00000004.ARM.Collect$$libinit$$0000000A.ARM.Collect$$libinit$$0000000C.ARM.Collect$$libinit$$0000000E.ARM.Collect$$libinit$$00000011.ARM.Collect$$libinit$$00000013.ARM.Collect$$libinit$$00000015.ARM.Collect$$libinit$$00000017.ARM.Collect$$libinit$$00000019.ARM.Collect$$libinit$$0000001B.ARM.Collect$$libinit$$0000001D.ARM.Collect$$libinit$$0000001F.ARM.Collect$$libinit$$00000021.ARM.Collect$$libinit$$00000023.ARM.Collect$$libinit$$00000025.ARM.Collect$$libinit$$0000002C.ARM.Collect$$libinit$$0000002E.ARM.Collect$$libinit$$00000030.ARM.Collect$$libinit$$00000032.ARM.Collect$$libinit$$00000033__rt_lib_init_alloca_1__rt_lib_init_argv_1__rt_lib_init_atexit_1__rt_lib_init_clock_1__rt_lib_init_cpp_1__rt_lib_init_exceptions_1__rt_lib_init_fp_1__rt_lib_init_fp_trap_1__rt_lib_init_getenv_1__rt_lib_init_heap_1__rt_lib_init_lc_collate_1__rt_lib_init_lc_ctype_1__rt_lib_init_lc_monetary_1__rt_lib_init_lc_numeric_1__rt_lib_init_lc_time_1__rt_lib_init_preinit_1__rt_lib_init_rand_1__rt_lib_init_return__rt_lib_init_signal_1__rt_lib_init_stdio_1__rt_lib_init_user_alloc_10x0000805a:    bd1f        ..      POP      {r0-r4,pc}.ARM.Collect$$libshutdown$$00000000__rt_lib_shutdown0x0000805c:    b510        ..      PUSH     {r4,lr}.ARM.Collect$$libshutdown$$00000002.ARM.Collect$$libshutdown$$00000004.ARM.Collect$$libshutdown$$00000007.ARM.Collect$$libshutdown$$0000000A.ARM.Collect$$libshutdown$$0000000C.ARM.Collect$$libshutdown$$0000000F.ARM.Collect$$libshutdown$$00000010__rt_lib_shutdown_cpp_1__rt_lib_shutdown_fp_trap_1__rt_lib_shutdown_heap_1__rt_lib_shutdown_return__rt_lib_shutdown_signal_1__rt_lib_shutdown_stdio_1__rt_lib_shutdown_user_alloc_10x0000805e:    bd10        ..      POP      {r4,pc}.ARM.Collect$$rtentry$$00000000.ARM.Collect$$rtentry$$00000002.ARM.Collect$$rtentry$$00000004__rt_entry__rt_entry_presh_1__rt_entry_sh0x00008060:    f000f80d    ....    BL       __user_setup_stackheap ; 0x807e0x00008064:    4611        .F      MOV      r1,r2.ARM.Collect$$rtentry$$00000009.ARM.Collect$$rtentry$$0000000A__rt_entry_li__rt_entry_postsh_10x00008066:    f7fffff7    ....    BL       __rt_lib_init ; 0x8058.ARM.Collect$$rtentry$$0000000C.ARM.Collect$$rtentry$$0000000D__rt_entry_main__rt_entry_postli_10x0000806a:    f000f85b    ..[.    BL       main ; 0x81240x0000806e:    f000f82b    ..+.    BL       exit ; 0x80c8.ARM.Collect$$rtexit$$00000000__rt_exit0x00008072:    b403        ..      PUSH     {r0,r1}.ARM.Collect$$rtexit$$00000002.ARM.Collect$$rtexit$$00000003__rt_exit_ls__rt_exit_prels_10x00008074:    f7fffff2    ....    BL       __rt_lib_shutdown ; 0x805c.ARM.Collect$$rtexit$$00000004__rt_exit_exit0x00008078:    bc03        ..      POP      {r0,r1}0x0000807a:    f000f84d    ..M.    BL       _sys_exit ; 0x8118.text__user_setup_stackheap0x0000807e:    4675        uF      MOV      r5,lr0x00008080:    f000f82c    ..,.    BL       __user_libspace ; 0x80dc0x00008084:    46ae        .F      MOV      lr,r50x00008086:    0005        ..      MOVS     r5,r00x00008088:    4669        iF      MOV      r1,sp0x0000808a:    4653        SF      MOV      r3,r100x0000808c:    f0200007     ...    BIC      r0,r0,#70x00008090:    4685        .F      MOV      sp,r00x00008092:    b018        ..      ADD      sp,sp,#0x600x00008094:    b520         .      PUSH     {r5,lr}0x00008096:    f000f825    ..%.    BL       __user_initial_stackheap ; 0x80e40x0000809a:    e8bd4020    .. @    POP      {r5,lr}0x0000809e:    f04f0600    O...    MOV      r6,#00x000080a2:    f04f0700    O...    MOV      r7,#00x000080a6:    f04f0800    O...    MOV      r8,#00x000080aa:    f04f0b00    O...    MOV      r11,#00x000080ae:    46ac        .F      MOV      r12,r50x000080b0:    e8ac09c0    ....    STM      r12!,{r6-r8,r11}0x000080b4:    e8ac09c0    ....    STM      r12!,{r6-r8,r11}0x000080b8:    e8ac09c0    ....    STM      r12!,{r6-r8,r11}0x000080bc:    e8ac09c0    ....    STM      r12!,{r6-r8,r11}0x000080c0:    f0210107    !...    BIC      r1,r1,#70x000080c4:    468d        .F      MOV      sp,r10x000080c6:    4770        pG      BX       lr.textexit0x000080c8:    b510        ..      PUSH     {r4,lr}0x000080ca:    4604        .F      MOV      r4,r00x000080cc:    f3af8000    ....    NOP.W0x000080d0:    4620         F      MOV      r0,r40x000080d2:    e8bd4010    ...@    POP      {r4,lr}0x000080d6:    f7ffbfcc    ....    B.W      __rt_exit ; 0x80720x000080da:    0000        ..      MOVS     r0,r0.text__user_libspace__user_perproc_libspace__user_perthread_libspace0x000080dc:    4800        .H      LDR      r0,[pc,#0] ; [0x80e0] = 0x81400x000080de:    4770        pG      BX       lr$d0x000080e0:    00008140    @...    DCD    33088$t.text__user_initial_stackheap0x000080e4:    b500        ..      PUSH     {lr}0x000080e6:    b085        ..      SUB      sp,sp,#0x140x000080e8:    4669        iF      MOV      r1,sp0x000080ea:    aa01        ..      ADD      r2,sp,#40x000080ec:    600a        .`      STR      r2,[r1,#0]0x000080ee:    f04f0016    O...    MOV      r0,#0x160x000080f2:    beab        ..      BKPT     #0xab0x000080f4:    9801        ..      LDR      r0,[sp,#4]0x000080f6:    2800        .(      CMP      r0,#00x000080f8:    bf02        ..      ITTT     EQ0x000080fa:    4805        .H      LDREQ    r0,_RW_Limit ; [0x8110] = 0x81a00x000080fc:    1dc0        ..      ADDEQ    r0,r0,#70x000080fe:    f0200007     ...    BICEQ    r0,r0,#70x00008102:    9903        ..      LDR      r1,[sp,#0xc]0x00008104:    9a02        ..      LDR      r2,[sp,#8]0x00008106:    9b04        ..      LDR      r3,[sp,#0x10]0x00008108:    b005        ..      ADD      sp,sp,#0x140x0000810a:    bd00        ..      POP      {pc}$d0x0000810c:    00000009    ....    DCD    9_RW_Limit0x00008110:    000081a0    ....    DCD    33184$t.text__I$use$semihosting__use_no_semihosting_swi0x00008114:    4770        pG      BX       lr.text__semihosting_library_function0x00008116:    0000        ..      MOVS     r0,r0.text_sys_exit0x00008118:    4901        .I      LDR      r1,[pc,#4] ; [0x8120] = 0x200260x0000811a:    2018        .       MOVS     r0,#0x180x0000811c:    beab        ..      BKPT     #0xab0x0000811e:    e7fe        ..      B        0x811e ; _sys_exit + 6$d0x00008120:    00020026    &...    DCD    131110$t.0main0x00008124:    b081        ..      SUB      sp,sp,#40x00008126:    2000        .       MOVS     r0,#00x00008128:    9000        ..      STR      r0,[sp,#0]0x0000812a:    e7ff        ..      B        0x812c ; main + 80x0000812c:    e7fe        ..      B        0x812c ; main + 80x0000812e:    0000        ..      MOVS     r0,r0$d.realdataRegion$$Table$$Base0x00008130:    00008140    @...    DCD    330880x00008134:    00008140    @...    DCD    330880x00008138:    00000060    `...    DCD    960x0000813c:    0000803c    <...    DCD    32828Region$$Table$$Limit** Section #2 'ER_ZI' (SHT_NOBITS) [SHF_ALLOC + SHF_WRITE]Size   : 96 bytes (alignment 4)Address: 0x00008140** Section #3 '.debug_frame' (SHT_PROGBITS)Size   : 428 bytes** Section #4 '.symtab' (SHT_SYMTAB)Size   : 2960 bytes (alignment 4)String table #5 '.strtab'Last local symbol no. 118** Section #5 '.strtab' (SHT_STRTAB)Size   : 3260 bytes** Section #6 '.note' (SHT_NOTE)Size   : 24 bytes (alignment 4)** Section #7 '.comment' (SHT_PROGBITS)Size   : 608 bytes** Section #8 '.shstrtab' (SHT_STRTAB)Size   : 76 bytes

这段输出是 ARM 编译器生成的 ELF 格式可执行文件 hello.axf 的反汇编和段信息。以下是关键点的中文分析:

  1. 文件头信息
  • 32位ARM架构(ELFCLASS32)
  • 小端格式(ELFDATA2LSB)
  • 入口地址:0x00008001
  • 使用软件浮点(Soft float)
  • ARM编译器版本:6.16
  1. 程序执行流程
  • __main开始(0x8000)
  • 调用__scatterload初始化数据(0x8008)
  • 调用__rt_entry进入运行时环境(0x8060)
  • 最终跳转到main函数(0x8124)
  1. 关键函数
  • __scatterload:负责加载初始化数据(0x8008-0x8032)
  • __scatterload_zeroinit:清零ZI(未初始化)数据区(0x803c-0x8056)
  • main函数:位于0x8124,当前是一个空循环
  1. 内存布局
  • 代码段(ER_RO):0x8000-0x813F (320字节)
  • 未初始化数据段(ER_ZI):0x8140开始(96字节)
  1. 特殊说明
  • 使用半主机模式(semihosting)进行调试输出
  • 包含ARM库的初始化代码(__rt_lib_init等)
  • 程序最终进入无限循环(0x812c处的B指令)

1.4.6 bin 文件输出

而如果希望生成bin文件,则命令如下:

fromelf --bin --output=hello.bin hello.axf

bin 文件和反汇编文件的数据一样只是变成了大端模式:

1.4.6 总结

无论是我们使用手动方案还是 keil 自动所编译的,均是这个流程:

 预处理部分包括:

包含头文件:将标准库头文件或自定义头文件插入到当前文件的当前位置。

宏定义与替换:处理 #define 指令,将宏定义的常量、函数式宏或代码片段替换为相应的结果。

条件编译:处理条件编译指令,用于根据条件决定是否编译某段代码

删除所有注释:删除源代码中的所有注释(/*...*/和 课//..),以减少编译器的处理负担。

#Pragma等指令:保留#pragma等指令,从而向编译器传递特定实现相关的指令。

某些特殊指令:处理某些特殊指令,如#error,用于在预处理阶段生成错误信息并停止编译,或者完成其它操作。

二、Keil 的工程构建分析

2.1 编译选项

在Option for Target中,提供了对整个工程中所有文件的相关编译、链接配置选项。

2.1.1 预处理(Preprocessor Symbols):

这里主要就是预定义功能,相当于在程序中的#define xxxx。

2.1.2 语言/代码生成(Language / Code Generation)

  • Execute only Code:只生成执行代码 【设置编译器命令行:--execute_only】 只生成执行代码防止编译器生成任何数据访问代码部分。
  • Warnings:警告 【No Warnings设置编译器命令行:-W】 No Warnings:不会有警告提示和输出; All Warnings:所有警告提示和输出。 
  • Language C。选择 C 语言规范风格。
  • Optimize:优化选择项,有Level0 - Level3四个选项 【设置编译器命令行:-Onum】 初学者、在线调试建议使用Level0,也就是不优化,这样执行的效果才和代码一样。如果配置成Level3,在线调试可能有些地方优化而不能打断点。
  • Plain Char is Signed:纯字符标记为字符 【设置编译器命令行:--signed_chars】 代码举例:char a[] = “abcd”; 也就是说将“abcd”标记为字符型。 
  • Split Load and Store Multiple:加载和存储多个分裂 【设置编译器命令行:--split_ldm】 非对齐数据采用多次访问方式。当 LMD/STM 指令有 4 个以上产生时,列分裂LMD 和 STM 指令,以减不中断延迟。
  • Read-Only Position Independent:为常量生成独立的代码空间 【设置编译器命令行:--apcs=/ropi】 比如:我们定义字库变量为常量,勾选该选项,会将这些字库变量放在独立的代码空间。 
  • One ELF Section per Function:优化每一个函数 ELF 段 【设置编译器命令行:--split_sections】 每个函数都会产生一个 ELF 段,勾选上,允许优化每一个 ELF 段。这个选项可以减少潜在的共享地址、数据和函数之间的字符串。直白的意思:可以减少代码量ROM的大小(内存RAM不会减小)。举一个例子,勾选之前和勾选之后,编译后存储大小对比: 勾选之前: Program Size: Code=2540 RO-data=336 RW-data=40 ZI-data=1024。勾选之后: Program Size: Code=908 RO-data=320 RW-data=40 ZI-data=1024Read-Write Position Independent:为可读写代码生成独立的代码空间 【设置编译器命令行:--apcs=/rwpi】
  • No Auto Includes:不自动添加头文件 不勾选该选项,编译器就会在Keil安装路径寻找你工程中.h文件。 举例:我们定义uint8_t是定义在stdint.h文件里面的,但是我们工程目录下一般是没有stdint.h文件。这时候,编译器就会在Keil路径下去寻找stdint.h文件。

在我们选择这些配置项时,下方的 Compiler control string 自动生成编译的配置选项,此选项对于我们之前的生成 .o 文件命令,只是加了一些我们勾选的参数。

armclang --target=arm-arm-none-eabi -mcpu=cortex-m3 -c .\start.c

2.2 链接选项

  • Use Memory Layout from Target Dialog​:勾选后,链接器直接使用“Target”选项卡中定义的内存地址(如Flash/RAM的起始和大小)。
  • 作用**​:避免手动维护分散加载文件(Scatter File),适合简单项目。
  • Make RW Sections Position Independent:使读写段(RAM中的数据)支持地址无关(适用于动态加载或固件升级)。
  • Make RO Sections Position Independent:使只读段(Flash中的代码/常量)支持地址无关(较少使用,可能增加代码大小)。
  • Don't Search Standard Libraries:禁止链接标准库(需手动指定所有依赖库),用于精简代码或自定义库。
  • Report 'might fail' Conditions as Errors:将潜在链接问题(如内存不足)视为错误(严格模式)。

同样的,在勾选配置时,下方的 Linker control string 也会变动,此对应我们之前的:

armlink start.o hello.o -o hello.axf

链接命令。 

2.3 预处理结果

考虑一个很简单的 Keil 工程,只有两个文件:

main.c:

#define MAX(a, b) ((a) > (b) ? (a) : (b))int main() 
{int max = MAX(3, 4);return 0;
}void SystemInit(void) 
{// 空实现
}

 startup.s:

Stack_Size		EQU     0x1000AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>Heap_Size      EQU     0x1000AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limitPRESERVE8THUMB; Vector Table Mapped to Address 0 at ResetAREA    RESET, DATA, READONLYEXPORT  __VectorsEXPORT  __Vectors_EndEXPORT  __Vectors_Size__Vectors       DCD     __initial_sp               ; Top of StackDCD     Reset_Handler              ; Reset HandlerDCD     NMI_Handler                ; NMI HandlerDCD     HardFault_Handler          ; Hard Fault HandlerDCD     MemManage_Handler          ; MPU Fault HandlerDCD     BusFault_Handler           ; Bus Fault HandlerDCD     UsageFault_Handler         ; Usage Fault HandlerDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     SVC_Handler                ; SVCall HandlerDCD     DebugMon_Handler           ; Debug Monitor HandlerDCD     0                          ; ReservedDCD     PendSV_Handler             ; PendSV HandlerDCD     SysTick_Handler            ; SysTick Handler__Vectors_End__Vectors_Size  EQU  __Vectors_End - __VectorsAREA    |.text|, CODE, READONLY; Reset handler
Reset_Handler    PROCEXPORT  Reset_Handler             [WEAK]IMPORT  SystemInitIMPORT  __mainLDR     R0, =SystemInitBLX     R0LDR     R0, =__mainBX      R0ENDP; Dummy Exception Handlers (infinite loops which can be modified)NMI_Handler     PROCEXPORT  NMI_Handler                [WEAK]B       .ENDP
HardFault_Handler\PROCEXPORT  HardFault_Handler          [WEAK]B       .ENDP
MemManage_Handler\PROCEXPORT  MemManage_Handler          [WEAK]B       .ENDP
BusFault_Handler\PROCEXPORT  BusFault_Handler           [WEAK]B       .ENDP
UsageFault_Handler\PROCEXPORT  UsageFault_Handler         [WEAK]B       .ENDP
SVC_Handler     PROCEXPORT  SVC_Handler                [WEAK]B       .ENDP
DebugMon_Handler\PROCEXPORT  DebugMon_Handler           [WEAK]B       .ENDP
PendSV_Handler  PROCEXPORT  PendSV_Handler             [WEAK]B       .ENDP
SysTick_Handler PROCEXPORT  SysTick_Handler            [WEAK]B       .ENDPDefault_Handler PROCB       .ENDPALIGN;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************IF      :DEF:__MICROLIBEXPORT  __initial_spEXPORT  __heap_baseEXPORT  __heap_limitELSEIMPORT  __use_two_region_memoryEXPORT  __user_initial_stackheap__user_initial_stackheapLDR     R0, =  Heap_MemLDR     R1, =(Stack_Mem + Stack_Size)LDR     R2, = (Heap_Mem +  Heap_Size)LDR     R3, = Stack_MemBX      LRALIGNENDIFEND

 目录结构如下:

在 Keil 勾选上这个选项即可生成 .i 预编译后的文件:

在 目录下Listings 可以发现生成的 main.i 文件: 

这个文件内就是预编译后的文件,因为我们的程序比较简单,预编译器只做了宏替换。

# 1 "Source/main.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 363 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "Source/main.c" 2int main()
{int max = ((3) > (4) ? (3) : (4));return 0;
}void SystemInit(void)
{}

让我们考虑一个比这个更复杂的 main.c 程序:

#include <stdio.h>
#define PI 3.14159
#define MAX(a, b) ((a) > (b) ? (a) : (b))// test
#define VERSION 1.0#ifndef VERSION
#error "VERSION is not defined!"
#endifint main() {#ifdef DEBUGprintf("Debug mode is on.\n");#endifprintf("The value of PI is: %f\n", PI);int max = MAX(3, 4);return 0;
}

 在这里我们使用了:

包含头文件(#include)

处理 #include 指令,将指定文件的内容(标准库头文件(如<stdio.h>)或自定义头文件(如"myheader.h"))插入到当前文件的当前位置中。

#include <stdio.h>
#include "myheader.h"

宏定义与替换(#define)

处理#define指令,将宏定义的常量、函数式宏或代码片段替换为相应的结果。

#define PI 3.14159
#define MAX(a, b) ((a) > (b) ? (a) : (b))

条件编译(#if, #ifdef, #ifndef, #else, #elif, #endif)

处理条件编译指令,用于根据条件决定是否编译某段代码。例如,对于下面的代码,如果开启了DEBUG,则包含 printf() 调用语句,否则就跳过该语句。

#ifdef DEBUGprintf("Debug mode is on.\n");
#endif

某些特殊指令(#error)

预处理器支持某些特殊指令,如#error,用于在预处理阶段生成错误信息并停止编译,或者完成其它操作。

#ifndef VERSION
#error "VERSION is not defined!"
#endif

#Pragma等指令(#pragma)

保留#pragma等指令,从而向编译器传递特定实现相关的指令。

#pragma once  // 防止头文件重复包含(非标准但广泛支持)

此时 mian.i 文件就会把所有的预编译命令进行预处理后显示在出来: 

# 1 "Source/main.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 363 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "Source/main.c" 2
# 1 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 1 3
# 53 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3typedef unsigned int size_t;
# 68 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3typedef __builtin_va_list __va_list;
# 87 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
typedef struct __fpos_t_struct {unsigned long long int __pos;struct {unsigned int __state1, __state2;} __mbstate;
} fpos_t;
# 108 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
typedef struct __FILE FILE;
# 119 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
struct __FILE {union {long __FILE_alignment;char __FILE_size[84];} __FILE_opaque;
};
# 138 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern FILE __stdin, __stdout, __stderr;
extern FILE *__aeabi_stdin, *__aeabi_stdout, *__aeabi_stderr;
# 224 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int remove(const char * ) __attribute__((__nonnull__(1)));extern __attribute__((__nothrow__)) int rename(const char * , const char * ) __attribute__((__nonnull__(1,2)));
# 243 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) FILE *tmpfile(void);extern __attribute__((__nothrow__)) char *tmpnam(char * );
# 265 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int fclose(FILE * ) __attribute__((__nonnull__(1)));
# 275 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int fflush(FILE * );
# 285 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) FILE *fopen(const char * __restrict ,const char * __restrict ) __attribute__((__nonnull__(1,2)));
# 329 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) FILE *freopen(const char * __restrict ,const char * __restrict ,FILE * __restrict ) __attribute__((__nonnull__(2,3)));
# 342 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) void setbuf(FILE * __restrict ,char * __restrict ) __attribute__((__nonnull__(1)));extern __attribute__((__nothrow__)) int setvbuf(FILE * __restrict ,char * __restrict ,int , size_t ) __attribute__((__nonnull__(1)));
# 370 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
#pragma __printf_args
extern __attribute__((__nothrow__)) int fprintf(FILE * __restrict ,const char * __restrict , ...) __attribute__((__nonnull__(1,2)));
# 393 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
#pragma __printf_args
extern __attribute__((__nothrow__)) int _fprintf(FILE * __restrict ,const char * __restrict , ...) __attribute__((__nonnull__(1,2)));#pragma __printf_args
extern __attribute__((__nothrow__)) int printf(const char * __restrict , ...) __attribute__((__nonnull__(1)));#pragma __printf_args
extern __attribute__((__nothrow__)) int _printf(const char * __restrict , ...) __attribute__((__nonnull__(1)));#pragma __printf_args
extern __attribute__((__nothrow__)) int sprintf(char * __restrict , const char * __restrict , ...) __attribute__((__nonnull__(1,2)));#pragma __printf_args
extern __attribute__((__nothrow__)) int _sprintf(char * __restrict , const char * __restrict , ...) __attribute__((__nonnull__(1,2)));#pragma __printf_args
extern __attribute__((__nothrow__)) int __ARM_snprintf(char * __restrict , size_t ,const char * __restrict , ...) __attribute__((__nonnull__(3)));#pragma __printf_args
extern __attribute__((__nothrow__)) int snprintf(char * __restrict , size_t ,const char * __restrict , ...) __attribute__((__nonnull__(3)));
# 460 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
#pragma __printf_args
extern __attribute__((__nothrow__)) int _snprintf(char * __restrict , size_t ,const char * __restrict , ...) __attribute__((__nonnull__(3)));#pragma __scanf_args
extern __attribute__((__nothrow__)) int fscanf(FILE * __restrict ,const char * __restrict , ...) __attribute__((__nonnull__(1,2)));
# 503 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
#pragma __scanf_args
extern __attribute__((__nothrow__)) int _fscanf(FILE * __restrict ,const char * __restrict , ...) __attribute__((__nonnull__(1,2)));#pragma __scanf_args
extern __attribute__((__nothrow__)) int scanf(const char * __restrict , ...) __attribute__((__nonnull__(1)));#pragma __scanf_args
extern __attribute__((__nothrow__)) int _scanf(const char * __restrict , ...) __attribute__((__nonnull__(1)));#pragma __scanf_args
extern __attribute__((__nothrow__)) int sscanf(const char * __restrict ,const char * __restrict , ...) __attribute__((__nonnull__(1,2)));
# 541 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
#pragma __scanf_args
extern __attribute__((__nothrow__)) int _sscanf(const char * __restrict ,const char * __restrict , ...) __attribute__((__nonnull__(1,2)));extern __attribute__((__nothrow__)) int vfscanf(FILE * __restrict , const char * __restrict , __va_list) __attribute__((__nonnull__(1,2)));
extern __attribute__((__nothrow__)) int vscanf(const char * __restrict , __va_list) __attribute__((__nonnull__(1)));
extern __attribute__((__nothrow__)) int vsscanf(const char * __restrict , const char * __restrict , __va_list) __attribute__((__nonnull__(1,2)));extern __attribute__((__nothrow__)) int _vfscanf(FILE * __restrict , const char * __restrict , __va_list) __attribute__((__nonnull__(1,2)));
extern __attribute__((__nothrow__)) int _vscanf(const char * __restrict , __va_list) __attribute__((__nonnull__(1)));
extern __attribute__((__nothrow__)) int _vsscanf(const char * __restrict , const char * __restrict , __va_list) __attribute__((__nonnull__(1,2)));
extern __attribute__((__nothrow__)) int __ARM_vsscanf(const char * __restrict , const char * __restrict , __va_list) __attribute__((__nonnull__(1,2)));extern __attribute__((__nothrow__)) int vprintf(const char * __restrict , __va_list ) __attribute__((__nonnull__(1)));extern __attribute__((__nothrow__)) int _vprintf(const char * __restrict , __va_list ) __attribute__((__nonnull__(1)));extern __attribute__((__nothrow__)) int vfprintf(FILE * __restrict ,const char * __restrict , __va_list ) __attribute__((__nonnull__(1,2)));
# 584 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int vsprintf(char * __restrict ,const char * __restrict , __va_list ) __attribute__((__nonnull__(1,2)));
# 594 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int __ARM_vsnprintf(char * __restrict , size_t ,const char * __restrict , __va_list ) __attribute__((__nonnull__(3)));extern __attribute__((__nothrow__)) int vsnprintf(char * __restrict , size_t ,const char * __restrict , __va_list ) __attribute__((__nonnull__(3)));
# 609 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int _vsprintf(char * __restrict ,const char * __restrict , __va_list ) __attribute__((__nonnull__(1,2)));extern __attribute__((__nothrow__)) int _vfprintf(FILE * __restrict ,const char * __restrict , __va_list ) __attribute__((__nonnull__(1,2)));extern __attribute__((__nothrow__)) int _vsnprintf(char * __restrict , size_t ,const char * __restrict , __va_list ) __attribute__((__nonnull__(3)));
# 635 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
#pragma __printf_args
extern __attribute__((__nothrow__)) int __ARM_asprintf(char ** , const char * __restrict , ...) __attribute__((__nonnull__(2)));
extern __attribute__((__nothrow__)) int __ARM_vasprintf(char ** , const char * __restrict , __va_list ) __attribute__((__nonnull__(2)));
# 649 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int fgetc(FILE * ) __attribute__((__nonnull__(1)));
# 659 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) char *fgets(char * __restrict , int ,FILE * __restrict ) __attribute__((__nonnull__(1,3)));
# 673 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int fputc(int , FILE * ) __attribute__((__nonnull__(2)));
# 683 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int fputs(const char * __restrict , FILE * __restrict ) __attribute__((__nonnull__(1,2)));extern __attribute__((__nothrow__)) int getc(FILE * ) __attribute__((__nonnull__(1)));
# 704 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3extern __attribute__((__nothrow__)) int (getchar)(void);
# 713 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) char *gets(char * ) __attribute__((__nonnull__(1)));
# 725 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int putc(int , FILE * ) __attribute__((__nonnull__(2)));
# 737 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3extern __attribute__((__nothrow__)) int (putchar)(int );extern __attribute__((__nothrow__)) int puts(const char * ) __attribute__((__nonnull__(1)));extern __attribute__((__nothrow__)) int ungetc(int , FILE * ) __attribute__((__nonnull__(2)));
# 778 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) size_t fread(void * __restrict ,size_t , size_t , FILE * __restrict ) __attribute__((__nonnull__(1,4)));
# 794 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) size_t __fread_bytes_avail(void * __restrict ,size_t , FILE * __restrict ) __attribute__((__nonnull__(1,3)));
# 810 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) size_t fwrite(const void * __restrict ,size_t , size_t , FILE * __restrict ) __attribute__((__nonnull__(1,4)));
# 822 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int fgetpos(FILE * __restrict , fpos_t * __restrict ) __attribute__((__nonnull__(1,2)));
# 833 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int fseek(FILE * , long int , int ) __attribute__((__nonnull__(1)));
# 850 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int fsetpos(FILE * __restrict , const fpos_t * __restrict ) __attribute__((__nonnull__(1,2)));
# 863 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) long int ftell(FILE * ) __attribute__((__nonnull__(1)));
# 877 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) void rewind(FILE * ) __attribute__((__nonnull__(1)));
# 886 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) void clearerr(FILE * ) __attribute__((__nonnull__(1)));extern __attribute__((__nothrow__)) int feof(FILE * ) __attribute__((__nonnull__(1)));extern __attribute__((__nothrow__)) int ferror(FILE * ) __attribute__((__nonnull__(1)));extern __attribute__((__nothrow__)) void perror(const char * );
# 917 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) int _fisatty(FILE * ) __attribute__((__nonnull__(1)));extern __attribute__((__nothrow__)) void __use_no_semihosting_swi(void);
extern __attribute__((__nothrow__)) void __use_no_semihosting(void);
# 2 "Source/main.c" 2
# 12 "Source/main.c"
int main() {printf("The value of PI is: %f\n", 3.14159);int max = ((3) > (4) ? (3) : (4));return 0;
}

 其中大部分内容都是如:

extern __attribute__((__nothrow__)) int rename(const char * , const char * ) __attribute__((__nonnull__(1,2)));
# 243 "C:\\Keil_v5\\ARM\\ARMCLANG\\Bin\\..\\include\\stdio.h" 3
extern __attribute__((__nothrow__)) FILE *tmpfile(void);

 使用 __attribute__((__nothrow__)) 命令声明 stdio.h 文件内的函数和变量等。

__attribute__((__nothrow__)) ​是GCC/Clang编译器的扩展属性,表示被修饰的函数不会抛出异常(即使函数内部有异常也会被抑制)。

其中具体的语法会在之后章节描述。


http://www.hkcw.cn/article/QAWXdEYJIe.shtml

相关文章

XUANYING炫影-移动版-智能轻云盒SY900Pro和SY910_RK3528芯片_免拆机通刷固件包

XUANYING炫影-移动版-智能轻云盒SY900Pro和SY910_RK3528芯片_免拆机通刷固件包 智能轻云盒SY900Pro 智能轻云盒SY910 不要刷电信版的&#xff01; 不要刷电信版的&#xff01; 不要刷电信版的&#xff01; 固件说明&#xff1a; 这是一个亲测的固件。 1、默认开启 ADB功能。…

MySQL + CloudCanal + Iceberg + StarRocks 构建全栈数据服务

简述 在业务数据快速膨胀的今天&#xff0c;企业对 低成本存储 与 实时查询分析能力 的需求愈发迫切。 本文将带你实战构建一条 MySQL 到 Iceberg 的数据链路&#xff0c;借助 CloudCanal 快速完成数据迁移与同步&#xff0c;并使用 StarRocks 完成数据查询等操作&#xff0c…

实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.13 R语言解题

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅珏生译) 第5章析因设计引导5.7节思考题5.13 R语言解题。主要涉及方差分析&#xff0c;正态假设检验&#xff0c;残差分析&#xff0c;交互作用图。 dataframe<-data.frame( yc(36,18,30,39,20…

Excel 中的SUMIFS用法(基础版),重复项求和

1. 首先复制筛选条件所在的列&#xff0c;去除重复项目 数据 》重复项 》删除重复项 2. 输入函数公式 SUMIFS(C:C,A:A,E2) 3. 选中单元格&#xff0c;通过 ShiftF3 查看函数参数 第一个参数&#xff1a;求和区域&#xff0c;要累加的值所在的区域范围 第二个参数&#xff1a…

HCIP:MPLS静态LSP的配置及抓包

目录 一、MPLS的简单的一些知识点 1.MPLS的概述&#xff1a; 2.MPLS工作原理&#xff1a; 3.MPLS的核心组件&#xff1a; 4. MPLS标签 5.MPLS标签的处理 6.MPLS转发的概述&#xff1a; 7.MPLS的静态LSP建立方式 二、MPLS的静态LSP的实验配置 1.配置接口的地址和配置OS…

世冠科技亮相中汽中心科技周MBDE会议,共探汽车研发数字化转型新路径

近日&#xff0c;中汽中心2025年科技周MBDE前沿应用主题会议在天津成功举办。本次会议以“智汇津门共探MBDE前沿应用新征程”为主题&#xff0c;聚焦基于模型的数字工程&#xff08;MBDE&#xff09;方法论在汽车复杂系统研发中的创新实践与跨领域协同&#xff0c;旨在推动行业…

Linux之Nginx配置篇

一、Ngixn核心重点 Nginx是一款功能强大HTTP和反向代理服务器&#xff0c;目前大部分公司用于使用其Web服务器 在Nginx还未出世之前都是在使用比较传统Apache服务器&#xff0c;两则都能处理Web请求,但是后者处理效率更高、包括其负载均衡&#xff0c;反向代理功能都很强&#…

RAG混合检索:倒数秩融合RRF算法

文章目录 检索增强生成 (RAG)倒数秩融合在 RAG 中的工作原理RRF 背后的数学直觉检索增强生成 (RAG) RAG 是自然语言处理中的一种强大技术,结合了基于检索的模型和生成模型的优势。 如果检索器未能从检索器中获取相关文档,则精度较低,幻觉的可能性会增加。 有些查询适合…

2023年09月GESPC++二级真题解析(含视频)

视频讲解&#xff1a;GESP2023年9月二级C真题讲解 一、单选题 第1题 解析&#xff1a; 答案D&#xff0c;第一台用的就是电子管 第2题 解析&#xff1a; 答案B&#xff0c;x>y不符合条件&#xff0c;执行ay,bx&#xff0c;输出a、b&#xff0c;即输出y、x&#xff0c;也…

STUSB4500 PPS(PD3.0)快充SINK模块——应用 解析

0 前言 朋友参加车展&#xff0c;收获一枚很漂亮的倍思65W氮化镓快充头&#xff0c;送给我了。 我看了手中只支持33W快充的三星陷入了沉思… 快充头支持PPS协议&#xff0c;我心思这玩意适合做可调电源啊&#xff01; 上网随便一查没查到&#xff0c;都是转换成5V、9V、12V等…

4644芯片在商业航天与特种工业中的低温环境适应性研究

摘要 在现代电子技术的广泛应用中&#xff0c;商业航天和特种工业领域对于电子元件的环境适应性提出了极为苛刻的要求。本文以国科安芯研发的 ASP4644S 芯片为例&#xff0c;深入探讨其在-55℃极端低温条件下的运行性能、技术难点以及在商业航天与特种工业领域的应用。通过对芯…

Windows 权限提升 | TryHackMe | Windows Privilege Escalation

Windows 权限提升 [!quote] 权限提升就是利用用户A的主机访问权限,利用目标系统中的漏洞来获取到用户B的访问权限 Windows 服务或计划任务的配置错误账户被赋予过多权限缺少Windows安全补丁 Windows 用户 Windows系统主要存在两种类型的用户,根据访问级别,分为两类 Administ…

Redis持久化机制

一. Redis应用概述 Redis是一种高性能的KV键值对存储数据库&#xff0c;通常用作数据库、缓存和消息队列等。它支持多种数据结构&#xff0c;如字符串、哈希表、列表、集合和有序集合。Redis具有快速存取和实时响应的特点&#xff0c;广泛应用于Web开发、大数据处理和实时分析…

VMware使用时出现的问题,此文章会不断更新分享使用过程中会出现的问题

VMware使用时出现的问题&#xff0c;此文章会不断更新分享使用过程中会出现的问题 一、VMware安装后没有虚拟网卡&#xff0c;VMnet1&#xff0c;VMnet8显示黄色三角警告 此文章会不断更新&#xff0c;分享VMware使用过程中出现的问题 如果没找到你的问题可以私信我 一、VMware…

60天python训练计划----day40

DAY 40 训练和测试的规范写法 知识点回顾&#xff1a; 彩色和灰度图片测试和训练的规范写法&#xff1a;封装在函数中展平操作&#xff1a;除第一个维度batchsize外全部展平dropout操作&#xff1a;训练阶段随机丢弃神经元&#xff0c;测试阶段eval模式关闭dropout 一.单通道图…

leetcode:479. 最大回文数乘积(python3解法,数学相关算法题)

难度&#xff1a;简单 给定一个整数 n &#xff0c;返回 可表示为两个 n 位整数乘积的 最大回文整数 。因为答案可能非常大&#xff0c;所以返回它对 1337 取余 。 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;987 解释&#xff1a;99 x 91 9009, 9009 % 1337 …

vue2 + webpack 老项目升级 node v22 + vite + vue2 实战全记录

前言 随着这些年前端技术的飞速发展&#xff0c;几年前的一些老项目在最新的环境下很可能会出现烂掉的情况。如果项目不需要升级&#xff0c;只需要把编译后的文件放在那里跑而不用管的话还好。但是&#xff0c;某一天产品跑过来给你讲要升级某一个功能&#xff0c;你不得不去…

Golang | 运用分布式搜索引擎实现视频搜索业务

把前面所设计好的搜索引擎引用进来开发一个简单的具体的视频搜索业务。代码结构&#xff1a; handler目录&#xff1a;后端接口&#xff0c;负责接收请求并返回结果&#xff0c;不存在具体的搜索逻辑。video_search目录&#xff1a;具体的搜索逻辑存放在这&#xff0c;包括reca…

硬件学习笔记--64 MCU的ARM核架构发展及特点

MCU&#xff08;微控制器&#xff09;的ARM核架构是当前嵌入式系统的主流选择&#xff0c;其基于ARM Cortex-M系列处理器内核&#xff0c;具有高性能、低功耗、丰富外设支持等特点。以下是ARM核MCU的主要架构及其发展&#xff1a; 1. ARM Cortex-M系列内核概览 ARM Cortex-M系…

【笔记】Windows 系统安装 Scoop 包管理工具

#工作记录 一、问题背景 在进行开源项目 Suna 部署过程中&#xff0c;执行设置向导时遭遇报错&#xff1a;❌ Supabase CLI is not installed. 根据资料检索&#xff0c;需通过 Windows 包管理工具Scoop安装 Supabase CLI。 初始尝试以管理员身份运行 PowerShell 安装 Scoop…