6502 算术逻辑单元(ALU)

news/2025/12/9 23:12:32/文章来源:https://www.cnblogs.com/1bite/p/19164444

算术逻辑单元(ALU)是 CPU 的核心部件,负责 CPU 内的各种算术运算。现代 CPU 的 ALU 无疑相当复杂,想要从晶体管或逻辑门级别对它的工作原理进行说明几乎不现实。但是 6502 CPU 是一款颇具知名度但又相对简单的 8 位 CPU,使用它来介绍 ALU 的原理非常合适。接下来让我们来看看 6502 的 ALU 是如何构成以及它的工作原理。

功能

6502 CPU 可以对 8 位有符号和无符号数进行加(ADC)、减(SBC)、按位与(AND)、按位或(ORA)、按位异或(EOR)、左移(ASL,ROL)、右移(LSR,ROR)总共 9 种运算。但是并不是每一种运算都有一个对应的运算模式,6502 ALU 只支持求和(SUMS)、按位与(ANDS)、按位或(ORS)、按位异或(EORS)和右移(SRS)共 5 种运算模式。因此,有些指令是通过一些“巧思”实现的。

减法(SBC)

减法(SBC)是由求和实现的。SBC 指令的功能可以表述为 \(A - M - \overline{C} \to A\),其中 A 表示 A 寄存器;M 表示内存中的操作数;C 表示标志寄存器中进位标志(CF)的值。SBC 可以转换为加法:

\[\begin{split} SBC =&\ A - M - \overline{C} \\=&\ A + -M - \overline{C} \\=&\ A + \overline{M} + 1 - \overline{C} \\=&\ A + \overline{M} + C \end{split} \]

所以只需要把 M 取反后送入 ALU,然后照常进行加法即可。

左移(ASL,ROL)

左移(ASL,ROL)相当于把操作数乘以 2,所以是通过把操作数加上自身实现的。即 \(X + X + C \to X\),其中 X 表示操作数(来自 A 寄存器或者内存),C 表示标志寄存器中进位标志(CF)的值。

右移(LSR,ROR)

右移(LSR,ROR)是把每个 NAND 输出位接入到上一个位的总输出中,其中最高位固定为 1。在存储时,最高位有单独的信号(ADD/SB7)用来控制是否放到总线上。运算时,ALU 的两个输入都被配置为操作数,这样:

\[\begin{split} Y_{n} =& \overline{A_{n+1} \cdot B_{n+1}} \\ =& \overline{X_{n+1} \cdot X_{n+1}} \\ =& \overline{X_{n+1}} \end{split} \]

可见,输出正好是操作数右移一位后取反的结果,要得到正确结果只需对输出取反即可。

核心结构

由于没有乘除法运算,因此 ALU 的核心其实基本就是一个 8 比特全加器,比较有趣的是这个全加器的奇偶位电路略有不同。

其中偶数位全加器的晶体管电路图如下:
alu-cell-a

对应的逻辑门电路图如下:
alu-cell-a-logic

奇数位全加器的晶体管电路如下:
alu-cell-b

对应的逻辑门电路图如下:
alu-odd-bit

想知道晶体管电路是怎么转换到逻辑门电路的?可以看看这篇文章

上面晶体管电路中,x1、x2 用来控制是否对 DATA1 进行取反。x1 用于将相反数送入 ALU,x2 用于将原数送入 ALU。

将这两个运算单元交替串联起来,就组成了 ALU:
alu

注意,这只是演示。由于 6502 支持 BCD,实际电路比上述电路复杂,后文有介绍

外围结构

ALU 的外围结构包括两个输入寄存器(AI 和 BI)、一个输出寄存器(ADD,注意这个不是累加寄存器 AC)、标志寄存器、BCD 修正电路,这些外围结构与 ALU 计算核心一起组成了功能完整的 ALU。运算方式选择实际上是运算结果的选择。从上面的逻辑门电路图不难看出,ALU 是一次性把求和、与、或和异或运算都进行了的,选择不同的计算结果就达到了进行不同计算的目的。

这些外围组件与 ALU 计算核心的连接关系如下:

ALU-components

ALU 状态标志

