loop指令深度解析:计数器循环的语义、边界与调试实战

前阵子帮人看一段老汇编代码,单步跟到一条loop指令时,旁边同事问了一句:ecx 现在已经是 0 了,这条到底跳还是不跳?我愣了一下,因为太多人把loop当成“死循环指令”来记,实际上它的语义很明确,只是越简单的指令越容易被忽略细节。今天就把我这些年读代码、写汇编、调 bug 过程中积累的loop指令经验全部摊开聊一遍,内容包括指令本质、边界情况、踩坑案例、编译器视角,以及调试实战。无论你是刚从 ARM 转 x86 的开发者,还是在逆向老程序、写引导代码,这篇文章都应该能帮你少走不少弯路。

1. 从一段简单循环说起:loop指令到底是什么

1.1 高级语言的 for 循环,在汇编里长什么样

先用大家最熟的 C 语言举个例:

for (int i = 0; i < 100; i++) { buf[i] = i; }

如果让你把它手写成经典 x86 汇编,最自然的写法是这样:

mov ecx, 100 ; 循环次数 xor eax, eax ; i = 0 lea edi, [buf] loop_start: mov [edi + eax], al ; buf[i] = i inc eax ; i++ dec ecx ; 计数减一 jnz loop_start ; 计数非零则继续

这个写法里,循环计数、数组下标、比较跳转是分开处理的。每次循环要执行dec和jnz两条指令才能完成“减一判断跳转”三件事。而loop指令想做的,就是把这三件事合并成一条:自动减计数、自动判断零、自动跳转。

mov ecx, 100 ; 循环次数 xor eax, eax lea edi, [buf] loop_start: mov [edi + eax], al inc eax loop loop_start ; ecx--,若 ecx != 0 则跳回 loop_start

从功能上讲,上面两种写法是等价的。但从设计角度看,loop是把“循环控制”这件事整体封装成了一条复合指令。这也是 x86 指令集里非常有历史感的一类设计。

1.2 一条指令管一个循环:设计意图与历史缘由

loop指令的全称叫“Loop Control with CX Counter”,它最早出现在 8086 处理器时代。那个年代的内存和代码密度都非常宝贵,指令能短则短。像loop这种由硬件直接完成的“计数器递减 + 跳转”组合,只需要极短的机器码,比起两条独立指令省下的字节数相当可观。

你可以把loop理解成一种“专用循环摇杆”:它绑定了一个专用的计数器寄存器(32 位模式下是 ECX,64 位模式下是 RCX),每次执行自动完成一次递减,然后看计数器是否为 0。不为 0 就跳回循环头,为 0 就落到下一条指令继续执行。

所以本质上来讲,loop不是“让你无限循环的指令”,而是“让你用计数器控制循环次数的指令”。它自带两个动作:先递减,再判断。这个顺序很多人会搞反,后面我会专门讲它有多坑。

1.3 不是所有架构都有 loop:x86 的“特殊待遇”

这里顺便插一句,很多从 RISC-V 或者 ARM 转到 x86 的同学,第一次看到loop会有点不适应。因为在大多数精简指令集架构里,你找不到一个专门绑定计数器的循环指令。RISC-V 里要做循环,通常就是一个普通的寄存器递减加上条件跳转,比如:

li t0, 100 loop_start: # 循环体 addi t0, t0, -1 bnez t0, loop_start

ARM 上有CBZ、CBNZ这类“比较为零就跳”的指令,但也没有像 x86 这样把“减一 + 判零 + 跳转”焊死成一个专用指令族。这正是 x86 指令集“丰富且历史包袱重”的典型体现:硬件为你做了很多组合动作,方便是方便,但也带来了边界条件的坑。

2. 亲手写一个基于 loop 的循环:格式、语义与边界

2.1 指令格式与计数器匹配

loop指令的完整格式是loop 目标标签。它本质上是一条短跳转指令,跳转范围是相对当前下一条指令的 -128 到 +127 字节。也就是说,如果你的循环体特别大,几百个字节,loop可能直接跳不过去,汇编器会报错。

计数器方面,切记:实模式下和 32 位模式下用 CX/ECX,64 位模式下用 RCX。很多人喜欢百年不变地写ecx,在 64 位代码里有时没问题,有时就会出诡异问题,因为地址大小和操作数大小会决定硬件到底读取哪个计数寄存器。最稳妥的做法是:写 32 位汇编就统一用 ECX,写 64 位汇编就统一用 RCX。

2.2 一个完整可运行的求和示例

下面是一个 32 位风格的例子,逻辑是计算 1 到 100 的累加和,结果放到 eax 里:

xor eax, eax ; 清空累加器 mov ecx, 100 ; 循环 100 次 mov edx, 1 ; 从 1 开始加 sum_loop: add eax, edx inc edx loop sum_loop ; 此时 eax = 5050

跑完以后 eax 的值是 5050,这是 1+2+…+100 的标准结果。这个例子虽然简单,但足以说明loop的控制逻辑:它管的是“循环次数”,而不是“循环变量的值”。循环变量本身(这里是 edx)需要你在循环体里自己去维护。

2.3 最容易踩的第一个边界:初始计数为 0 会怎样

这是我认为loop指令最反直觉的一个点,也是面试和调试里经常考到的地方。

先听结论:如果 ECX 初始值是 0,loop指令并不会“一次都不执行”直接跳过,而是会循环 2^32 次。64 位同理,会是 2^64 次。

原因是这样的:常规理解里,像while (cnt-- != 0)这种写法,如果 cnt 一开始是 0,确实一次都不会进入循环体。但loop的硬件实现顺序是“先减一,再判零”。初始 ECX = 0,减一之后变成 0xFFFFFFFF,非零,于是跳转。这就是一个极其隐蔽的死循环来源。

所以很多手写汇编的老代码里,你会看到loop前面通常会先来一条jecxz(或jrcxz)做“计数为 0 直接跳过”的防护:

mov ecx, count jecxz done ; 如果 count 为 0,直接跳过 repeat: ; 循环体 loop repeat done: ; 继续

这个模式非常重要。如果你写代码时面对的循环次数是个变量,且有可能为 0,必须自己加判断。硬件不会帮你做这个判断,它只会老老实实先减再跳。

loop家族还有一个近亲:loope/loopz(相等时循环)和loopne/loopnz(不等时循环)。它们的判断条件除了计数器非零,还要额外检查 ZF 标志位。比如loope要求“计数非零且 ZF=1”才跳转。这类指令适合做扫描场景,但也带来了新的坑,因为循环体里任何一条改变 ZF 的指令都会影响判断基准,用起来要格外小心。下表总结了三种形式的跳转条件:

指令计数器判断额外标志判断备注
loopRCX/ECX ≠ 0无最常用
loope/loopzRCX/ECX ≠ 0ZF = 1适合相等比较扫描
loopne/loopnzRCX/ECX ≠ 0ZF = 0适合不等比较扫描

3. 用 loop 指令最常踩的几个坑

3.1 循环体里动了计数器:计数器被污染是最常见事故

loop的计数器是全局统一的寄存器,不是硬件单独隔离的。这就意味着,一旦你的循环体里有任何代码修改了 ECX/RCX,整个循环次数就失控了。

比如下面这段“看似正常”的代码:

mov ecx, 10 loop_start: mov ecx, 5 ; 重新给 ecx 赋值,循环次数当场爆炸 ... loop loop_start

第一次进入循环体就把 ecx 改成 5,然后loop每次减一,从 5 数到 0 就退出,总共只循环了 5 次,而不是 10 次。更隐蔽的情况是,你调用了某个子函数,子函数内部把 ecx 用作临时变量,返回后没恢复,你在循环里一call,计数器就全乱了。

我曾经排查过一个排序函数的 bug,现象是数组只排了一半就莫名其妙停止。单步跟了很久才发现,问题不在排序逻辑,而是某次优化时往循环里插入了一段查找子程序,子程序用了 ecx 当临时计数器,出来没恢复。所以我的建议很简单:除非循环体短到一目了然,否则别默认计数器是安全的。

3.2 循环里调用函数:调用约定让 ecx 成为“高危寄存器”

这其实是上一点的延伸,但在 x86 体系里尤其突出。很多 32 位调用约定里,ECX 属于调用者保存寄存器,也就是“被调函数可以随意改,你要自己保护”。你在循环里call一个函数,函数内部十有八九会用 ecx,等你回来再执行loop,计数已经面目全非。

典型的保护方式是压栈:

mov ecx, 100 big_loop: push ecx ; 保存计数 call some_function ; 这个函数内部可能会改 ecx pop ecx ; 恢复计数 loop big_loop

这里有个性能上的反直觉点:为了保住计数器,你额外多做了push和pop两条指令,那loop相对dec + jnz的指令数优势就完全没了,甚至更慢。这也是为什么下面的问题会出现。

3.3 性能迷思:为什么现代编译器几乎不生成 loop

很多人有这种想法:既然loop一条指令顶三条,那它应该更快、代码更紧凑,为什么编译器生成循环时不用它?

实际上现代处理器上,loop指令往往不被原生支持为单条快速指令,而是被译码器拆成多条微操作,还要维护一个“ECX/RCX 递减 + 比较 + 跳转”的长依赖链,分支预测器也不好对它做高级优化。在很多处理器上,它的速度并不比dec + jnz快,某些阶段甚至更慢。

代码紧凑性是它为数不多的优势,但这个优势只在极度在意二进制体积的场景(比如引导扇区、老式 ROM 代码)里才值得考虑。现代编译器默认追求的是速度、可预测性和更灵活的分支处理,所以你看主流编译器生成的循环,几乎清一色是dec/sub+jcc,绝不会拿loop来“优化”。这是个很反直觉的结论:名字叫 loop 的指令,恰恰不适合给现代优化循环用。

4. 编译器如何理解 loop:从指令级到优化级

4.1 高级语言的 for 循环,到机器码经历了什么

为了说清楚编译器为什么不用loop,值得展开讲一下现代编译器生成循环的思路。一个高级语言的for循环,经过编译后通常不是简单的“每轮判断一次”,而是被转换成一个由“初始化、条件判断、循环体、步进、回跳”组成的标准控制流。

在这个控制流里,循环次数只是一个普通的运行时值,它可以放在任意通用寄存器里,不一定非要在 ECX。编译器会综合整个函数的寄存器分配情况,哪个寄存器空闲、哪个寄存器依赖链更短,就把循环计数放哪里。loop指令强行绑定了 ECX/RCX,等于限制了编译器的自由,在很多情况下反而会加剧寄存器压力。

4.2 现代优化器眼中的循环优化套路

循环是整个程序里最值得优化的一块,编译器会在上面做大量变换。常见的有:

  • 循环展开:把连续几轮合并成一轮,减少跳转和判断的开销。
  • 强度削减:把乘法变成加法,把循环里的复杂计算变简单。
  • 循环不变量外提:把每轮都不变的计算挪到循环体外。
  • 向量化:用 SIMD 指令一次处理多个元素。

这些优化都建立在编译器能“看穿”整个循环结构的前提下。如果你在一个 C 函数里用asm嵌入了loop指令,那这个循环体对编译器来说就变成了一个黑盒。编译器无法推断循环次数、无法分析数组访问边界、也无法做向量化,等于主动放弃了所有循环优化。

我见过不少新人在写性能敏感代码时,想用内联汇编loop来“加速”,结果就是代码又慢又难维护。我的态度很明确:手写loop的本质,是在告诉编译器“这块你别管了,我来”,这意味着你必须有足够的理由证明自己比优化器更懂这段代码的循环模式。绝大多数情况下,这个前提不成立。

4.3 手写 loop 仍然有价值的几个场景

说了一堆别用的理由,但手写loop也并非一无是处。我自己实际用到它的场景主要有三个:

第一个是引导代码和极简环境。这类环境里没有库、没有标准运行时,代码体积和依赖控制到极致,用loop省几个字节很有意义。

第二个是逆向工程和古董代码阅读。老程序里到处是loop,你不懂它的精确语义,根本没法往下看。尤其是loope/loopne带着 ZF 判断的扫描型循环,读起来很容易误判执行次数。

第三个是教学和调试。用loop写一个极短循环,对比dec + jnz,对理解 CPU 流水线、寄存器依赖、分支预测都有帮助。

5. 调试与实战:在真实项目里诊断 loop 相关的问题

5.1 单步跟踪时怎么看计数器变化

调试loop相关的代码,我最常用的办法就是给loop指令下断点,每次停住后观察 ECX/RCX 的当前值。正常的循环,ECX 应该呈现规律的递减序列:100、99、98……直到 0。如果中途某一次停住时发现 ECX 变成了一个毫无规律的大数,那基本可以断定循环体内有地方污染了计数器。

在常见调试器里观察寄存器是基本功,但有一个小技巧值得提:不要只盯着 ECX,还要看 ZF。如果代码用的是loope/loopne,那么跳不跳不仅取决于计数器,还取决于 ZF。循环体内某条test、cmp甚至inc指令恰好把 ZF 改了,loope就可能提前退出或者多跑几轮。这种 bug 只看 ECX 是永远看不出来的,必须把标志位一并纳入视野。

5.2 一个典型排查案例:图像数据处理循环越界

我以前调试过一个处理灰度图像数据的函数,逻辑是逐像素做阈值比较,大概是“对 N 个像素做处理”的套路。现象是处理后的图像总有一段区域数据不对,像被随机值覆盖了。

排查链是这样走的:

  1. 先确认循环次数初始值。断点打在loop上,第一轮停住时看计数器,发现值比预想大了一圈,怀疑内存里读到的总数错了。
  2. 再单步几次,发现计数器不是均匀递减,中间某次忽然跳变——说明循环体里某个运算写了同一个寄存器。
  3. 检查循环体里的指令,发现有一处lea ecx, [ecx + eax]之类的地址计算,顺手把循环计数器也用了。
  4. 修正方法是把地址计算换到别的寄存器,或者临时压栈保存计数。

这个 bug 的根因完全不是loop的问题,但这正是loop调试的典型难点:计数器是全局共享资源,代码一复杂就容易被连带修改。排查时,我始终把握一个原则:先假设计数器被污染,验证它是否精确递减;再看跳转条件里有没有被标志位干扰。这两个方向能覆盖绝大多数loop相关的疑难杂症。

5.3 引导代码和嵌入式环境里使用 loop 的注意点

最后聊一下引导代码和嵌入式这类“真正必须用loop”的场景。在这里有几个细节容易被忽略。

第一个是短跳转范围。loop是相对短跳转,目标必须在 -128 到 +127 字节之间。启动代码里的循环体通常很小,没问题,但如果你在循环里展开了一些初始化逻辑,代码膨胀超过 127 字节,汇编阶段就会报“跳转超出范围”。解决办法有两种:一是把loop改成dec + jnz,jnz有近跳转版本,范围大得多;二是把目标标签往循环体中间挪,让跳转距离缩短。

第二个是段寄存器和地址模式的变化。引导代码经常要切换实模式、保护模式,或者手动设置段寄存器。loop跳转的是偏移地址,如果执行过程中段基址变了,同一个标签实际访问的内存位置也会变。切换模式的那条指令附近最好不要用loop跨着跳。

第三个是中断处理。如果循环过程中来了中断,中断处理程序进去之前会保存现场,出来之后恢复现场,计数器一般没事。但如果你的中断处理程序本身不完整,没有正确保存和恢复 ECX/RCX,等中断返回后loop的计数就乱了。这种问题极其难查,因为现象是“概率性死循环”,和中断触发时机强相关。

我自己在实际写这类代码时的习惯是:除非循环体短到不会超过 127 字节,否则一律用dec + jnz,保留loop给那些确认不可能溢出的场景。看起来保守,但省掉的是半夜调跳转范围报错的时间。

最后再分享一个小技巧。写loop相关汇编时,我习惯在注释里把“计数初值、退出时计数器值、循环体内哪些指令使用了计数器”三行写清楚。这个习惯帮我避免了很多次“看起来循环正常、实际上计数器早就被改”的隐性事故。毕竟汇编代码的维护者往往是几个月后的自己,多写两行注释,比少调一次 bug 更实在。

相关新闻

Agent越用越傻?自适应知识迁移机制设计与工程落地

Agent越用越傻?自适应知识迁移机制设计与工程落地

Agent上线没几天&#xff0c;业务方跑过来问“它怎么感觉越来越不聪明了”。这个问题我最近一年反复听到——模型部署时跑得很顺&#xff0c;一旦遇到新领域的知识、新格式的数据&#xff0c;性能掉得比想象中快得多。传统做法是拉数据重新微调&#xff0c;但Agent场景里&#…

2026/10/20 4:23:38 阅读更多 →
端侧智能体函数调用实战:FunctionGemma架构与落地

端侧智能体函数调用实战:FunctionGemma架构与落地

1. 只会聊天的机器人帮不了你&#xff1a;行动型智能体的门槛在哪过去一年多&#xff0c;我一直在折腾端侧智能体&#xff0c;有一个感受特别深&#xff1a;大多数所谓“智能体”&#xff0c;本质还是一个会接话的聊天机器人。你说“帮我把空调调到26度”&#xff0c;它能回你一…

2026/10/20 4:23:38 阅读更多 →
电赛E题追踪云台全考点:OpenMV与STM32闭环调试实战笔记

电赛E题追踪云台全考点:OpenMV与STM32闭环调试实战笔记

简介&#xff1a;这份资源面向参加2023年全国大学生电子设计竞赛E题&#xff08;运动目标控制与自动追踪系统&#xff09;的本科组选手及嵌入式学习者&#xff0c;聚焦OpenMV视觉识别与STM32云台控制的协同实现。压缩包共2个文件&#xff0c;包含1个rar工程归档与1个Python脚本…

2026/10/20 4:23:38 阅读更多 →

最新新闻

VMware中安装Windows 11:绕过TPM与硬件检查完整指南

VMware中安装Windows 11:绕过TPM与硬件检查完整指南

如果你要装 Windows 11&#xff0c;但电脑太老、没有 TPM 2.0&#xff0c;或者你现在用的是 Mac、Linux&#xff0c;想在虚拟机里先跑起来看看效果&#xff0c;那这篇文章就是给你准备的。我在 VMware 里完整走了一遍 Win11 的安装流程&#xff0c;从新建虚拟机、加载镜像、绕过…

2026/10/20 5:06:58 阅读更多 →
微信小程序火车票查询源码解析:从请求封装到列表渲染的完整实践

微信小程序火车票查询源码解析:从请求封装到列表渲染的完整实践

简介&#xff1a;这是一份面向微信小程序初学者与前端开发者的实战型源码资源&#xff0c;围绕火车票查询场景&#xff0c;演示如何在小程序中调用接口完成车次检索与结果展示&#xff0c;适合作为课程设计、练手项目或二次开发的基础模板。压缩包共23个文件&#xff0c;约11KB…

2026/10/20 5:06:58 阅读更多 →
AI大战PowerShell:脚本跑不通的四大根源与解决模板

AI大战PowerShell:脚本跑不通的四大根源与解决模板

你有没有过这样的经历&#xff1a;手头一堆重复性的系统任务&#xff0c;实在懒得逐条敲命令&#xff0c;随手把需求丢给 AI 助手&#xff0c;AI 也很爽快地吐出一段 PowerShell 脚本。你复制、粘贴、回车&#xff0c;然后看着满屏红色报错发呆。我最近连续处理了好几个这种场景…

2026/10/20 5:06:58 阅读更多 →
LangChain 1.0 Community生态全解析:第三方集成与迁移实践指南

LangChain 1.0 Community生态全解析:第三方集成与迁移实践指南

写这个东西之前我想先交代一个背景&#xff1a;如果你是从 LangChain 0.x 一路用上来的老用户&#xff0c;应该都经历过那种"不装不对、装多也错"的依赖地狱。新项目还没跑起来&#xff0c;先花一晚上解决包冲突&#xff1b;好不容易跑通了&#xff0c;换一个模型厂商…

2026/10/20 5:06:58 阅读更多 →
智能车变道全链路拆解:从感知到控制的算法与工程实践

智能车变道全链路拆解:从感知到控制的算法与工程实践

前方两公里就是出口&#xff0c;右侧车道一台速度明显偏慢的货车正好堵住去路&#xff0c;后视镜里还有一辆试图从右侧挤上来的小车。老司机大概扫一眼&#xff0c;抬脚、打灯、小幅度加速&#xff0c;变道一气呵成。但把这个动作交给一台智能车时&#xff0c;问题就复杂了&…

2026/10/20 5:06:58 阅读更多 →
AI面试八股文-17_17-AI 编程工具与自主 Coding Agent 面试题

AI面试八股文-17_17-AI 编程工具与自主 Coding Agent 面试题

pdf版下载链&#xff1a;https://pan.quark.cn/s/9cc742e9c2a8 17 AI 编程工具与 Coding Agent&#xff1a;原理、评测与工程实践 更新&#xff1a; 2026-10-12 难度&#xff1a; ⭐⭐⭐⭐ 考点&#xff1a; Coding Agent、Harness、沙箱、权限、Skills、长任务、评测与工具选…

2026/10/20 5:05:58 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →