天津大学计算机系统基础实验:手拆Hello World学内存栈汇编链接

简介:本资源是天津大学计算机系统基础课程配套的完整上机实验资料包,面向计算机专业本科生及系统底层学习者,聚焦位运算、数值表示、安全攻防与缓存优化等核心能力训练。压缩包共35个文件,含14份PDF实验指导与报告、6个C语言源码(如trans.c、csim.c)、4份Word实验文档、2个汇编文件(.asm)及bomb、ctarget等典型二进制靶场程序,辅以PNG图示与hex2raw等工具脚本,总大小112.48MB,结构清晰、开箱即用。已有921人学习下载,覆盖从基础位操作到高速缓存模拟的全链路实践环节。读者可直接复现实验环境,获取各实验的参考实现、拆弹分析思路、浮点精度验证代码、缓存模拟器源码及多份学生完成版报告(含杨亦凡等署名PDF/DOC),特别适合系统编程入门、CSAPP课程辅助学习与底层安全实践拓展。

1. 这不是“写个Hello World就完事”的系统课:天津大学计算机系统基础实验,专治对内存、栈、汇编和链接过程的模糊认知

你有没有试过:明明C代码逻辑清晰,gdb单步到某一行却突然跳进__libc_start_main;printf输出乱码,查半天发现是栈帧被自己手写的汇编踩坏了;或者make报错undefined reference to 'main',翻遍源文件确认写了main,最后发现是链接脚本里.text段起始地址设成了0x0——这些不是玄学,是《计算机系统基础》实验里最常摔跟头的硬茬。天津大学这组上机实验,不教IDE怎么点,不带跑现成Demo,而是用6个递进式实验,逼你亲手拆开hello.c:从预处理后的.i文件看宏展开,到反汇编.o看函数调用约定,再到用objdump -d对照.s手写汇编实现strlen,最后在QEMU里用GDB调试一个裸机启动的最小内核。它适合两类人:一类是刚学完《C语言程序设计》但对“变量存在哪”“函数怎么调”只有模糊印象的学生;另一类是工作三年、能写业务逻辑却说不清malloc返回的地址为什么不能直接当物理地址用的开发者。实验包里没有PPT,只有Makefile、汇编模板、内存布局图、以及一份要求你必须手填的“栈帧变化跟踪表”。


2. 实验环境搭建:为什么必须用Ubuntu 20.04 + QEMU 6.2,而不是随便找个WSL或新版Docker

2.1 环境选型的底层逻辑:工具链版本锁死是避免“别人能跑我报错”的唯一解

这套实验的编译、链接、调试链条极敏感。比如实验3要求用gcc -m32 -c生成32位目标文件,但Ubuntu 22.04默认GCC 11+已移除对-m32的完整支持(需额外装gcc-multilib且仍有符号解析问题);再如实验5的引导扇区加载,QEMU 7.0+默认启用KVM加速后,某些内存映射行为与真实BIOS差异变大,导致jmp 0x7c0:0跳转失败。天津大学实验文档明确指定Ubuntu 20.04(内核5.4)、GCC 9.4、Binutils 2.34、QEMU 6.2——这不是怀旧,而是因为所有.asm模板里的段定义(.section .text, "ax", @progbits)、重定位项(R_386_32)、甚至GDB的set architecture i386命令,在这个组合下才能100%对齐。我试过用Docker拉一个20.04镜像,但宿主机是ARM Mac,QEMU无法启用x86模拟,最终退回物理机安装双系统。关键结论:环境不是越新越好,而是要和实验中所有.ld链接脚本、.inc头文件、gdbinit配置里的ABI假设完全咬合。

2.2 三步完成可复现实验环境(含验证命令)

提示:以下命令全部在Ubuntu 20.04 Desktop x86_64真机或VM中执行,非WSL/容器。若用VM,请确保开启嵌套虚拟化(Intel VT-x/AMD-V)。