ALU 除了输出运算结果,还附带输出一些状态信息,这些状态包括:溢出标志(AVR)、符号标志(NF)、进位标志(ACR)、零标志(ZF)以及 BCD 修正要用到的半进位标志(HC)。有了这些状态标志,CPU 就能实现“比较”指令。

溢出标志(AVR)

溢出标志表示计算结果溢出,有符号数运算结果如果小于 -128 或者大于 127 则溢出。溢出标志对于无符号数没有意义,无符号数的溢出看进位标志(ACR)即可。溢出检测电路如下:

AVR-circuit

图中 Carry6 是 ALU 的第 7 个位(次高位)的进位输出,NAND7 是 ALU NAND 输出的最高位,NOR7 则是 NOR 输出的最高位

上面晶体管电路对应的逻辑门电路图如下:

AVR-logic

即:

\[\begin{split} \overline{AVR} =&\overline{\overline{NAND_7+ Carry_6} + NOR_7 \cdot Carry_6} \\ AVR =& \overline{NAND_7+ Carry_6} + NOR_7 \cdot Carry_6 \\=& \overline{\overline{A_7 \cdot B_7} + Carry_6} + \overline{A_7 + B_7} \cdot Carry_6 \\=& A_7 \cdot B_7 \cdot \overline{Carry_6} + \overline{A_7 + B_7} \cdot Carry_6 \end{split} \]

当 Carry6 为 0 时,AVR 等于 \(A_7 \cdot B_7\);当 Carry6 为 1 时,AVR 等于 \(\overline{A_7 + B_7}\)。让我们一起分析看看这种检测方式是否有效。

若 Carry6 为 0:

  • A、B 都为正数时,和小于等于 127。这时不会溢出
  • A、B 只有一个负数时,它们的和仍然为负数。这时,负数的那个绝对值较大,不会溢出
  • A、B 都为负数时,它们的和变为正数。显然溢出

若 Carry6 为 1:

  • A、B 都为正数时,和变为负数。显然溢出
  • A、B 只有一个负数时,和为正数。这时,正数的那个绝对值较大,不会溢出
  • A、B 都为负数时,要产生 Carry6 的进位,其中一个(假设是 A)必然大于等于 -64(即次高位为 1),B 则需要满足 B >= (~A + 1) | -128B >= (~A + 1) | -128 等价于 B >= -A + -128,也就是 B + A >= -128,即 “A + B” 不会溢出

综上,Carry6 为 0 且 A、B 都为负数时(即 \(A_7 \cdot B_7 = 1\))会溢出;Carry6 为 1 且 A、B 都为正数时(即 \(\overline{A_7} \cdot \overline{B_7} = 1\))会溢出。

根据上面的分析,我们可以确认 6502 的溢出检测算法是正确的。但是上面的算法有点复杂和难以理解,如果我们进行模拟器开发,通常采用以下算法判断溢出:

OV = 0x80 & (AI ^ ADD) & (BI ^ ADD) ? 1 : 0;

即,最终结果与 A、B 都异号时,计算会溢出。这其实跟上面 AVR 的逻辑表达式是等价的。

符号标志(NF)

符号标志表示计算结果是否为负数,也就是计算结果的最高位(第 8 位)是否为 1。此标志只在对有符号数进行运算时才有意义。

零标志(ZF)

零标志表示计算结果是否为零,电路非常简单,就是把计算结果送入一个 NOR 门。

进位标志(ACR)

进位标志就是全加器的进位输出取反,不再多做介绍。

半进位标志(HC)

这个标志是 ALU 第 4 个位上产生的进位(Carry3),用于 BCD 修正,没有对应的寄存器。

BCD 模式

6502 CPU 支持硬件 BCD 模式,这种模式需要额外的电路对结果进行修正。BCD 修正电路如在 MOS 科技的专利 patent US 3991307 中有详细介绍。BCD 修正电路包含 BCD 进位部件和 BCD 修正部件两个部分,这些部件与 ALU 加法器的关系如下:

image

接下来,我们来拆解一下每个部分的工作原理。

BCD 进位

BCD 进位部件分成低四位进位 DC3 和 高四位进位 DC7,其中 DC3 的进位电路如下:

BCD-DC3

上述电路对应的逻辑表达式如下:

\[\begin{split} DC3 =& DAA \cdot \{(A2 \cdot B2 + A3 \oplus B3) \cdot [A2 \oplus B2 + A1 \oplus B1 + A1 \cdot B1 + (A0 \cdot B0 + AC_{in}) \cdot (A0 + B0)] + (A0 \cdot B0 + AC_{in}) \cdot (A0 + B0) \cdot A1 \cdot B1 \cdot (A2 + B2)\} \\ =& DAA \cdot \{(A2 \cdot B2 + A3 \oplus B3) \cdot [Carry0 + A1 + B1 + A2 \oplus B2] + Carry0 \cdot A1 \cdot B1 \cdot (A2 + B2)\} \end{split} \]

其中 \(Carry0 = (A0 \cdot B0 + AC_{in}) \cdot (A0 + B0)\)

这个逻辑表达式相当复杂,很难想象是怎么设计出来的。对这个表达式进行验算可以发现,A + B + AC 小于 10 时,DC3 为 0;和大于等于 10 时,DC3 大多数情况下值为 1。和大于等于 10 但 DC3 为 0 的情形中,二进制加法进位 Carry3 这时是 1,所以最终并不不影响后续 BCD 修正。

DC3 与 ALU 加法器的第 3 位输出 Carry3 进行 “或” 运算后被送往第 4 位的进位输入。由于实际 ALU 加法器的第 3 位输出是取反了的,且第 4 位的进位输入也要求取反,所以实际电路是这样的:

HC

最后形成的新 Carry3 也被叫做 HC(半进位)。

ALU 加法器加上上述 DC3 进位电路后完成的功能如下:

s = a + b + c;
if (s > 9) {s |= 0x10;
}

DC7 与 DC3 基本上是相同的,不再过多介绍。

BCD-DC7

对应的逻辑表达式:

\[\begin{split} DC7 &= (A6 \cdot B6 + A7 \oplus B7) \cdot (Carry4 + A5 \cdot B5 + A5 \oplus B5 + A6 \oplus B6) + Carry4 \cdot A5 \cdot B5 \cdot A6 \oplus B6 \\ &= (A6 \cdot B6 + A7 \oplus B7) \cdot (Carry4 + A5 + B5 + A6 \oplus B6) + Carry4 \cdot A5 \cdot B5 \cdot A6 \oplus B6 \end{split} \]

BCD 修正

BCD 的高、低四位用的是相同的修正电路,这里只细讲低四位的修正电路。低四位修正电路如下:

BCD-CORRECTION

电路中 SB0~SB3 表示的 CPU 内的特殊总线(SB 总线)的低四位。CPU 在进行 BCD 修正时,SB 总线上的数据实际上就是 ADD 寄存器中的内容(可以参考 Hanson 的框图辅助理解 CPU 内的数据通路)。所以,上述修正电路对应的逻辑表达式如下:

\[\begin{split} DS0 =& ADD0 \\ DS1 =& (DSAL + DAAL) \oplus ADD1 \\ DS2 =& (DSAL \cdot ADD1 + DAAL \cdot \overline{ADD1}) \oplus ADD2 \\ DS3 =& [DSAL \cdot (\overline{ADD1} + \overline{ADD2}) + DAAL \cdot (ADD1 + ADD2)] \oplus ADD3 \end{split} \]

当 DAA 为 1 时,DS 等于 ADD + 6; 当 DSA 为 1 时,DS 等于 ADD + 10。这正是 BCD 修正算法。

BCD 命令信号

BCD 修正命令分为加法修正(DAA)和减法修正(DSA)两个信号,信号的生成电路如下:

BCD_MODE

上面电路中的 51、52 表示解码器的 51、52 号输出。其中 51 解码 SBC 的 T0 周期,52 解码 SBC、ADC 的 T0 周期。D_out 表示 D 标志位(BCD 模式位)的值。

51 的指令匹配模板:111XXXX1
52 的指令匹配模板:X11XXXX1

上面电路对应的逻辑表达式如下:

\[\begin{split} DAA =& \overline{SBC0} \cdot ADC0 \cdot D \\ DSA =& SBC0 \cdot D \end{split} \]

上面电路的 DAA、DSA 信号延迟一个时钟周期后(即 T1 周期)将被送到下面的电路中,进一步生成针对高、低四位的命令信号:

