计算机如何将寄存器设置为常量值?

Mar*_*ler 2 cpu assembly cpu-architecture cpu-registers

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

警告2:我不知道"CPU指令","CPU操作"和"CPU功能"等术语之间的区别.也许有一个,也许没有,但我使用这些就好像它们是同义词.如果我错了,请纠正我.

背景:想象一下,你有一个带有两个寄存器的4位CPU.现在你需要加载一个常量值来注册1!可能有几种方法可以做到这一点:

  • 像0SXX这样的指令,其中0表示它是"设置寄存器到X"类指令,S表示寄存器1的哪一侧应加载XX.
    • 优点:易于操作寄存器1.只需使用两个字节的程序存储器即可设置常量值.
    • 缺点:消耗可能的CPU指令的HALF.对于我的4位小设备来说,这是一个悲剧,但也许这对于= 8位计算机来说并不是什么大问题.
  • 纯粹的算术/逐位CPU系列功能(如AND,OR,NOT,XOR,RoR,RoL,INC等......)
    • 优点:没有额外的CPU实现.
    • 缺点:需要更多指令,常量加载速度较慢,当然,在装配中加载常量之前需要考虑更多.
  • 介于两者之间的东西?像清除寄存器,加载?? XX然后逻辑运算?
  • 还有别的我没有想过的东西?

通常:

  • 有没有办法让所有正常的现代CPU将寄存器设置为常量值?
    • 如果不是,最常见的方法是什么?
  • 旧的4/8位计算机有不同的方法吗?

我认为任何接触过大会的人都会知道asnwer.我非常感谢你的帮助!提前致谢.

old*_*mer 6

每个处理器架构,x86,arm,mips等都有自己的方式来做到这一点.如果你不能以某种方式操作常量,你肯定无法从处理器中获得太多的使用.

首先,并非所有处理器都使用寄存器,例如,有些是基于堆栈的,尽管在某种程度上在堆栈上放置了一个常量,但是你遇到了同样的问题.

有两种基本方法,都可以在大多数处理器上找到.一个是你所暗示的,有一些指令表明这是一个立即移动(立即意味着常量在指令本身中被编码)来注册,术语会有所不同,但操作码,寄存器号和立即值被编码在指令中.虽然您可能无法在一条指令中加载整个寄存器,但可能无法在一条指令中加载整个寄存器,例如,您不能使用32位的操作码,寄存器编号和32位值,因此例如ARM和MIPS可以只加载一小部分寄存器.加载一个0x00000078,然后或在0x00005600,然后或在0x00340000然后或在0x12000000或另一个架构加载0x00005678和或在0x12340000,导致0x12345678.

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

它们在历史上与它们不同的相似之处是多么新旧.旧的到新的指令集倾向于使用几个或更多的寄存器,有一个程序计数器,有alu操作,添加,和,或者,不是,xor等.有办法读写内存(加载和存储)并有能够使用立即值.较旧的cisc处理器和/或可变长度指令集处理器提供了更多这些指令,每个alu操作都能够使用全宽度的直接,这样的事情,并且当你试图通过risc提高性能时,你牺牲了这些功能可实现更快的流水线操作,更多指令,但它们移动得更快更顺畅,从而可以更快地执行(或其他功能).

网上有指令集信息供您使用.pdp-11或msp430是一个很好的第一个指令集,我经常建议在学习装配时使用模拟器而不是硬件,首先避免使用x86,直到你有一两个其他的.msp430/pdp11,arm,mips,avr等.在一两个之后,pdp8实际上是有趣且有教育意义的,当然你可能想要挖掘4004或8008然后继续前进到6502和6800和8080和那样的事情.