汇编中的伪指令和软件抽象

Pseudoinstuctions and software abstractions in Assembly

这更像是一个一般性的理论问题。

我正在学习一些汇编语言,并且注意到一些软件,例如用于 MIPS 的 MARS, 实现架构的真实指令集中不存在的抽象,这些指令似乎被称为伪指令,其中的例子是li,以及其他舒适的抽象,如整洁的数组创建等

我的问题是:

我有点怀疑它只是为了教育目的而存在,但还没有找到任何这方面的信息。

作为一名“专业的汇编程序员”,如果不使用易于阅读的 move 伪指令,您可能会疏忽使用晦涩的三操作数形式,这些形式可以将值从一个寄存器移动到另一个寄存器使用晦涩的 3 操作数形式将立即数移入寄存器,而不是易于阅读的 li 伪指令。

避免使用伪指令的主要原因是您的导师说您不能使用它们。

但是,在使用它们时,我们应该了解它们,它们可能会导致意想不到的低效率。许多伪指令(但不是全部)扩展为 2 或 3 条真实的硬件指令。使用它们隐藏了优化的机会。

例如,比较寄存器和立即数(硬件不直接支持)的分支有一个扩展,需要将一个立即数值加载到一个寄存器中,以便使用该寄存器来寄存器比较。如果您知道这一点,那么在循环中执行此操作,我们可能会将立即数加载到寄存器中 outside/before 循环以保存该指令及其循环内的循环。

此外,一般来说,MIPS 汇编程序支持使用 CPU 寄存器 $at 扩展和互连的伪指令。因此,汇编程序员被警告不要使用这个寄存器;调用约定将 $at 描述为“为汇编器保留”。但是,CPU寄存器是宝贵的资源,这种专门预留是一种浪费。 (请注意,编译器不受此保留约束,可以自由使用 $at 作为暂存寄存器 [call clobbered]。)

RISC V 及其汇编程序已经消除了这个“汇编程序保留”寄存器(将其还给程序员)并且只支持无需汇编程序专用寄存器即可完成的伪指令。虽然仍然支持各种 lw $regtrg, label($regsrc) 形式(尽管它们很丑陋),但类似的 sw 形式并不支持,因为它们需要额外的寄存器! RISC V 还删除了两个 $k 寄存器(为操作系统保留),将它们还给用户模式代码,并且还扩展了调用约定以在寄存器中传递更多参数。这些变化使 RISC V 更有效地使用稀缺资源(CPU 寄存器)。