BCD-CMD

注意,这里的 Carry3 并不是加法器第 3 位的输出,而是前面提到的 HC。所以:

\[\begin{split} DAAL =& DAA \cdot HC \\ DAAH =& DAA \cdot ACR \\ DSAL =& DSA \cdot \overline{HC} \\ DSAH =& DSA \cdot \overline{ACR} \end{split} \]

完整电路

最后给出完整的重建电路,如下:

ALU_FULL

代码模拟

带 BCD 修正逻辑的 ADC、SBC 指令模拟代码如下:

#define BIT_N    0x80
#define BIT_V    0x40
#define BIT_B    0x10
#define BIT_D    0x08
#define BIT_I    0x04
#define BIT_Z    0x02
#define BIT_C    0x01
#define BITS_NVZC    0xc3uint8_t ADC(uint8_t a, uint8_t b, uint8_t *flags) {int s = 0;if (*flags & BIT_D) {s = (a & 0xf) + (b & 0xf) + (*flags & BIT_C);if (s > 9) {s = 0x10 | (s + 0x6) & 0xf;}s = (a & 0xf0) + (b & 0xf0) + s;if (s > 0x9f) {s = 0x100 | (s + 0x60) & 0xff;}} else {s = a + b + (*flags & BIT_C);}*flags &= ~BITS_NVZC;*flags |= ((a ^ s) & (b ^ s) & BIT_N ? BIT_V : 0)| (s > 255 ? BIT_C : 0)| ((uint8_t)s ? s & BIT_N : BIT_Z);return (uint8_t)s;
}uint8_t SBC(uint8_t a, uint8_t b, uint8_t *flags) {int s = 0;b ^= 0xff;if (*flags & BIT_D) {s = (a & 0xf) + (b & 0xf) + (*flags & BIT_C);if (s < 0x10) {s = 0x10 | (s + 0xa) & 0xf;}s = (a & 0xf0) + (b & 0xf0) + s;if (s < 0x100) {s = 0x100 | (s + 0xa0) & 0xff;}} else {s = a + b + (*flags & BIT_C);}*flags &= ~BITS_NVZC;*flags |= ((a ^ s) & (b ^ s) & BIT_N ? BIT_V : 0)| (s > 255 ? BIT_C : 0)| ((uint8_t)s ? s & BIT_N : BIT_Z);return (uint8_t)s;
}

参考

  • patent US 3991307
  • breaks-alu.md

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/995697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

make出错立即终止

make出错立即终止Make编译时错误处理与日志输出解决方案 在使用 make -j4 编译 u-Boot(或其他项目)时,实现“错误触发所有线程终止”和“错误日志单独输出”,可通过 make 自身参数 + 脚本辅助实现,以下是两种核心…

Testing Reprised之关于基米

Testing Reprised之关于基米2025.11.10 奇迹就是小有遗憾 你不要有情绪,有情绪就去唱雨中曲(注:今年11月以后我没有什么创作了,就是没有诗和小说,但是会写一些小东西,汇集起来叫做忒思廷大重奏,不知道什么时候有…

Solon AI 开发学习19 - 结合 Solon Flow 实现 ReAct 效果

Solon Flow 是一个基于 YAML/JSON 配置的流程编排引擎,本文演示了其与 solon-ai 结合实现人机交互的 RcAct 流程。该流程通过 LLM 生成文章初稿后进入人工审核循环,支持根据反馈动态修改内容直至审核通过。核心流程包…

网络安全编程——基于Python达成的SSH通信(Windows执行)

网络安全编程——基于Python达成的SSH通信(Windows执行)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…

2025 最新水磨石抗污剂厂家 TOP5 评测!环保高性能标杆榜单发布,守护石材持久美观。国内水磨石抗污剂品牌2025年度盘点 - 全局中转站

随着水磨石在商业空间、高端住宅及公共设施中的广泛应用,其易渗污、难养护的问题日益凸显,水磨石抗污剂市场需求持续攀升。本榜单基于产品环保性能、抗污效果持久性、适用场景广泛性及行业口碑四大核心维度,结合国内…

OTOFIX IM2 1-Year Update Subscription: Ensure Latest Vehicle Diagnostics for European/American Cars

Staying Ahead in Automotive Diagnostics: The OTOFIX IM2 One Year Update Service Problem: Outdated Data Holds Back Repairs In today’s rapidly evolving automotive landscape, European and American mechan…

深入解析:2025年11月11日 AI快讯

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

北京守嘉健康干细胞项目介绍 - 品牌排行榜单

守嘉(北京)健康管理有限公司,秉承“引领主动健康,解码生命未来”的理念,通过与生命科学领域的前沿机构北京九思九如健康科技有限公司和北京福安华生物科技有限公司的深度战略合作,整合顶尖科研与临床资源,正式推…

统计文本文件记录

$folderPath = Read-Host "Enter the folder path" function mainMenu { while($prompt -ne ){$totaLines = 0 $n = 0 Get-ChildItem -Path $folderPath -Filter *.txt -Recurse | ForEach-Object { $fileL…

2025最新水洗石抗污剂厂家TOP5评测!环保性能与抗污效果品牌双权威榜单发布,技术赋能重构景观防护生态 - 全局中转站

随着水洗石材料在园林景观、市政工程、商业空间等场景的广泛应用,其抗污防护需求日益凸显。水洗石抗污剂作为提升材料耐久性与美观度的核心产品,市场关注度持续升温。本榜单基于环保安全、抗污性能、场景适配、服务体…

When Ongeki Gets Stuck at the Aime Check

When I updated Ongeki to version 1.21i, I inexplicably ran into the problem of getting stuck at the Aime check. If you are encountering the same issue: I know this is totally messed up, but trust me �…

如果同一个子网中,设备超过255台,那会如何才能保证处于同一子网

要让超过 255 台设备处于同一子网,核心是 扩大网段容量—— 通过选择「网络位更短、主机位更长」的子网掩码(即 CIDR 标识中「/」后面的数字小于 24),让网段可容纳的设备数量超过 253 台(/24 的上限)。关键原理:…

Autel MaxiPRO MP808TS 1-Year Update Subscription: Keep Your Diagnostic Tool Updated Effective

The Challenge: Outdated Diagnostics in a Rapidly Evolving Market Modern vehicles are evolving at an unprecedented pace, with advanced ECUs, hybrid/electric systems, and complex safety protocols becomin…

需求的变更控制

目录1. “变更的影响是可以接受的。”理解方式典型实践2. “受到变更影响的所有人都接到通知并明白这一点。”理解方式典型实践3. “由合适的人选来作出接受变更的正式决定。”理解方式如果没有“正式决定”会发生什么…

在java中实现c#的int.TryParse方法

在java中实现c#的int.TryParse方法在Java中实现类似C#的 int.TryParse方法,确实能带来更安全、更优雅的编码体验(指数字转换)。在.net(c#)的mscorlib程序集中,以System.Int32(int的实际类型)为例,有如下TryParse…

【值得收藏】构建企业级智能体RAG系统:解决大模型五大痛点,让AI真正理解业务 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

基于微信小应用的茶叶茶具销售和管理系统(源码+论文+部署+安装)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

我的 OI 生涯(更新中)

生活记录而已,全是流水账,不喜勿喷。 坐标:FJ XM 于 2025-12-9 开始编撰。 内容不会涉及其他人。 前言 父母都是程序员,所以从小多多少少有接触一些编程,也为我日后 OI 的生涯打下了基础。 大概是五年级时,被朋友…

少儿编程哪家强?这几家机构不容错过! - 品牌测评鉴赏家

少儿编程哪家强?这几家机构不容错过!编程热下的选择难题 在当今数字化飞速发展的时代,少儿编程学习已然成为一股热潮。走在街头,时不时就能看到少儿编程培训机构的招牌;打开社交媒体,也总能刷到孩子们展示自己编…

为AI时代蓄力:除了几大热门,还有哪些值得关注的少儿编程选择? - 品牌测评鉴赏家

为AI时代蓄力:除了几大热门,还有哪些值得关注的少儿编程选择?在为孩子选择人工智能与编程学习机构时,许多家长的目光往往聚焦于少数几个知名品牌。然而,教育的选择在于“适合”而非“名气”。如果您希望为孩子寻找…