【运算篇】算术与逻辑律令(3):比特的手术刀,镜像翻转与空间缝合
在 4-bit 的逻辑地牢里如果说算术指令提供了“肌肉”逻辑指令开启了“感官”那么接下来我们要聊的则是这台机器最细腻的形态手术。如果说AND/OR是在判定“存在”那么NOT和移位指令SHL/SHR就是在重塑数据形态。特别是在 10x20 的段码屏与 4 位总线这种“先天不育”的配置下每一比特的平移都是一场关于精度与空间的博弈。本文将深入探讨 NOT 的镜像之美与 SHL/SHR 的平移艺术。我们将看清NOT指令如何在地牢里颠倒黑白并利用补码逻辑模拟出消失的减法灵魂更将解构SHL/SHR指令如何利用那枚 1-bit 的 Carry Flag 作为临时码头接应从物理边界坠落的数字碎片完成对 10 列像素显示区的空间缝合。在这场比特级别的微操中每一位数据的进退都是对 4 位总线极限的一次精准裁断。NOT 指令地牢里的“黑白镜像”注记符 NOT硬编码 0x05对应你代码中的 case 0x05类型 逻辑运算指令周期 21周期取指 1周期内部反相影响标志 Zero (Z)指令格式在 4-bit ISA 体系中NOT 指令通常采用 累加器寻址Accumulator Addressing 模式NOT AOpcode (4-bit):0x05标识这是一次逻辑取反操作。Operand: 无隐式指向累加器 A指令分析:在 4-bit 架构的严苛约束下为了节省昂贵的专用减法器电路我们必须充分挖掘现有指令的潜力。此时NOT 指令便成了我们手中极具性价比的‘逻辑杠杆’。在这一体系中减法运算 (A - B) 并不是原生发生的。我们巧妙地利用补码逻辑通过先加载操作数 (B) 至累加器并执行NOT A按位取反随后配合前文提到的ADC A, #1取反加一操作让原本仅具备加法逻辑的 ALU在瞬间获得了处理减法运算的能力。此外NOT指令的物理特性也直接服务于《俄罗斯方块》的视觉呈现。在处理‘整行反色’或‘高亮闪烁’等动画特效时NOT是最理想的优化手段——它无需复杂的逻辑分支判定仅需 2 个指令周期即可完成 4 个比特位的瞬间电平翻转实现了显示状态的高效切换。从硬件电路来看NOT 是 ALU 内部响应最快的组件因为它不需要进位链的漫长等待。虽然 NOT 只是翻转电平但它依然会触发 Zero 标志位在 4-bit 系统中只有当 A 原本为 1111b (15) 时执行 NOT 才会产生全零结果并点亮 Z 标志。这常被用来探测某个计数器是否达到了它的物理上限。在实现上寄存器 A 的输出端到总线之间物理上排列着 4 个 NOT 门反相器。我依然介绍一些实力场景1. 模拟减法计算 (5 - 3); 目标计算 A 5 - 3 ; 4-bit 补码逻辑A - B A (NOT B 1) LDI A, 3 ; A 0011 (操作数 B) NOT A ; A 1100 (取反) CLC ; 清除进位标志确保 ADC 的进位输入为 0 ADC A, 1 ; A 1101 (此时 A 已经变成了 -3 的补码形式) MOV B, A ; 将 -3 暂存到寄存器 B LDI A, 5 ; A 0101 (操作数 A) ADD A, B ; A 0101 1101 10010 ; 硬件自动丢弃溢出的第5位结果 A 0010 (十进制 2)这一连串动作展示了NOT如何作为逻辑杠杆在 2 个周期内将一个正数强行扭转为负数补码从而绕过了对硬件减法器的依赖。2. 视觉特效LCD 段码屏的“整行反色”:在《俄罗斯方块》中当一行填满或者游戏结束时我们需要让屏幕内容瞬间反转黑变白白变黑。; 假设内存 0x80 存放的是当前行第一个 Nibble 的显存数据 ; 原始数据假设为 1010 (两格亮两格灭) LDA [0x80] ; A 1010 NOT A ; A 0101 (亮灭状态瞬间翻转) STA [0x80], A ; 写回显存屏幕上该区域立刻实现“负片”效果在 4-bit 这种算力贫血的机器上NOT的价值在于其非判断性。你不需要知道当前像素是亮还是灭只需一次电平翻转就能实现最纯粹的视觉冲击。3. 状态判定检测计数器是否达到上限 (15)有时候我们需要判断一个 4-bit 计数器是否已经数到了头1111b。; 假设 X 寄存器是我们的计数器 MOV A, X ; A 1111 (如果计数器已满) NOT A ; A 0000 JZ COUNTER_FULL ; 如果结果为 0 (Zero Flag 1)说明原值是 15这是利用NOT触发 Zero Flag 的典型用法。这种“镜像判定”比复杂的比较指令更节省指令空间。所以在 4-bit 的逻辑地牢里减法不是一种本能而是一场骗局。 我们利用NOT指令颠倒黑白再通过ADC补上一枚比特让只会加法的 ALU 在不知不觉中完成了对数值的削减。这种硬件级‘偷梁换柱’的智慧是所有微型计算机生存的基础。SHL / SHR 指令比特的位移手术注记符 SHL (左移) / SHR (右移)硬编码 0x08 / 0x09类型 位移运算指令周期 3影响标志 Zero (Z), Carry (C)指令格式在 4-bit 架构中移位指令是处理非对齐数据的唯一手段SHL A或SHR AOpcode (4-bit): 标识移位方向。操作对象: 隐式指向累加器 A将 4 位数据整体向左或向右推移 1 bit。指令解析这两条位移指令在 4-bit 架构中占据着极其关键的地位。由于我们的显示区域设定为 10 列像素而数据总线位宽仅为 4 位导致一行像素数据被迫“碎裂”跨地址分布在三个 Nibble 单元中采用 (442) 的内存布局。在这种物理限制下平移方块本质上是一场比特级别的“跨栏接力”坠落与暂存我们首先对第一个内存单元执行SHL左移。此时溢出的最高位\(D_{3}\)并不会直接消失而是如同“坠落”一般被锁存在 Carry Flag进位标志位中。缝合与重组随后我们对相邻的第二个内存单元执行带进位的循环移位将 Carry 标志位中暂存的那枚比特“缝合”回新单元的最低位\(D_{0}\)。如果没有这一套位移指令方块在 10 列屏幕上的移动将只能以 4 个像素为步长进行生硬的“瞬移”。SHL/SHR 的存在是 4 位机展现平滑动画效果的唯一技术屏障。硬件层面的连锁反应在仅有的 3 个指令周期内CPU 内部经历了一场微观的电平风暴数据从寄存器流出经过移位矩阵的物理偏转最终将溢出位精准锁存至 Carry 引脚。SHL逻辑左移数据向高位挤压原 \(D_{3}\) 位的电平信号被直接导向状态寄存器的 Carry 输入端。SHR逻辑右移原 \(D_{0}\) 位的信号线在位移瞬间被 Carry 捕获高位则由硬件自动补零。技术总结跨维度的“避风港”至此我们利用 Carry Flag 成功构建了一个跨越地址维度的“临时避风港”用来接应那些从物理边界坠落的数字碎片。这种在 4 根信号线里闪转腾挪的艺术不仅解决了 10 列像素的对齐死局更是在这片资源荒原上为图形学实现了最基础的“运动自由”。实战110列像素的“跨地址平移”这是解决 10 列像素跨 3 个 Nibble水平移动 1 像素的核心算法。我们将展示如何利用Carry Flag像接力棒一样传递比特。; 场景将一行 10 位数据存储在 0x80, 0x81, 0x82 三个地址整体左移 1 位 ; 内存布局[0x80: bits 0-3], [0x81: bits 4-7], [0x82: bits 8-9] ; --- 处理第一个单元 (低 4 位) --- LDA [0x80] ; 加载第一个 Nibble SHL A ; 执行左移。此时 D3 溢出坠落并锁存到 Carry Flag STA [0x80], A ; 写回此时 bit 0 空出原 bit 3 暂存在 Carry 中 ; --- 处理第二个单元 (中 4 位) --- LDA [0x81] ; 加载第二个 Nibble ; 这里假设你实现了一条指令叫 ROL (Rotate Left through Carry) ; 如果没有逻辑如下 SHL A ; bit 7 坠入新的 Carry旧的 Carry 还在等待“缝合” ; [此处需逻辑干预将旧 Carry 补回当前 A 的 D0 位] ; 这展示了为什么 4-bit 程序员极其渴望硬件支持“带进位循环移位” STA [0x81], A ; --- 处理第三个单元 (高 2 位) --- LDA [0x82] SHL A ; 延续接力过程 STA [0x82], A实战2 利用位移替代“昂贵”的乘除法在 4-bit ALU 中没有乘法器。要计算方块坐标或得分偏移位移指令是性能最高的操作。场景将寄存器 A 的值快速乘以 2例如计算内存偏移; 目标计算 A A * 2 LDA #0011b ; A 3 SHL A ; A 0110b (结果为 6) ; 指令周期3如果用加法ADD A, A可能需要更多的取指周期。而SHL直接在 ALU 内部通过布线完成速度极快。实战3 提取特定的“像素位”; 目标检查 A 的 D2 位 LDA [0x20] ; 假设 A 0100b SHR A ; A 0010b, Carry 0 (D0坠落) SHR A ; A 0001b, Carry 0 (D1坠落) SHR A ; A 0000b, Carry 1 (D2坠落) JC BIT_IS_ONE ; 如果 Carry1说明原 D2 位是 1这种通过 “连续坠落” 到 Carry 的方式是 4-bit 机器在没有BIT测试指令时探测任意比特位的标准手段。至此那个被我称为‘码头’的 Carry Flag在这些例子里不停地忙碌着。 它一会儿要接住左移溢出的像素一会儿要捕获右移坠落的状态位。这种在时间轴上拼凑空间完整性的做法正是 4-bit 程序员在资源地牢里的日常。在这里代码不是写出来的是缝出来的。至此【运算篇】的所有武器库——从跨维接力的 ADD/ADC到逻辑审判的 AND/OR/XOR再到比特缝合的 NOT/SHL/SHR均已悉数列阵。规则已经订立但这仅仅是‘纸上谈兵’。下一期我们将撕开逻辑的表象把这套 4-bit 模拟器的具体代码框架完整地推向台前。 我们不再满足于抽象的指令推演而是要开启真实的指令集压力测试。看这些在‘地牢’里博弈出的指令如何在真正的 C 代码运行环境中跳动出第一波比特流。