2

警告 1:我对现实生活中的实用 CPU 设计一无所知。

警告 2:我不知道“CPU 指令”、“CPU 操作”和“CPU 功能”等术语之间的区别。也许有,也许没有,但我把它们当作同义词一样使用。如果我错了,请纠正我。

背景:假设您有一个带有两个寄存器的 4 位 CPU。现在您需要加载一个常量值到寄存器 1!可能有几种方法可以做到这一点:

  • 像 0SXX 这样的指令,其中 0 表示它是“将寄存器设置为 X”类型的指令,而 S 表示应该将 XX 加载到寄存器 1 的哪一侧。
    • 优点:寄存器 1 的操作简单。仅使用两个字节的程序存储器就可以设置一个常数值。
    • 缺点:消耗一半可能的 CPU 指令。对于我的 4 位小设备来说,这是一个悲剧,但对于 >=8 位的计算机来说,这可能没什么大不了的。
  • 纯算术/按位系列 CPU 函数(如 AND、OR、NOT、XOR、RoR、RoL、INC 等...)
    • 优点:没有额外的 CPU 实现。
    • 缺点:需要更多指令,常量加载速度较慢,当然,在汇编中加载常量之前需要考虑更多。
  • 介于两者之间?像清除寄存器,加载??XX然后逻辑操作?
  • 还有什么我没有想到的?

一般来说:

  • 有没有办法让所有普通的现代 CPU 将寄存器设置为常数值?
    • 如果不是,最常见的方法是什么?
  • 旧的 4/8 位计算机是否有不同的方法来做到这一点?

我想任何接触过汇编的人都会知道答案。非常感谢您的帮助!提前致谢。

4

2 回答 2

6

每个处理器架构、x86、arm、mips 等都有自己的方法。如果您不能以某种方式对常量进行操作,那么您肯定无法充分利用处理器。

首先,并非所有处理器都使用寄存器,有些是基于堆栈的,例如,尽管以某种方式在堆栈上放置一个常量,但您也会遇到同样的问题。

有两种基本方法,并且在大多数处理器上都可以找到。一个是按照您所暗示的,有指令指出这是一个立即移动(立即意味着常数在指令本身中编码)进行注册,术语会有所不同,但操作码,寄存器号和立即值被编码在指令中。取决于 cpu,尽管您可能无法在一条指令中加载整个寄存器,例如固定长度指令集,但您无法将操作码、寄存器编号和 32 位值放入 32 位中,例如 ARM 和 MIPS 可以一次只加载一部分寄存器。加载 0x00000078,然后或在 0x00005600 中,然后或在 0x00340000 中,然后或在 0x12000000 或在另一个架构上加载 0x00005678 和或在 0x12340000 中,导致 0x12345678。

第二种方法是将常量放在程序存储器中,通常称为 .text,然后使用指令将数据从存储器加载或移动到寄存器,使用 pc 相对寻址。pc 程序计数器,基本上是程序员和汇编程序(读取汇编语言并从中生成机器代码的程序)的组合,已经放置了要加载的指令和要加载的数据,基本上说,取您现在正在执行的指令并添加一些数字 X 并生成我要读取并加载到此寄存器中的常量的地址。第二种方法适用于大多数指令集,您现在可以根据指令集的规则将任何大小常量加载到所需的寄存器中,在固定指令长度指令集的情况下,不需要两个或四个或更多指令来拼凑你想要的常数,它确实会花费你一个内存周期,这可能会或可能不会影响性能。如果您考虑可变长度指令集,那么常量本身就是指令流中的单独读取,因此架构之间的权衡确实没有任何不同。

无论指令集有多旧或多新,它们在历史上都是相似的,因为它们是不同的。从旧到新的指令集倾向于使用几个或更多的寄存器,有一个程序计数器,有 alu 操作,加和,或,非,异或等。有一种读写内存的方法(加载和存储),并有使用即时值的能力。较旧的 cisc 处理器和/或可变长度指令集处理器提供了更多这些指令,每个 alu 操作都能够使用全宽立即数,诸如此类,并且当您尝试使用 risc 提高性能时,您牺牲了这些特性用于更快的流水线、更多指令,但它们移动得更快、更平滑,从而产生整体更快的执行(或其他特性)。

指令集信息在网上供您使用。pdp-11 或 msp430 是一个很好的第一个指令集,我经常建议在学习汇编时使用模拟器而不是硬件,首先避免使用 x86,直到你有一个或两个其他指令集。msp430/pdp11、arm、mips、avr 等。在一两次之后,pdp8 确实很有趣且具有教育意义,当然您可能想继续挖掘 4004 或 8008,然后逐步升级到 6502、6800 和 8080诸如此类的事情。

于 2013-08-04T15:51:46.527 回答
2

我没有看到你问题的背景。如果你正在设计一个 4 位 CPU,你可能应该比你看起来做的多读一点。

大多数现实世界的 CPU 使用一些操作码位来描述操作类型(移动、加法、比较等),并使用更多位来描述寻址模式(常量、寄存器、寄存器间接、内存间接等)。并非所有 CPU 都为所有操作码提供所有寻址模式(具有此属性的指令集称为“正交”)。

尝试保存“CPU 实现”(= 减少操作码的数量)可能适用于很少使用的“神秘”指令(或例如浮点运算),但不适用于将常量值移动到寄存器等基本操作。

于 2013-08-04T16:00:56.973 回答