# 步骤1:安装基础工具链(注意顺序!先装binutils再装gcc) sudo apt update && sudo apt install -y build-essential gdb-multiarch qemu-system-x86 \ nasm xorriso mtools python3-pip # 验证:必须同时存在i686-linux-gnu-gcc(用于交叉编译)和x86_64-linux-gnu-gcc(用于宿主编译) i686-linux-gnu-gcc --version # 应输出gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 x86_64-linux-gnu-gcc --version # 应输出相同版本号
# 步骤2:安装指定版本QEMU(官网tarball编译,避免apt源版本漂移) wget https://download.qemu.org/qemu-6.2.0.tar.xz tar -xf qemu-6.2.0.tar.xz && cd qemu-6.2.0 ./configure --target-list=i386-softmmu,x86_64-softmmu --prefix=/usr/local make -j$(nproc) && sudo make install # 验证:qemu-system-i386 --version 必须显示6.2.0,且无"WARNING: Image format was not specified"提示 qemu-system-i386 --version
# 步骤3:配置GDB调试环境(关键!实验5/6依赖此配置) echo "set architecture i386 set disassembly-flavor intel target remote | qemu-system-i386 -S -s -kernel" > ~/.gdbinit # 验证:启动gdb后输入`show architecture`应返回`The target architecture is set to "i386".` gdb --batch -ex "show architecture" | grep "i386"

参数说明:

  • --target-list=i386-softmmu:强制编译出纯软件模拟的i386版QEMU,绕过KVM兼容性问题;
  • set architecture i386:告诉GDB按32位x86指令解码,否则disassemble会把mov eax, [ebx]错解为64位指令;
  • -S -s:QEMU启动后暂停并监听localhost:1234端口,这是GDB远程调试的握手协议。

3. 实验1-2核心:从C到汇编的逐层剥茧——预处理、编译、汇编、链接四阶段实操

3.1 预处理阶段:用cpp暴露宏的“真面目”,理解#include如何变成数千行代码

实验1第一题要求分析hello.c经预处理后的体积膨胀。很多人直接gcc -E hello.c > hello.i就结束,但这样看不到关键信息。正确做法是加-dD参数导出所有宏定义,并用grep过滤:

gcc -E -dD hello.c | grep -E "^#define|^#undef" | head -20 # 输出示例: #define __linux__ 1 #define __x86_64__ 1 #define __SIZE_TYPE__ unsigned long int #define __INTMAX_TYPE__ long int # 注意:这里暴露了`__x86_64__`宏,意味着后续编译默认走64位路径——但实验要求32位,所以必须加`-m32`

为什么这步不能跳?因为实验2的strlen.s要调用C库函数,而strlen在glibc中是弱符号,其实际实现取决于__x86_64__或__i686__宏。若预处理没检查宏,后面链接时会出现undefined reference to 'strlen'——表面是链接错误,根子在预处理阶段的架构假设错了。

3.2 编译阶段:用gcc -S生成汇编,重点盯住栈帧建立与参数传递

实验1第二题要求对比gcc -S -O0 hello.c和gcc -S -O2 hello.c的汇编差异。新手常忽略一个致命细节:-O0下GCC默认使用-fno-omit-frame-pointer,而-O2会启用-fomit-frame-pointer。这意味着:

# 生成-O0汇编(观察标准栈帧) gcc -S -O0 -m32 hello.c -o hello_O0.s grep -A5 -B5 "push.*ebp\|mov.*esp.*ebp" hello_O0.s # 输出包含: # pushl %ebp # movl %esp, %ebp # subl $16, %esp ← 为局部变量分配空间
# 生成-O2汇编(观察优化后栈帧消失) gcc -S -O2 -m32 hello.c -o hello_O2.s grep -E "pushl.*ebp|movl.*esp.*ebp" hello_O2.s # 无输出! # 取而代之的是: # leal 4(%esp), %ecx ← 用%ecx保存原%esp+4,替代帧指针

参数说明:

  • -m32:强制生成32位指令,否则在64位系统上默认生成movq等64位指令,导致后续nasm汇编失败;
  • leal 4(%esp), %ecx:leal(Load Effective Address)计算地址而非取值,此处将%esp+4存入%ecx,作为函数内访问参数的基址——这是-fomit-frame-pointer的核心技巧。

3.3 汇编与链接阶段:手写strlen.s并用ld链接,直面符号未定义的真相

实验2要求手写strlen汇编函数并链接到main.o。常见错误是直接gcc main.o strlen.s -o a.out,这会让GCC调用自带链接器,自动引入C运行时(crt0.o),导致实验失去意义。正确流程是:

# 1. 分别生成目标文件(注意:strlen.s必须用nasm,因GCC不认nasm语法) nasm -f elf32 -o strlen.o strlen.s gcc -c -m32 -o main.o main.c # 2. 手动链接(关键!禁用默认crt0和libc) ld -m elf_i386 -o myprog strlen.o main.o \ --entry main \ -Ttext 0x10000 \ -nostdlib \ -static # 参数说明: # -m elf_i386:指定32位ELF格式,否则ld可能选错架构 # --entry main:显式指定入口点为main符号,绕过_crt0 # -Ttext 0x10000:将代码段加载到0x10000,避免与系统保留区冲突 # -nostdlib:彻底禁用标准库,强制所有符号必须自实现

为什么-nostdlib后printf会炸?因为printf依赖write系统调用,而write需要通过int 0x80触发内核,但实验2的链接脚本没提供系统调用封装。此时必须用sys_write替代——这正是实验2的考点:让你意识到C库函数不是魔法,而是对系统调用的封装。


4. 实验3-4攻坚:栈帧手工构造与全局偏移表(GOT)劫持原理初探

4.1 栈帧手工构造:用gdb动态修改$esp,验证call指令的压栈行为

实验3要求在gdb中手动构造栈帧调用func。很多人卡在call指令执行后$eip没变。根本原因是:call指令会将下一条指令地址(即call后的ret地址)压栈,然后跳转。若你用set $esp = $esp - 4预留空间,但没把返回地址写进去,CPU执行完func的ret时会从错误位置取地址。

# 在gdb中调试main.o(未链接libc) (gdb) break *main+10 # 在call指令前断住 (gdb) info registers esp eip esp 0xffffd5a0 0xffffd5a0 eip 0x80491b6 0x80491b6 <main+10> (gdb) set $esp = $esp - 4 # 预留4字节存返回地址 (gdb) set {int}$esp = 0x80491bc # 将call后地址(main+16)写入栈顶 (gdb) set $eip = 0x80491a0 # 强制跳转到func入口 (gdb) stepi # 单步执行func # 此时func内ret会弹出0x80491bc,正确返回到main+16

血泪经验:set {int}$esp = ...中的{int}表示以4字节整数方式写入,若写成{char}会只写1字节,导致栈数据错位。这是实验3最易翻车的点。

4.2 GOT表原理与实验4的“重定位炸弹”

实验4要求修改.got.plt节内容,让printf调用跳转到自定义函数。这涉及两个关键概念:

  • PLT(Procedure Linkage Table):.plt节中每个外部函数有桩代码,首次调用时通过jmp *got.plt跳转;
  • GOT(Global Offset Table):.got.plt节存储函数真实地址,首次调用后由动态链接器填充。

实验4的bomb.s故意在.got.plt中埋了错误地址。修复步骤:

# 1. 先用readelf定位.got.plt节地址和大小 readelf -S bomb | grep "\.got\.plt" # 输出:[12] .got.plt PROGBITS 0804a000 001000 000014 04 WA 0 0 4 # 地址0x0804a000,大小0x14=20字节,共5个条目(printf占1个) # 2. 用gdb在运行时修改(关键!必须在printf首次调用后) (gdb) break *0x08048440 # 断在printf的PLT桩首指令 (gdb) run (gdb) x/5xw 0x0804a000 # 查看原始GOT值(全是0或占位符) # 3. 计算自定义函数地址(假设my_printf在0x08049000) (gdb) set {void*}0x0804a004 = 0x08049000 # 覆盖printf的GOT条目(偏移4字节)

避坑点:GOT条目偏移不是从0开始!.got.plt前4字节是_GLOBAL_OFFSET_TABLE_自身,第一个函数(通常是printf)从0x0804a004开始。若写错偏移,会覆盖其他函数地址,导致整个程序崩溃。


5. 避坑指南:六个实验里最常踩的五个“静默杀手”

5.1 现象:nasm报错error: parser: instruction expected

