第 3 章 体验一次手工汇编
从程序员视角读取 Z80 寄存器和指令表,手工把助记符编码为机器字节并追踪执行时间。
直觉起点
、、、、共同构成本页的观察坐标。汇编语言用助记符表达机器指令,汇编过程依据操作码表把指令和操作数编码成字节;寄存器、程序计数器、标志位和时钟周期共同决定执行轨迹。
学习时不要背孤立名词。先预测一个输入进入系统后会改变哪些位、寄存器、内存单元、控制状态、对象、数据行或网络消息,再用最小实验逐层核对。只看到最终输出会丢失中间因果,无法解释边界与失败。
六阶段运行链
1. 声明寄存器初值
手工汇编先查目标 CPU 的操作码表,再按指令格式写入立即数或地址。每执行一条指令都记录 PC、寄存器、标志、内存与周期数,这比只看最终输出更能揭示错误。
实验从“声明寄存器初值”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
2. 读取助记符语义
读取助记符语义 必须放回“声明寄存器初值、读取助记符语义、查找操作码、编码地址与立即数、逐指令追踪状态、累计时钟周期”的完整运行链,明确输入编码、状态变化、接口边界、失败出口和恢复条件。
实验从“读取助记符语义”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
3. 查找操作码
查找操作码 必须放回“声明寄存器初值、读取助记符语义、查找操作码、编码地址与立即数、逐指令追踪状态、累计时钟周期”的完整运行链,明确输入编码、状态变化、接口边界、失败出口和恢复条件。
实验从“查找操作码”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
4. 编码地址与立即数
编码地址与立即数 必须放回“声明寄存器初值、读取助记符语义、查找操作码、编码地址与立即数、逐指令追踪状态、累计时钟周期”的完整运行链,明确输入编码、状态变化、接口边界、失败出口和恢复条件。
实验从“编码地址与立即数”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
5. 逐指令追踪状态
逐指令追踪状态 必须放回“声明寄存器初值、读取助记符语义、查找操作码、编码地址与立即数、逐指令追踪状态、累计时钟周期”的完整运行链,明确输入编码、状态变化、接口边界、失败出口和恢复条件。
实验从“逐指令追踪状态”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
6. 累计时钟周期
地址线选择内存或 I/O 位置,数据线双向搬运内容,控制线声明读写和有效时刻。调试时固定时钟步进,逐根核对片选、读写、地址和数据,避免多个器件同时驱动总线。
实验从“累计时钟周期”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
核心机制深挖
汇编语言用助记符表达机器指令,汇编过程依据操作码表把指令和操作数编码成字节;寄存器、程序计数器、标志位和时钟周期共同决定执行轨迹。 本页统一登记六类证据:输入与编码、当前状态、转换规则、接口所有者、首个失败、恢复结果。硬件页观察引脚和寄存器,程序页观察控制流与数据结构,网络页观察逐层地址和消息,系统页观察阶段文档与运营状态;对象不同,证据方法一致。
本页签发不变量是:每条助记指令都唯一映射到目标 CPU 的机器字节,地址和字节序明确;逐步执行后的寄存器、标志和内存状态与周期估算一致。。先预测再运行能迫使学习者明确因果;正常样本证明基本路径,边界样本暴露容量和时序,失败样本确定责任边界,恢复样本证明系统可以回到受控状态。
2015 版语境与现代对照
原书以 Z80、手工汇编、流程图、Java/.NET、关系数据库、TCP/IP、公开密钥、XML 和传统系统开发流程为实例。重构保留 12 章 114 个公开目录条目,不用云原生、现代前端或机器学习主题替换原书身份;现代实现只用于说明相同的输入、状态、接口与恢复原则。
Z80 的地址与控制引脚可对应现代处理器的总线事务,纸上算法可对应自动化测试,传统 DBMS 和 XML 可对应今天的数据服务与交换协议。工具会变化,但有限状态、可验证契约、分层地址、事务边界、密钥责任和灾难恢复仍需重新证明。
完整公开目录逐项讲解
第3章 体验一次手工汇编
手工汇编先查目标 CPU 的操作码表,再按指令格式写入立即数或地址。每执行一条指令都记录 PC、寄存器、标志、内存与周期数,这比只看最终输出更能揭示错误。
实验从“声明寄存器初值”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
3.1 从程序员的角度看硬件
手工汇编先查目标 CPU 的操作码表,再按指令格式写入立即数或地址。每执行一条指令都记录 PC、寄存器、标志、内存与周期数,这比只看最终输出更能揭示错误。
实验从“读取助记符语义”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
3.2 机器语言和汇编语言
手工汇编先查目标 CPU 的操作码表,再按指令格式写入立即数或地址。每执行一条指令都记录 PC、寄存器、标志、内存与周期数,这比只看最终输出更能揭示错误。
实验从“查找操作码”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
3.3 Z80 CPU的寄存器结构
手工汇编先查目标 CPU 的操作码表,再按指令格式写入立即数或地址。每执行一条指令都记录 PC、寄存器、标志、内存与周期数,这比只看最终输出更能揭示错误。
实验从“编码地址与立即数”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
3.4 追踪程序的运行过程
手工汇编先查目标 CPU 的操作码表,再按指令格式写入立即数或地址。每执行一条指令都记录 PC、寄存器、标志、内存与周期数,这比只看最终输出更能揭示错误。
实验从“逐指令追踪状态”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
3.5 尝试手工汇编
手工汇编先查目标 CPU 的操作码表,再按指令格式写入立即数或地址。每执行一条指令都记录 PC、寄存器、标志、内存与周期数,这比只看最终输出更能揭示错误。
实验从“累计时钟周期”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
3.6 尝试估算程序的执行时间
手工汇编先查目标 CPU 的操作码表,再按指令格式写入立即数或地址。每执行一条指令都记录 PC、寄存器、标志、内存与周期数,这比只看最终输出更能揭示错误。
实验从“声明寄存器初值”开始:固定初始状态,先预测寄存器、内存、对象、数据表或网络消息的下一步变化;每次只改变一个输入、容量、时序、地址、密钥或依赖条件,在首个偏离点保存证据。恢复后重放相同样本,不能只凭最终界面判断正确。
状态与失败矩阵
| 对象 | 正常状态 | 常见边界 | 失败证据 | 恢复条件 |
|---|---|---|---|---|
| 输入与编码 | 类型和范围明确 | 空值、最大值、非法字节 | 原始输入与解析位置 | 拒绝或规范化 |
| 运行与存储 | 状态转换可追踪 | 容量、时序、并发 | 首个错误状态 | 回到已知快照 |
| 接口与网络 | 地址和协议一致 | 丢包、乱序、超时 | 分层日志与消息 | 重试不破坏结果 |
| 系统与运营 | 文档和责任明确 | 依赖故障、节点失效 | 告警、切换与影响 | 业务结果恢复 |
最小可运行实验
const trace = [];
for (const instruction of program) {
trace.push({ pc: cpu.pc, registers: { ...cpu.registers } });
cpu.step(instruction);
}book: 计算机是怎样跑起来的
edition: 2015-05
page: hcw-03-manual-assembly
sample: normal | boundary | failure | recovery
predict_before_run: true
capture_first_divergence: true
replay_same_input: truefreeze initial state and input
predict the next observable state
change exactly one condition
stop at the first divergent boundary
remove the fault and replay
verify state, output, and recovery常见误区与故障注入
四类样本与验收
| 样本 | 注入方式 | 必查证据 | 通过条件 |
|---|---|---|---|
| 正常 | 固定合法输入 | 全阶段状态与输出 | 与预测一致 |
| 边界 | 空、满、最大值、慢时钟 | 容量和终止状态 | 不越界不悬挂 |
| 失败 | 错地址、断链、错钥、节点失效 | 首个错误与所有者 | 失败被隔离 |
| 恢复 | 删除故障后重放 | 状态、接口、业务结果 | 回到受控状态 |
目录证据:第3章 体验一次手工汇编、3.1 从程序员的角度看硬件、3.2 机器语言和汇编语言、3.3 Z80 CPU的寄存器结构、3.4 追踪程序的运行过程、3.5 尝试手工汇编、3.6 尝试估算程序的执行时间。本页按完整公开目录独立教学重构,不复制原书正文;7 个条目全部进入输入、状态、接口、失败和恢复证据链。
练习
小结
- 机器语言:对应“声明寄存器初值”的核心观察量。
- 汇编语言:对应“读取助记符语义”的核心观察量。
- 操作码:对应“查找操作码”的核心观察量。
- 寄存器:对应“编码地址与立即数”的核心观察量。
- 时钟周期:对应“逐指令追踪状态”的核心观察量。
- 7 个本页公开目录条目已全部映射到状态链和实验账本。
- 最终输出只是证据之一,过程状态、边界失败与恢复共同决定是否通过。