x86 汇编入门(06):文件读写
程序不能只跟终端打交道。配置文件、日志、数据文件——都离不开文件 I/O。这一篇用 06_file_io.asm 完成「写入 → 关闭 → 重新打开 → 读取 → 输出」全流程,也是本系列的收官之作。 这是「x86 汇编入门」系列的第 6 篇,也是最后一篇。前五篇覆盖了输出、输入、算术、循环和函数。这一篇综合运用文件相关系统调用,并回顾整个系列的学习路径。 一、文件相关系统调用 调用号 名称 作用 2 sys_open 打开或创建文件 0 sys_read 从 fd 读取 1 sys_write 向 fd 写入 3 sys_close 关闭 fd sys_open 参数: 寄存器 含义 rdi 文件路径(以 \0 结尾的 C 字符串) rsi 打开标志 flags rdx 权限 mode(创建文件时有效) 返回值 rax 文件描述符;失败时为负数 常用 flags(可位或组合): 标志 值 含义 O_RDONLY 0 只读 O_WRONLY 1 只写 O_CREAT 0x40 不存在则创建...
x86 汇编入门(05):函数调用与递归阶乘
call 和 ret 是汇编里最重要的「接力棒」。没有它们,代码只能从上到下一条道走到黑。这一篇我们拆开函数调用的完整机制,并用递归计算 5 的阶乘——在汇编里亲眼看到栈是怎么一层层长高的。 这是「x86 汇编入门」系列的第 5 篇。上一篇用跳转实现了循环。这一篇通过 05_function.asm,理解 call / ret、栈帧和 x86_64 调用约定。 一、call 和 ret 做了什么?123call factorial ; ① 把「下一条指令地址」压栈 ② 跳到 factorial...ret ; 从栈弹出地址,跳回去 可以把它想成:call 留下回城坐标,ret 按坐标回去。栈就是存放这些坐标的地方。 二、栈帧:函数自己的「工作台」每次进入函数,标准开场是: 12345678factorial: push rbp ; 保存调用者的帧指针 mov rbp, rsp ; 建立当前帧 push rbx ; 保存要用的 callee...
x86 汇编入门(04):循环与条件跳转
高级语言里写 for (i = 1; i <= 10; i++) 一行搞定。汇编里没有 for,只有比较 + 跳转。这一篇用 04_loop.asm 打印 1 到 10,把循环拆成你能看见的每一步。 这是「x86 汇编入门」系列的第 4 篇。上一篇实现了算术和数字打印。这一篇通过 04_loop.asm,学习条件跳转指令和循环结构的汇编写法。 一、比较与跳转cmp a, b 做减法但不保存结果,只设置 CPU 标志位。然后根据标志位跳转: 指令 条件 je 相等 (ZF=1) jne 不相等 jl 小于(有符号) jle 小于等于 jg 大于 jge 大于等于 jmp 无条件跳转 二、用跳转拼出循环04_loop.asm 的逻辑等价于: 123for (int i = 1; i <= 10; i++) { printf("当前数字: %d\n", i);} 汇编实现: 1234567891011121314mov r12, 1 ...
x86 汇编入门(03):算术运算与数字转字符串
终端只能显示字符,不能直接显示数字 42。所以汇编里做算术只是第一步,更麻烦的是把结果「翻译」成 '4' 和 '2' 再送出去。这一篇我们练四则运算,并实现一个可复用的 print_number 子程序。 这是「x86 汇编入门」系列的第 3 篇。前两篇解决了输出字符串和读取输入。这一篇通过 03_calc.asm,掌握算术指令和整数转 ASCII 的核心技巧。 一、基本算术指令对两个常数 42 和 8 演示四则运算: 指令 含义 示例结果 add dst, src 加法 42 + 8 = 50 sub dst, src 减法 42 - 8 = 34 imul dst, src 有符号乘法 42 × 8 = 336 idiv src 有符号除法 42 ÷ 8 = 5 … 2 除法要特别注意:idiv 用 rdx:rax 作为被除数。执行前需要 cqo 把 rax 符号扩展到 rdx: 1234mov rax, num_acqo ...
x86 汇编入门(02):读取用户输入
上一篇程序只会「说」,不会「听」。真实程序几乎都要处理输入——命令行参数、用户键入、网络数据,本质都是往缓冲区里塞字节。这一篇我们学 sys_read,并认识汇编里的第三个地盘:.bss 段。 这是「x86 汇编入门」系列的第 2 篇。上一篇用 sys_write 输出了 Hello World。这一篇通过 02_input.asm,实现读取键盘输入并回显。 一、三段式内存布局到本篇为止,汇编程序的「地盘」凑齐了: 段 用途 类比 .data 已初始化的常量(字符串、数字) 写死在程序里的便签 .bss 未初始化的变量(缓冲区) 运行时用的空白草稿纸 .text 可执行指令 操作步骤 .bss 里的空间在程序加载时自动清零,用 resb N 预留 N 个字节: 12section .bss name_buf resb 64 ; 预留 64 字节缓冲区 二、sys_read 怎么用?sys_read 是 sys_write 的镜像操作: 寄存器 含义 rax 0(调用号) rdi 文件描述符(0 = st...
x86 汇编入门(01):Hello World 与系统调用
每个程序员的第一课都是 Hello World。汇编版也不例外——只不过这次没有 printf,没有标准库,只有你和内核之间四条寄存器传话。搞懂这一篇,你就摸到了 Linux 程序最底层的「打电话」方式。 这是「x86 汇编入门」系列的第 1 篇。上一篇我们搭好了 Docker 环境和编译流程。这一篇从 01_hello.asm 出发,理解汇编程序的基本结构和 Linux 系统调用机制。 一、程序长什么样?汇编程序可以粗分为两块:数据放哪里,代码放哪里。 123456789section .data msg db "Hello, Assembly World!", 10 msg_len equ $ - msgsection .text global _start_start: ; ... 系统调用写在这里 ... 部分 作用 section .data 存放已初始化的数据,比如字符串 section .text 存放可执行的机器指令 global _start 告诉链接器:程序从这里开始执行 ...
x86 汇编入门(00):环境搭建与编译流程
学汇编,最怕的不是指令难记,而是环境配半天就跑不起来。这一篇我们不写任何寄存器,只把「能编译、能运行」这件事搞定。后面 6 篇会在这个环境里,一步步写出真正的汇编程序。 这是「x86 汇编入门」系列的第 0 篇。本系列基于 NASM 语法 + Linux x86_64 系统调用,在 Docker 容器中编译运行,不依赖 C 标准库。下一篇我们从 Hello World 开始,认识第一个系统调用。 一、为什么这样学?你可能听过汇编「难学、难调试、离硬件近」。这些都没错,但入门阶段更大的障碍往往是:工具链太杂。 本系列的选择很克制: 选择 原因 NASM 语法清晰,注释友好,Linux 社区资料多 Linux syscall 不链接 libc,直接跟内核对话,看清程序最底层在干什么 x86_64 64 位寄存器更多,调用约定也更规整 Docker 一次配好 nasm / ld / gdb,Mac 和 Linux 行为一致 可以把它想成学开车:我们先找一条封闭赛道(Docker),车况统一(Ubuntu 22.04 + 工具链),...
现代 C++ 实战(00):环境搭建与项目导览
学现代 C++,最怕的不是语法多,而是 demo 跑不起来、编译器版本对不上、CMake 报错看不懂。这一篇我们不讲任何语言特性,只把「能编译、能运行、知道 39 个 demo 在哪」这件事搞定。后面 27 篇会在这个环境里,逐个拆解 C++11 到 C++23 的核心特性。 这是「现代 C++ 实战」系列的第 0 篇。本系列基于 ref/cpp_demo 的 39 个独立 CMake 项目,在 Docker 或 macOS 本地编译运行。下一篇我们从 CMake 与现代构建说起,搞懂 FetchContent 依赖管理。 一、为什么这样学?你可能已经会写 C++,但面对 C++11 之后的「现代 C++」,往往有这样的困惑:特性太多、标准迭代太快、书和博客各说各话。本系列的选择很克制: 选择 原因 Demo 驱动 每个知识点对应可编译、可运行的代码,不是纸上谈兵 39 个独立项目 每个子目录自包含,可单独拷贝到其他机器 统一 build.sh 所有 demo 同一套构建命令,降低切换成本 Docker + macOS 双环境 容器保证 Linux...
实战进阶:用 MCP 打造多工具 Agent
上一篇我们手写了一个”单机游戏”式的 Agent——工具是自己定义的、能力是固定的,就像一个只能在自家小区逛的孩子。今天我们要让它”联网”——通过 MCP 协议接入外部工具生态,瞬间获得读写文件、查询数据库、操作 GitHub 等成千上万种能力。就像游戏角色走出新手村,接入了整个世界地图,可以接任务、买装备、组队打副本。 这是「小白讲 AI」系列的第 20 篇,也是 Agent 系列的最终章。从第 5 篇的一条 Prompt,到今天用 MCP 打造多工具 Agent——我们走了一段不短的路。这一篇既是实战教程,也是对整个系列的总结和回顾。 一、上一篇的 Agent 缺什么?回顾一下第 19 篇手写的研究助手 Agent——它能跑,但有几个明显的限制: 工具是硬编码的:只有 search 和 fetch_url 两个工具,想加新工具就得改代码 不能操作本地文件:Agent 查到了信息却没法保存下来 单打独斗:只有一个 Agent 在干活,没有分工协作 代码量随复杂度增长:工具越多、逻辑越复杂,手写代码越难维护 今天我们要解决这些问题: 用 MCP 让 Agent 动态...
动手构建你的第一个 Agent:从零到"能自己干活"
前面 6 篇文章,我们学了发动机原理(Loop)、车架设计(Harness)、接口标准(MCP)、零件品牌对比(框架)、建筑规范(设计模式)。你已经了解了 Agent 的方方面面——但你从来没有亲手造过一个。今天,我们开箱,把零件一个个组装起来,让一个 Agent 真正跑起来。不用任何框架,纯 Python 手写,你会亲眼看到前面讲的每一个概念在代码中是怎么工作的。 这是「小白讲 AI」系列的第 19 篇。第 12 篇我们学了怎么调用 AI API(单次对话)。这一篇我们要在那个基础上,把”单次对话”升级成”自主循环”——让 AI 不只是回答你一次,而是自己持续工作直到任务完成。 一、我们要造什么?今天的目标是构建一个 “研究助手 Agent”——你给它一个研究问题,它会: 自主搜索互联网上的相关信息 阅读搜索结果中的关键内容 整理信息并生成一份结构化的研究报告 全程自主决策,你不需要一步步指导它 比如你问:”2026 年最流行的 AI Agent 框架有哪些?”它会自己去搜索、阅读、比较、整理,最后给你一份有条有理的报告。 我们不使用任何框架——所有代码都是手写的。...