原因:.s文件用了GCC风格注释(//),但nasm只认;或/* */。实验包里部分模板混用了注释风格。
解决:用sed -i 's|//|;|g' *.s批量替换,或重装nasm时加--enable-all启用更多语法支持。

5.2 现象:ld链接时报relocation truncated to fit: R_386_16 against '.text'

原因:在16位模式下用了32位立即数,或.org伪指令地址超出段范围。实验3的bootsect.s要求.org 0x7c00,但若前面有未声明段的数据,会导致地址计算溢出。
解决:在.org前加section .text progbits align=1,并确保所有数据定义在.org之后。

5.3 现象:QEMU启动后黑屏,GDB连不上localhost:1234

原因:QEMU命令漏了-S(暂停)或-s(开启gdbserver),或防火墙拦截了1234端口。
解决:用netstat -tuln | grep 1234确认端口监听状态;若被占,改用-s -S -gdb tcp::1235换端口。

5.4 现象:gdb中stepi执行int 0x80后卡死

原因:宿主机内核禁止用户态发起系统调用(/proc/sys/kernel/unprivileged_userns_clone=0),或QEMU未启用-kernel参数加载内核。
解决:实验4/5必须用qemu-system-i386 -kernel vmlinuz -initrd initrd.img启动真实内核,而非裸机模式。

5.5 现象:objdump -d反汇编显示ff 15 00 a0 04 08,但查不到对应函数名

原因:该机器码是call *0x804a000(%rip),即间接调用GOT表地址,objdump无法解析符号。
解决:用objdump -R查看重定位表,找到0x804a000对应的符号名(如printf),再结合readelf -s确认符号值。


6. 进阶验证法:用/proc/<pid>/maps和pahole反向校验内存布局假设

6.1 用/proc/<pid>/maps验证实验4的GOT地址是否真实生效

实验4修改GOT后,仅靠GDB单步不够说服力。更硬核的验证是:在程序运行时读取其内存映射,确认.got.plt所在页确实被修改。

# 启动程序并获取PID ./bomb & PID=$! # 等待程序初始化GOT(加sleep 1) sleep 1 # 读取内存映射,定位.got.plt grep "got.plt" /proc/$PID/maps # 输出示例:0804a000-0804a014 rwxp 00001000 08:01 123456 /home/user/bomb # 地址0804a000匹配readelf结果,权限rwxp表示可读写执行(GOT必须可写) # 用gdb附加并读取该地址内容 gdb -p $PID -ex "x/5xw 0x0804a000" -ex "quit" # 若看到第2个DWORD是0x08049000,则证明my_printf地址已写入GOT

6.2 用pahole解析结构体内存布局,破解实验5的“栈溢出控制流劫持”

实验5要求覆盖返回地址触发shellcode。但现代GCC默认开启栈保护(-fstack-protector),直接strcpy(buf, input)会触发__stack_chk_fail。pahole能告诉你结构体真实布局:

# 编译带调试信息的版本 gcc -g -m32 -z execstack -fno-stack-protector -o vuln vuln.c # 用pahole查看struct布局(假设vuln.c中有struct data { char buf[16]; int key; }) pahole -C data vuln # 输出: # struct data { # char buf[16]; /* 0 16 */ # int key; /* 16 4 */ # /* size: 20, cachelines: 1, members: 2 */ # /* last cacheline: 20 bytes */ # } # 关键:`buf[16]`后紧跟`key`,偏移16。若输入20字节,第17-20字节会覆盖`key`,第21-24字节覆盖`saved ebp`,第25-28字节覆盖`return address`

参数说明:

  • -z execstack:标记栈可执行,否则shellcode无法运行;
  • -fno-stack-protector:关闭栈金丝雀,否则覆盖key会触发检测;
  • pahole -C data:精准定位key在结构体内的偏移,比凭空猜测可靠10倍。

6.3 一个让我少熬三次夜的习惯:每次修改汇编后,必做三件事

  1. 用ndisasm -b32 xxx.o反汇编目标文件:确认nasm生成的机器码和你写的汇编指令100%一致。曾有一次mov eax, 0x12345678被nasm优化成mov eax, dword 0x12345678,但实验要求必须用mov eax, 0x12345678的原始形式,ndisasm立刻暴露了差异。
  2. 用readelf -a xxx.o | grep -A10 "Symbol table"检查符号类型:确保main是FUNC GLOBAL DEFAULT而非NOTYPE,否则链接器找不到入口。
  3. 用strace -e trace=brk,mmap,mprotect ./xxx观察内存操作:实验5的shellcode需要mprotect改写内存权限,若strace没看到mprotect调用,说明你的系统调用封装有误。

从那以后我每次写完.s文件,都强制走一遍这三步——不是为了炫技,是怕凌晨三点对着黑屏QEMU发呆时,才发现是mov写成了move这种低级错误。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

从神经元到反向传播:重建神经网络基础的完整学习路径

从神经元到反向传播:重建神经网络基础的完整学习路径

去年年底那阵子&#xff0c;我把各种CNN示例代码跑得飞起&#xff0c;模型能出结果、准确率也能看&#xff0c;但一被问到“卷积核到底为什么能提取边缘”“反向传播的梯度是怎么一层层流回去的”这类问题&#xff0c;我就只能支支吾吾。这让我意识到一个尴尬的事实&#xff1a…

2026/10/20 20:09:29 阅读更多 →
Spring Boot电动汽车充电服务系统设计与实现:完整业务闭环解析

Spring Boot电动汽车充电服务系统设计与实现:完整业务闭环解析

做电动汽车充电服务系统这类选题&#xff0c;在高校毕业设计里几乎年年都有&#xff0c;但真正做出“能答辩、能演示、能说明白”的&#xff0c;反而不多。Spring Boot Java 的技术栈看似简单&#xff0c;真正落地时牵扯到充电桩状态流转、订单计费、故障上报、运维闭环&#…

2026/10/20 20:09:29 阅读更多 →
深度学习故障诊断入门:一维卷积与注意力机制的轴承分类实战

深度学习故障诊断入门:一维卷积与注意力机制的轴承分类实战

简介&#xff1a;面向深度学习故障诊断入门者的完整示例包&#xff0c;围绕数据预处理、模型搭建、模型训练三个核心环节展开&#xff0c;适合刚接触智能运维、设备健康管理的学生或工程师用来快速跑通基础流程。压缩包共57个文件&#xff0c;其中40个mat数据文件用于实验验证&…

2026/10/20 20:09:29 阅读更多 →

最新新闻

TensorFlow鞋类识别实战:Fashion MNIST图像分类全流程

TensorFlow鞋类识别实战:Fashion MNIST图像分类全流程

前段时间重新整理之前的深度学习实验笔记&#xff0c;翻到鞋类识别&#xff08;Fashion MNIST&#xff09;这个项目时&#xff0c;觉得特别值得拿出来单独写一篇。原因很简单&#xff1a;很多人入门深度学习时&#xff0c;都会被建议先跑通手写数字识别&#xff08;MNIST&#…

2026/10/20 20:57:37 阅读更多 →
用AI辅助Kamailio路由排错:一场人机讨论实录与故障切换实践

用AI辅助Kamailio路由排错:一场人机讨论实录与故障切换实践

最近接手一套老的SIP通信平台&#xff0c;核心信令是Kamailio撑着。业务要新增一个较复杂的路由策略&#xff1a;同一个主叫号码&#xff0c;在不同时间段、针对不同被叫前缀&#xff0c;要分别走不同的网关&#xff1b;而其中一路网关做故障切换时&#xff0c;还要保证已经建立…

2026/10/20 20:57:37 阅读更多 →
LibVLC轻量级视频播放模块:嵌入C/C++工程的硬件解码方案

LibVLC轻量级视频播放模块:嵌入C/C++工程的硬件解码方案

简介&#xff1a;本资源是一份基于C/C与VLC开源库开发Windows视频播放器的完整工程实践包&#xff0c;面向具备基础C编程能力、希望掌握多媒体开发技能的中级开发者及高校课程设计学习者。资源聚焦于在Visual Studio 2022环境下集成libvlc实现视频加载、播放控制、窗口渲染等核…

2026/10/20 20:57:37 阅读更多 →
AI Agent创业团队如何配置一支高效的Harness Engineering团队

AI Agent创业团队如何配置一支高效的Harness Engineering团队

1. 为什么需要一支专门的Harness Engineering团队先从一个很现实的场景说起&#xff1a;你所在的创业团队花三个月做出了一个基于大模型的Agent产品Demo&#xff0c;演示给投资人看时效果炸裂&#xff0c;但真正进入客户试用阶段&#xff0c;问题接踵而来——模型给出正确意图却…

2026/10/20 20:57:37 阅读更多 →
视觉语言模型与RGB-D感知融合:三条进化主线与工程实践

视觉语言模型与RGB-D感知融合:三条进化主线与工程实践

1. 从 Transformer 到多模态感知的演进逻辑视觉语言模型和 RGB-D 感知这两个方向&#xff0c;过去几年基本是各走各的路。做 VLM 的人盯着图文对齐、指令跟随、视觉问答这些任务&#xff0c;做 RGB-D 的人则埋头于点云配准、深度补全、SLAM 建图。但最近一年&#xff0c;这两条…

2026/10/20 20:57:37 阅读更多 →
VTI介质地震波数值模拟:MATLAB实现与各向异性正演避坑指南

VTI介质地震波数值模拟:MATLAB实现与各向异性正演避坑指南

简介&#xff1a;这份资源面向地震勘探与地球物理方向的学习者和研究者&#xff0c;提供一套基于Matlab的VTI介质地震波场数值模拟程序&#xff0c;用于分析各向异性介质中地震波的传播规律。VTI介质在垂直与平行层理方向上纵波速度存在差异&#xff0c;是实际地壳中常见的各向…

2026/10/20 20:56:32 阅读更多 →

日新闻

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/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

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

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

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

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

如果你的信息流最近也天天刷到“机器人大脑”这个词&#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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →