24、ASCII、Unicode、UTF - 8 与汇编代码优化解析

ASCII、Unicode、UTF - 8 与汇编代码优化解析

1. ASCII、Unicode 与 UTF - 8

在计算机处理字符数据时,编码是一个核心问题。早期,ASCII 编码在字符表示中占据主导地位,它简单直接,并且在一定程度上与更高级的国际标准 Unicode 兼容。

1.1 Unicode

在 Unicode 出现之前,为字符串添加额外字符的解决方案是临时的,缺乏全局规划。不同的代码页(code page)被用于映射一组数字到屏幕上的显示字符,但这种方法存在局限性。例如,当需要混合使用不同代码页,或者不同组织使用不同代码页时,就会出现问题。如果要写一篇用日语汉字讨论梵语及其向希伯来语发展的论文,代码页的局限性就会凸显出来。

同时,扩展字符集也面临挑战,因为现有的大量文档和程序通常使用 ASCII 编码。将它们迁移到新的标准会很困难。

Unicode 联盟提出的解决方案是将字符列表与字符的表示方式分离。Unicode 为任何语言的每个字符分配一个 32 位的数字,这提供了超过 40 亿种可能性,几乎不会用完。当前的 Unicode 13.0 版本有 143,859 个字符,这比 8 位或 16 位能表示的字符数量多得多,但只是 32 位所能表示范围的一小部分。

Unicode 字符通常用 U + XXXX 表示,XXXX 是十六进制值,这被称为字符的代码点(code point)。对于大多数语言,大多数值位于前 16 位,因此 Unicode 代码点通常用 16 位十六进制值表示,但也可以使用长达 32 位的十六进制值。对于常见的 ASCII 字符,代码点和 ASCII 码相同。

1.2 Unicode 编码与 UTF - 8

虽然每个字符都有唯一的代码点,但在计算机上的表示方式并不唯一,这些表示方式被称为字符编码。UTF - 32 是一种简单的 Unicode 编码,每个字符为 32 位宽,值就是 Unicode 值。但它几乎与其他编码不兼容。

因此,通常选择 UTF - 8 编码。UTF - 8 使用不同长度的字符,所以如果要查找字符串中的第 13 个字符,不能直接进行索引查找,而需要逐个字符处理,同时确定每个字符的长度。不过,其优点是,如果使用不支持 UTF - 8 的旧程序,只使用标准英语字符时,看起来就像 ASCII 编码。

UTF - 8 编码不同长度字符的方式是使用第一个字节的第一位来指定字符是否为多字节字符。在传统 ASCII 中,第一位总是 0,所以不会与 ASCII 产生冲突。具体编码规则如下:
- 代码点 U + 0000 到 U + 007F:编码为 1 字节,0xxxxxxx(7 位)
- 代码点 U + 0080 到 U + 07FF:编码为 2 字节,110xxxxx 10xxxxxx(11 位)
- 代码点 U + 0800 到 U + FFFF:编码为 3 字节,1110xxxx 10xxxxxx 10xxxxxx(16 位)
- 代码点 U + 10000 到 U + 10FFFF:编码为 4 字节,11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(21 位)

例如,希腊小写字母 β 的代码点是 U + 03B2,二进制为 1110110010,长度为 10 位。在 UTF - 8 中,它被编码为 2 字节,允许 11 位,因此值扩展为 01110110010,编码为 11001110 10110010,十六进制为 0xCEB2。

如果要查找字符串中的第 n 个字符,可以使用每个字符的初始位来确定字符的长度。

1.3 UTF - 8 的一些特殊情况

在 UTF - 8 中,一些文档以字节顺序标记(BOM)开头,它基于另一种 Unicode 编码 UTF - 16。转换为 UTF - 8 时,这个值是 0xEFBBBF。如果这个值出现在 UTF - 8 文件的开头,可以基本忽略。

另一个重要问题是 Unicode 字符 U + FFFD,即“Unicode 替换字符”。当进行文本处理的系统遇到无效字符时,有时会用这个字符替换它们。在 UTF - 8 中,它编码为 0xEFBFBD。如果二进制文件或数据流被期望处理文本的系统处理,输出中大量出现 0xEFBFBD 字节就表明可能发生了这种情况。

1.4 ASCII 表

ASCII 非常重要,以下是 ASCII 字符的标准表,使用时,找到感兴趣的字符,将顶行的数字与左列的数字相加即可得到对应的 ASCII 码。

+0 +1 +2 +3 +4 +5 +6 +7
0 NULL SOH STX ETX EOT ENQ ACK
8 BS HTAB LF VTAB FF CR SO
16 DLE DC1 DC2 DC3 DC4 NAK SYN
24 CAN EM SUB ESC FS GS RS
32 ! “ # $ % & ’
40 ( ) * + , - .
48 0 1 2 3 4 5 6
56 8 9 : ; < = >
64 @ A B C D E F
72 H I J K L M N
80 P Q R S T U V
88 X Y Z [ \ ] ^
96 ‘ a b c d e f
104 h i j k l m n
112 p q r s t u v
120 x y z { | } DEL

不过,ASCII 也并非完全标准。例如,计算机对行尾的编码方式不同。在 Windows 上,标准是用两个字符表示行尾,回车符(CR)将光标水平移到行首,换行符(LF)将光标垂直移到下一行;在基于 Unix 的机器上,使用单个 LF 表示行尾,同时完成水平和垂直移动;在非常旧的 Macintosh 上,则使用单个回车符。此外,水平制表符应代表多少个空格也是一个有争议的问题。

2. 汇编代码优化

优化汇编语言代码需要深入了解 CPU 的指令处理架构。现代处理器非常复杂,目标是充分利用每纳秒的运算时间。以下是一些常见的优化概念。

2.1 对齐(Alignment)

处理器通常以块为单位处理数据,即使处理单个值,在底层,处理器和计算机的其他部分也以更大的尺寸进行操作。

从代码角度看,内存中的每个字节都有独立的地址,可以从内存位置 17、18 或 19 轻松加载四字(quadword)。但对于实际的硬件 RAM 并非如此。在 x86 - 64 系统中,数据通常以四字块分组(与处理器的字长匹配)。如果尝试从内存加载四字,但该四字的地址不能被 8(四字的字节数)整除,处理器实际上需要从两个不同的物理 RAM 位置加载数据并拼接结果。

因此,需要关注数据地址,使要加载值的地址与数据在 RAM 中的物理存储方式匹配。可以使用 .balign 指令控制数据对齐。例如,要确保 .data 段中的值按 8 字节边界对齐,只需在标记地址并添加数据之前使用 .balign 8。

2.2 数据缓存(Data Caching)

当访问主内存时,处理器会在数据总线上发出请求,然后等待请求完成。但通常,使用过一次的内存很快会再次被使用,因此处理器会将值存储在一个或多个位于处理器上的小缓存中。当再次请求该内存时,如果在缓存中找到(缓存命中),就无需等待内存总线来满足内存需求。

数据以块的形式从内存传输到缓存,这些块称为缓存行(cache line)或缓存块(cache block)。大多数 x86 - 64 处理器的缓存行为 64 字节。当请求内存时,处理器通常会假设需要更多数据,因此会请求超过所需的数据,加载一个完整的缓存块到缓存中。这些缓存块按 64 字节对齐。

如果要处理内存中的多个值,将这些值存储在彼此靠近的位置有助于提高处理器速度。例如,如果处理一个大的结构体,更可能一起访问的部分应存储在一起,这将提高缓存性能。还可以使用 .balign 64 指令将部分数据对齐到最近的缓存块。

2.3 流水线(Pipelining)

处理器提高速度的一种方式是通过指令流水线。现代 CPU 指令很复杂,需要处理器执行多种操作,如指令提取、指令解码、内存访问、寄存器访问、算术运算、浮点运算以及将运算结果写入寄存器或内存。

现代处理器将指令分成多个阶段,这样可以同时执行多条指令。例如,当一条指令正在解码时,另一条指令正在进行内存提取。目标是让处理器的各个部分都忙于处理不同的指令。

处理器需要检测指令是否可以流水线执行。如果一条指令不能与另一条指令流水线执行,就会导致流水线停顿(pipeline stall)。例如,如果第一条指令最后写入 %rax,而第二条指令需要从 %rax 读取,处理器就不能对这两条指令进行流水线处理,因为第二条指令依赖于第一条指令的完成。作为程序员,无需担心这些,处理器会确保代码的正确执行。但在编程时考虑流水线,可以帮助处理器更优化地执行代码,目标是让处理器的各个部分都保持忙碌,尽量减少等待前一条指令结果的时间。

一些超标量处理器(superscalar processor)更进一步,可以同时启动两条指令,甚至可以乱序执行(前提是不影响代码的含义)。

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([开始]):::startend --> B(指令 1 提取):::process
    B --> C(指令 1 解码):::process
    C --> D(指令 1 内存访问):::process
    D --> E(指令 1 执行):::process
    E --> F(指令 1 写回):::process
    G(指令 2 提取):::process --> H(指令 2 解码):::process
    H --> I(指令 2 内存访问):::process
    I --> J(指令 2 执行):::process
    J --> K(指令 2 写回):::process
    B --> G
    C --> H
    D --> I
    E --> J
    F --> K
    F --> L([结束]):::startend
    K --> L

这个流程图展示了两条指令的流水线执行过程,两条指令的不同阶段可以并行进行,提高了处理器的执行效率。

2.4 指令缓存与分支预测

代码也存储在内存中,处理器可以缓存代码所在的内存,从而更快地加载下一条指令。处理器还擅长预测程序的未来走向,因此可以预取即将执行的指令,避免在执行时等待内存。

但当遇到分支(如 jmp、call 或条件跳转)时,情况会发生变化。在分支处,代码不一定会执行下一条指令。对于条件分支,处理器甚至无法提前确定会选择哪个分支;对于间接跳转,甚至分支的目标地址也可能无法提前知道。这会影响缓存和流水线,因为两者都需要处理器知道下一条指令是什么。

分支预测允许处理器猜测条件分支代码可能选择的分支。预测不一定正确,但正确的预测会更快。否则,处理器会缓存错误的指令并开始流水线处理(称为推测执行)。当分支不按处理器的预测执行时,流水线会停顿,需要清除流水线并从内存读取实际指令。

分支预测可以通过多种方式实现,从简单的(总是以相同方式猜测)到更复杂的(跟踪不同分支被选择或未被选择的频率)。x86 指令集甚至允许向处理器提示分支更可能被选择还是不被选择,但现代处理器不再使用这些提示。

在进行间接跳转时,处理器需要更难的预测,即预测跳转的目标地址。现代处理器在一定程度上可以做到这一点,但需要在跳转前足够长的时间将值放入寄存器,以便处理器提前预测目标地址并做好相应准备。

有时,将分支目标按缓存行对齐会有帮助,这样在分支被预测时,代码可以更有效地移动到指令缓存中。可以在 .text 段使用 .balign 指令使分支目标正确对齐。当 .balign 在数据段时,用零填充数据;在 .text 段时,用 nop(或等效)指令填充指令。

2.5 选择指令和寄存器

指令选择也很重要。不同的指令在字节大小上不同,这会影响缓存。此外,不同的指令对流水线的影响也不同。例如,SSE 指令 movaps 和 movapd 实际上执行相同的操作,但 movaps 编码使用的字节数更少,因此更适合放入指令缓存。虽然 enter 指令专门用于设置栈帧,但实际上它比手动设置栈帧慢,尽管它需要更多的指令。

寄存器选择同样重要。有时,使用新寄存器存储结果比重用现有寄存器更好,因为这样可以实现更好的流水线处理。

优化汇编语言代码是一个复杂的过程,需要考虑多个因素。通过了解这些常见的优化概念,可以更好地编写高效的汇编代码。如果对优化汇编语言感兴趣,可以进一步了解处理器的内部架构和各种指令的详细操作。

ASCII、Unicode、UTF - 8 与汇编代码优化解析

2. 汇编代码优化(续)
2.6 优化操作步骤总结

为了更好地进行汇编代码优化,下面总结一些具体的操作步骤:
1. 对齐优化
- 确定数据类型和处理器架构,对于 x86 - 64 系统,数据通常以四字块分组,关注 8 字节对齐。
- 在 .data 段使用 .balign 8 指令确保数据按 8 字节边界对齐,示例代码如下:

.data
.balign 8
my_variable: .quad 123 ; 按 8 字节对齐的四字变量
- 对于分支目标,在 `.text` 段使用 `.balign 64` 指令按 64 字节缓存行对齐,示例代码如下:
.text
.balign 64
my_label:
    ; 分支目标代码
  1. 数据缓存优化
    • 将经常一起访问的数据存储在相邻位置,例如结构体中相关成员的排列。
// C 语言示例,结构体成员按访问频率排列
struct my_struct {
    int frequently_used;
    int less_frequently_used;
};
- 使用 `.balign 64` 指令将数据对齐到 64 字节缓存块,提高缓存命中率。
.data
.balign 64
my_array: .int 1, 2, 3, 4 ; 按 64 字节对齐的数组
  1. 流水线优化
    • 避免指令间的依赖关系,例如避免前一条指令写入寄存器,后一条指令立即读取该寄存器。
; 不好的示例,存在依赖关系
mov %rax, %rbx ; 写入 %rbx
add %rbx, %rcx ; 从 %rbx 读取

; 好的示例,减少依赖
mov %rax, %rdx ; 临时存储到 %rdx
add %rdx, %rcx ; 使用 %rdx
- 编写代码时尽量让处理器的各个部分保持忙碌,充分利用流水线。
  1. 指令缓存与分支预测优化
    • 对于条件分支,尽量减少分支的不确定性,例如通过代码逻辑让分支结果更可预测。
    • 对于间接跳转,提前将跳转目标地址放入寄存器,让处理器有足够时间进行预测。
; 提前设置跳转目标地址
mov $target_address, %rax
jmp *%rax ; 间接跳转
- 使用 `.balign` 指令将分支目标按缓存行对齐,提高指令缓存效率。
  1. 指令和寄存器选择优化
    • 选择字节长度更短的指令,例如优先使用 movaps 而非 movapd 。
; 使用 movaps 指令
movaps %xmm0, %xmm1
- 合理选择寄存器,避免不必要的寄存器重用,提高流水线性能。
3. 总结

本文主要介绍了字符编码和汇编代码优化的相关知识。

在字符编码方面:
- Unicode 解决了传统代码页在处理多语言字符时的局限性,通过为每个字符分配 32 位代码点,实现了更广泛的字符表示。
- UTF - 8 作为一种常用的 Unicode 编码,具有与 ASCII 兼容的优点,同时能处理不同长度的字符,但查找字符时需要特殊处理。
- ASCII 虽然是基础的字符编码,但在不同系统中存在行尾编码和制表符表示等差异。

在汇编代码优化方面:
|优化方面|要点|
| ---- | ---- |
|对齐|关注数据地址与硬件存储方式匹配,使用 .balign 指令进行对齐|
|数据缓存|将相关数据存储在一起,使用 .balign 64 指令提高缓存命中率|
|流水线|减少指令依赖,让处理器各部分保持忙碌|
|指令缓存与分支预测|减少分支不确定性,提前设置跳转目标,使用 .balign 指令对齐分支目标|
|指令和寄存器选择|选择字节长度短的指令,合理选择寄存器|

通过掌握这些知识和优化方法,可以更好地处理字符编码问题,编写高效的汇编代码。在实际应用中,需要根据具体的场景和需求,综合运用这些优化技巧,以达到最佳的性能效果。

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([开始优化]):::startend --> B{选择优化方向}:::decision
    B -->|对齐优化| C(确定对齐方式):::process
    C --> D(使用.balign 指令):::process
    D --> E(检查对齐效果):::process
    B -->|数据缓存优化| F(整理数据布局):::process
    F --> G(使用.balign 64 指令):::process
    G --> H(测试缓存命中率):::process
    B -->|流水线优化| I(减少指令依赖):::process
    I --> J(保持处理器忙碌):::process
    J --> K(分析流水线性能):::process
    B -->|指令缓存与分支预测优化| L(减少分支不确定性):::process
    L --> M(提前设置跳转目标):::process
    M --> N(使用.balign 指令对齐分支目标):::process
    N --> O(评估预测准确率):::process
    B -->|指令和寄存器选择优化| P(选择合适指令):::process
    P --> Q(合理选择寄存器):::process
    Q --> R(测试代码性能):::process
    E --> S([结束优化]):::startend
    H --> S
    K --> S
    O --> S
    R --> S

这个流程图展示了汇编代码优化的整体流程,根据不同的优化方向进行相应的操作,最终评估优化效果并结束优化过程。通过这些优化方法和流程,可以不断提高汇编代码的性能和效率。

Go字符串比较:==、EqualFold与零拷贝优化实战 字符串比较是编程中最基础的文本处理操作,其本质是字节序列的相等性判定,涉及底层内存布局、Unicode编码规范与运行时性能权衡。在Go中,`==`提供O(1)平均复杂度的字节级严格比较,而`strings.EqualFold`支持大小写不敏感的Unicode语义等价,但带来rune解析开销;不当使用`strings.ToLower`则引发高频堆分配,成为GC瓶颈。技术价值在于平衡语义正确性与执行效率,适用于HTTP头校验、API路由匹配、JWT字段验证、国际化用户名比对等典型场景。本文聚焦Go语言实操路径, 阅读详情

相关推荐

WinDBG深度解析String内存布局与调试实战

String是.NET中最基础却最易被误解的类型,其本质并非字符数组而是内联存储的紧凑结构体。在WinDBG中,理解String的内存布局(对象头+MethodTable+长度字段+UTF-16字符数据)是精准定位内存泄漏、GC异常和字符串池滥用的前提。该结构直接决定对象大小计算、LOH分配阈值(42500字符)、gcroot追踪路径及du命令偏移量(+16)等关键调试行为。典型应用场景包括:高频日志导致Gen0堆积、Base64大字符串引发LOH碎片、Intern误用造成句柄表膨胀,以及P/Invoke封

as2886089的博客 533

嵌入式签名技术:用ASCII字符串实现系统可信锚点

在嵌入式系统开发中,'可信锚点(Trust Anchor)'是保障设备身份可识别、可验证、可追溯的核心机制。其原理基于确定性设计——通过将精简ASCII字符串硬编码至只读段,并结合CRC校验与物理层输出时机控制,构建轻量级但高鲁棒性的存在性自检能力。该技术不依赖加密或网络服务,却能在启动瞬间提供系统健康的第一手证据,显著提升调试效率、产线质检精度与安全审计合规性。典型应用场景包括固件完整性初筛、OTA升级链路验证、IoT设备端云一致性校验,以及团队协作中的知识传递信标。本文深入解析‘LeoXingNothi

dingguayi7025的博客 603

C++20高性能NLP词表系统:面向嵌入式与实时场景的零拷贝设计

词表(Vocabulary)是NLP流水线中连接文本与模型的关键基础设施,其加载效率、查找性能与内存行为直接影响端到端延迟与资源占用。传统Python实现虽生态丰富,但在车载语音、边缘设备等资源受限场景下,常因GIL锁、动态内存分配、字符串深拷贝及ABI不稳定性引发OOM、毛刺和启动超时。现代C++17/20凭借std::string_view零拷贝视图、constexpr编译期计算、pmr内存池与mmap内存映射等特性,可构建确定性延迟、低内存抖动、高并发安全的只读词表二进制镜像。本文聚焦工业级落地实践,

weixin_33985507的博客 477

逆向工程中的编码与加密算法识别与实战分析

在计算机安全与软件分析领域,编码与加密是数据处理的两大基础技术。编码作为信息的表现形式,如Base64、十六进制等,旨在实现数据的标准化传输与存储;而加密作为信息的保护手段,如AES、RSA等算法,通过密钥机制确保数据的机密性。理解其原理对软件逆向、漏洞挖掘及安全审计至关重要。在逆向工程中,快速识别Base64、AES等常见算法特征,并分析其模式与密钥,是解密通信协议、分析恶意代码的核心技能。本文聚焦于逆向实战,系统讲解如何通过特征识别、动态调试及工具链应用,高效处理编码转换与加密算法分析,帮助开发者掌握从

weixin_33714884的博客 363

C/C++生产级Trie实现:内存布局、性能优化与工程落地

Trie(前缀树)是一种基础而关键的字符串索引数据结构,其核心原理是通过字符路径共享实现高效前缀匹配与空间复用。在嵌入式、实时系统及高性能服务等工程场景中,Trie的性能价值远超理论复杂度——它直接决定关键词检索延迟、内存 footprint 与缓存命中率。区别于教学版链表或固定数组实现,生产级Trie需兼顾确定性内存行为、CPU缓存亲和性与多字符集兼容性,典型技术路径包括压缩数组+二分查找、内存池化分配、UTF-8码点抽象及序列化扁平化。本文聚焦C/C++底层实现细节,覆盖从裸机部署到混合接口封装的全栈实

weixin_30938149的博客 436

嵌入式GUI开发实战:emWin字体转换与颜色管理核心技术解析

在嵌入式系统开发中,图形用户界面(GUI)的渲染效率与显示效果是衡量产品体验的关键指标。其核心原理在于如何将丰富的视觉元素高效、准确地映射到资源受限的硬件平台上。字体渲染与颜色管理正是实现这一目标的两大基础技术。字体渲染技术通过将矢量字体转换为适配特定硬件的位图格式,并运用抗锯齿算法优化边缘显示,直接影响文本的可读性与美观度。颜色管理则负责在有限的硬件色彩深度下,精准映射设计色彩,确保视觉一致性。这些技术的价值在于,它们使开发者能在Flash和RAM资源紧张的环境中,构建出清晰、流畅且色彩准确的用户界面。其

weixin_34175509的博客 295

浅谈一下小波变换和EEG信号处理

浅谈小波变换,总结不是很到位,请大家指正。

qq_45045249的博客 2864

通信工程学习:什么是OLT光线路终端

OLT(光线路终端)是无源光网络(PON)的核心局端设备,负责光/电信号转换、数据处理、带宽分配及用户管理。具有高带宽、低损耗、高安全性和易维护等技术特点,广泛应用于家庭、企业及公共机构宽带接入。未来将向更高性能、智能化方向发展,结合SDN/NFV等新技术,提升网络服务质量。

limengshi138392的博客 4366

逍遥模拟器改真机参数全指南:从ARM伪装到电池传感器模拟

本文提供逍遥模拟器深度伪装实战指南,重点讲解如何通过修改ARM架构、系统属性和模拟传感器数据,使其在硬件信息、电池状态等维度逼近真实设备,有效规避应用检测。文章详细介绍了使用Magisk模块、LSPosed框架进行设备指纹伪装和动态数据模拟的策略,帮助用户实现从静态信息到动态行为的全方位真机模拟。

weixin_29279101的博客 453

FlinkCDC数据同步Bug——同步性能由于写入并行度限制无法提升问题的解决

使用FlinkCDC进行数据同步时,出现增量阶段写入并行度强制为1导致整体同步性能无法提升问题的解决方案

csdn_lan的博客 2081

从零开始学DAG:用dagitty软件快速构建因果图的5个步骤

本文为初学者提供了使用dagitty软件快速构建因果图的5个实用步骤。通过一个公共卫生研究实例,详细演示了如何从定义核心变量开始,逐步引入混杂、中介和碰撞变量,最终利用dagitty的自动分析功能识别最小充分调整集,从而科学指导研究设计与统计分析,有效提升因果推断的严谨性。

ii567的博客 800

(11-3-01 )

以太坊(Ethereum)是一种基于区块链技术的开源平台和加密货币。它于2015年由Vitalik Buterin和Gavin Wood等开发者创建,并成为比特币之后最受欢迎的加密货币之一。以太坊不仅支持加密货币交易,还为开发者和企业提供了构建去中心化应用程序的强大工具。在本节的内容中,将实型一个完整的机器学习模型项目,智能检测出以太坊区块链中的非法账户。从问题定义到模型建立和评估,再到最终的总结和建议。本实例突出了处理类别不平衡问题的重要性,并展示了如何使用多种机器学习算法来解决实际问题。此外,通过数据可

码农三叔 2171

使用FPGA实现MIPI DSI接口

通过使用FPGA,我们可以实现MIPI DSI接口,并在FPGA上生成相应的时序和电平转换电路。通过使用FPGA,我们可以实现MIPI DSI接口,并在FPGA上生成相应的时序和电平转换电路。在本文中,我们将探讨如何使用FPGA实现MIPI DSI接口,并提供相应的源代码。根据不同的发送状态,我们设置相应的输出信号。请注意,这只是一个基本的示例,用于说明如何使用FPGA实现MIPI DSI接口的发送功能。请注意,这只是一个基本的示例,用于说明如何使用FPGA实现MIPI DSI接口的发送功能。

ZdqDeveloper的博客 1708

大模型——AI对话四象限

{ "摘要": "文章揭示了90%的人不会有效与AI沟通的问题,指出简单粗暴的提问只能得到标准答案。作者提出'AI对话四象限'模型:1)双方都懂时提效;2)AI懂但需学会分层提问;3)共同探索未知领域;4)向AI传授独家知识。强调沟通技巧的重要性,认为会提问的人不会被AI替代。最后呼吁读者尝试四象限思维,与AI碰撞火花。" }

312

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

上一篇: 23、汇编编程中的浮点运算与栈初始状态
下一篇: 8、CockroachDB 数据变更捕获与数据隐私保护指南
python9snake
博客等级 码龄1天 0粉丝 1724原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值