现代计算机的理论最小寄存器数?


10

我在我的本科课程中学习了关于编译器的课程,其中我们编写了一个编译器,该编译器将类似于Java的玩具语言的源程序编译为玩具汇编语言(为此我们提供了解释器)。在项目中,我们对与“真正的”本机可执行文件密切相关的目标计算机做出了一些假设,包括:

  • 运行时堆栈,由专用堆栈指针(“ SP”)寄存器跟踪
  • 用于动态对象分配的堆,由专用堆指针(“ HP”)寄存器跟踪
  • 专用程序计数器寄存器(“ PC”)
  • 目标机器有16个寄存器
  • 对数据的操作(与例如跳转相反)是寄存器到寄存器的操作

当我们到达使用寄存器分配作为优化的单元时,我感到很奇怪:这种机器的理论最小寄存器数量是多少?通过我们的假设,您可以看到我们在编译器中使用了五个寄存器(SP,HP,PC,另外两个用作二进制操作的存储)。尽管诸如寄存器分配之类的优化当然可以利用更多的寄存器,但有没有办法在保持堆栈结构(如堆栈和堆)的同时减少使用?我想通过寄存器寻址(寄存器到寄存器操作)我们至少需要两个寄存器,但是我们需要两个以上吗?


“堆指针”似乎是一个奇怪的想法。因为与堆栈相反,所以堆不是LIFO,并且不会归结为push / pop语义。您应该将动态内存分配视为对malloc / free例程的调用。
伊夫·戴乌斯特

Answers:


14

如果允许通过内存地址直接访问内存,则不需要任何“寄存器”,因为可以使用内存位置。例如,位置0的内存可以是程序计数器,位置1的内存可以是堆栈指针,等等。

因此,为了防止自己作弊,让我们假设没有直接的内存访问,因为我们可以将固定的内存位置用作寄存器。然后,我们可以使用两个寄存器,一个程序计数器和一个堆栈指针,如Wikipedia上有关堆栈计算机的文章所述。只能通过堆栈指针访问堆栈,而只能通过程序计数器访问程序。

另一种可能性是使用柜台机器。两计数器机器是图灵完整的,也就是说,它可以计算出任何图灵机可以做到的。维基百科关于计数器机器的文章再次很好地解释了这一点。


感谢您的答复!但是,有关堆栈计算机的文章提到该计算机能够直接进行内存访问(以对最顶层的堆栈元素执行操作并将结果推回去),所以这仍然是欺骗,对吗?至于柜台机器,我读了那篇文章。我也读过类似的2-CM TC证明,但两者都有效地将所有RAM存储在两个寄存器中,这似乎更像是对我的欺骗。
BlueBomber

好吧,在某些时候它不再作弊。堆栈操作不作弊,只要它们禁止直接访问内存中的固定位置即可。可以旋转堆栈的三个最上面的元素是可以的。无论如何,您的问题有点奇怪,因此痴迷于什么是和没有作弊是没有用的。
Andrej Bauer

再次感谢你的回复。只要话题涉及理论界限,作弊就更不可接受了!不过,这并不意味着它没有启发性。我想这不是作弊的时候就是没有作弊。我发现您的最初答案很有用,但问题是我们的模型与所有图灵机,计数器机和堆栈机模型重叠,并且给出我们的假设(包括有限的有限寄存器且没有直接的内存访问),我们可以得到只有两个寄存器?
BlueBomber

1
我发现这个问题很奇怪,因为很难确定现实世界中的概念,例如处理器,寄存器,内存访问等,但是您需要确定那些概念才能证明任何东西。因此,最终结果将是无论您证明什么都容易证明,但这在很大程度上取决于您如何形式化问题(“处理器”,“寄存器”,“内存”等的理论概念是什么)。
Andrej Bauer

1
编译器教科书不允许我们证明太多,至少不能在数学上证明“证明”。您需要在硬件的形式化上进一步迈进,以实现可以证明的目标。无论如何,我们正在努力,我已经给了我最好的答案。
Andrej Bauer 2013年

1

PIC在1970年代引入并一直沿用至今的PIC体系结构具有以下寄存器:

W register (not addressible)
01    Timer/Counter
02    Program Counter
03    Status
04    File-Select Register
05-07 One register for each I/O port
08-1F General-purpose registers/"memory"

典型的指令将读取一个寄存器,使用读取的值和W进行计算,然后将计算结果存储到W或读取的寄存器中。可用的计算之一产生“读取的值,忽略W”。另一个是“取W,忽略读取的值”。对应于“读取XX,然后取W,忽略读取的值,然后将结果存储在W中”的位模式用于NOP以及各种特殊指令。

为了允许地址计算,处理器的执行单元将监视对地址00进行编码的指令,并将文件选择寄存器的内容替换为该地址。

尽管必须通过W寄存器馈送所有值可能是一个瓶颈,但与使用相同长度指令字的其他体系结构相比,PIC体系结构的工作集更大。在PIC16C54(今天仍在生产,与1970年代的PIC非常相似)上,指令长12位。在许多其他16Cxx或16Fxx部件上,指令为14位长,可以直接访问128字节的地址空间。如果程序的工作集与指令集的工作集非常吻合,则类似“ total + = value”(其中“ total”和“ value”的类型为)的语句unsigned char将编译为:

movf  value,w
addwf total,f

在类似ARM的设备上,即使一个寄存器已预加载一个变量的基地址,其代码也将更像:

ldr    r0,[r7+value]
ldr    r1,[r7+total]
add    r1,r1,r0
str    r1,[r7+total]

在许多情况下,编译器将能够避免每次操作都进行加载和存储,但是在PIC之类的工具上,较大工作集的好处有时会超过必须始终通过W的限制。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.